diff --git a/Example/Example.csproj b/Example/Example.csproj
index ea12fe91..8cf6a8c1 100644
--- a/Example/Example.csproj
+++ b/Example/Example.csproj
@@ -54,6 +54,7 @@
notify-sharp
+
diff --git a/Example/Example.pidb b/Example/Example.pidb
index b1361e55..4fb45023 100644
Binary files a/Example/Example.pidb and b/Example/Example.pidb differ
diff --git a/Example/Program.cs b/Example/Program.cs
index df1a5cfe..0d82b8b9 100644
--- a/Example/Program.cs
+++ b/Example/Program.cs
@@ -3,8 +3,10 @@ using Notifications;
#endif
using System;
using System.Collections;
+using System.Linq;
using System.Threading;
using WebSocketSharp;
+using WebSocketSharp.Net;
namespace Example
{
@@ -109,6 +111,8 @@ namespace Example
"notification-message-im");
};
+ //ws.SetCookie(new Cookie("nobita", "idiot"));
+ //ws.SetCookie(new Cookie("dora", "tanuki"));
ws.Connect();
Thread.Sleep(500);
diff --git a/Example/bin/Debug/example.exe b/Example/bin/Debug/example.exe
index 06a5eb1e..50a22662 100755
Binary files a/Example/bin/Debug/example.exe and b/Example/bin/Debug/example.exe differ
diff --git a/Example/bin/Debug/example.exe.mdb b/Example/bin/Debug/example.exe.mdb
index ded191cf..c0a677ac 100644
Binary files a/Example/bin/Debug/example.exe.mdb and b/Example/bin/Debug/example.exe.mdb differ
diff --git a/Example/bin/Debug/websocket-sharp.dll b/Example/bin/Debug/websocket-sharp.dll
index 274194fa..da66f4cc 100755
Binary files a/Example/bin/Debug/websocket-sharp.dll and b/Example/bin/Debug/websocket-sharp.dll differ
diff --git a/Example/bin/Debug/websocket-sharp.dll.mdb b/Example/bin/Debug/websocket-sharp.dll.mdb
index 334c331d..42c27219 100644
Binary files a/Example/bin/Debug/websocket-sharp.dll.mdb and b/Example/bin/Debug/websocket-sharp.dll.mdb differ
diff --git a/Example/bin/Debug_Ubuntu/example.exe b/Example/bin/Debug_Ubuntu/example.exe
index 697d85ce..882df6e9 100755
Binary files a/Example/bin/Debug_Ubuntu/example.exe and b/Example/bin/Debug_Ubuntu/example.exe differ
diff --git a/Example/bin/Debug_Ubuntu/example.exe.mdb b/Example/bin/Debug_Ubuntu/example.exe.mdb
index c22a7357..9b4ad027 100644
Binary files a/Example/bin/Debug_Ubuntu/example.exe.mdb and b/Example/bin/Debug_Ubuntu/example.exe.mdb differ
diff --git a/Example/bin/Debug_Ubuntu/websocket-sharp.dll b/Example/bin/Debug_Ubuntu/websocket-sharp.dll
index 5993ee69..6329426a 100755
Binary files a/Example/bin/Debug_Ubuntu/websocket-sharp.dll and b/Example/bin/Debug_Ubuntu/websocket-sharp.dll differ
diff --git a/Example/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/Example/bin/Debug_Ubuntu/websocket-sharp.dll.mdb
index 0cf18085..41f3e6c0 100644
Binary files a/Example/bin/Debug_Ubuntu/websocket-sharp.dll.mdb and b/Example/bin/Debug_Ubuntu/websocket-sharp.dll.mdb differ
diff --git a/Example/bin/Release/example.exe b/Example/bin/Release/example.exe
index 8e68ab47..509daf65 100755
Binary files a/Example/bin/Release/example.exe and b/Example/bin/Release/example.exe differ
diff --git a/Example/bin/Release/websocket-sharp.dll b/Example/bin/Release/websocket-sharp.dll
index f9220eb0..a3a3d62a 100755
Binary files a/Example/bin/Release/websocket-sharp.dll and b/Example/bin/Release/websocket-sharp.dll differ
diff --git a/Example/bin/Release_Ubuntu/example.exe b/Example/bin/Release_Ubuntu/example.exe
index f5bbecbc..022fa2bd 100755
Binary files a/Example/bin/Release_Ubuntu/example.exe and b/Example/bin/Release_Ubuntu/example.exe differ
diff --git a/Example/bin/Release_Ubuntu/websocket-sharp.dll b/Example/bin/Release_Ubuntu/websocket-sharp.dll
index 51c796ed..44002b79 100755
Binary files a/Example/bin/Release_Ubuntu/websocket-sharp.dll and b/Example/bin/Release_Ubuntu/websocket-sharp.dll differ
diff --git a/Example1/Example1.pidb b/Example1/Example1.pidb
index 011a3974..308af6ce 100644
Binary files a/Example1/Example1.pidb and b/Example1/Example1.pidb differ
diff --git a/Example1/bin/Debug/example1.exe b/Example1/bin/Debug/example1.exe
index 73046743..e4311324 100755
Binary files a/Example1/bin/Debug/example1.exe and b/Example1/bin/Debug/example1.exe differ
diff --git a/Example1/bin/Debug/example1.exe.mdb b/Example1/bin/Debug/example1.exe.mdb
index 9096bac8..d3a538f6 100644
Binary files a/Example1/bin/Debug/example1.exe.mdb and b/Example1/bin/Debug/example1.exe.mdb differ
diff --git a/Example1/bin/Debug/websocket-sharp.dll b/Example1/bin/Debug/websocket-sharp.dll
index 274194fa..da66f4cc 100755
Binary files a/Example1/bin/Debug/websocket-sharp.dll and b/Example1/bin/Debug/websocket-sharp.dll differ
diff --git a/Example1/bin/Debug/websocket-sharp.dll.mdb b/Example1/bin/Debug/websocket-sharp.dll.mdb
index 334c331d..42c27219 100644
Binary files a/Example1/bin/Debug/websocket-sharp.dll.mdb and b/Example1/bin/Debug/websocket-sharp.dll.mdb differ
diff --git a/Example1/bin/Debug_Ubuntu/example1.exe b/Example1/bin/Debug_Ubuntu/example1.exe
index 562c82b9..e3e4e4b1 100755
Binary files a/Example1/bin/Debug_Ubuntu/example1.exe and b/Example1/bin/Debug_Ubuntu/example1.exe differ
diff --git a/Example1/bin/Debug_Ubuntu/example1.exe.mdb b/Example1/bin/Debug_Ubuntu/example1.exe.mdb
index cda3bf6b..bb595be0 100644
Binary files a/Example1/bin/Debug_Ubuntu/example1.exe.mdb and b/Example1/bin/Debug_Ubuntu/example1.exe.mdb differ
diff --git a/Example1/bin/Debug_Ubuntu/websocket-sharp.dll b/Example1/bin/Debug_Ubuntu/websocket-sharp.dll
index 5993ee69..6329426a 100755
Binary files a/Example1/bin/Debug_Ubuntu/websocket-sharp.dll and b/Example1/bin/Debug_Ubuntu/websocket-sharp.dll differ
diff --git a/Example1/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/Example1/bin/Debug_Ubuntu/websocket-sharp.dll.mdb
index 0cf18085..41f3e6c0 100644
Binary files a/Example1/bin/Debug_Ubuntu/websocket-sharp.dll.mdb and b/Example1/bin/Debug_Ubuntu/websocket-sharp.dll.mdb differ
diff --git a/Example1/bin/Release/example1.exe b/Example1/bin/Release/example1.exe
index e9b9e8c1..ea08a154 100755
Binary files a/Example1/bin/Release/example1.exe and b/Example1/bin/Release/example1.exe differ
diff --git a/Example1/bin/Release/websocket-sharp.dll b/Example1/bin/Release/websocket-sharp.dll
index f9220eb0..a3a3d62a 100755
Binary files a/Example1/bin/Release/websocket-sharp.dll and b/Example1/bin/Release/websocket-sharp.dll differ
diff --git a/Example1/bin/Release_Ubuntu/example1.exe b/Example1/bin/Release_Ubuntu/example1.exe
index 19dc036a..75cac9a6 100755
Binary files a/Example1/bin/Release_Ubuntu/example1.exe and b/Example1/bin/Release_Ubuntu/example1.exe differ
diff --git a/Example1/bin/Release_Ubuntu/websocket-sharp.dll b/Example1/bin/Release_Ubuntu/websocket-sharp.dll
index 51c796ed..44002b79 100755
Binary files a/Example1/bin/Release_Ubuntu/websocket-sharp.dll and b/Example1/bin/Release_Ubuntu/websocket-sharp.dll differ
diff --git a/Example2/Echo.cs b/Example2/Echo.cs
index 831e125b..c7063c7d 100644
--- a/Example2/Echo.cs
+++ b/Example2/Echo.cs
@@ -1,5 +1,6 @@
using System;
using WebSocketSharp;
+using WebSocketSharp.Net;
using WebSocketSharp.Server;
namespace Example2 {
@@ -13,5 +14,16 @@ namespace Example2 {
: e.Data;
Send(msg);
}
+
+ protected override bool ProcessCookies(CookieCollection request, CookieCollection response)
+ {
+ foreach (Cookie cookie in request)
+ {
+ cookie.Expired = true;
+ response.Add(cookie);
+ }
+
+ return true;
+ }
}
}
diff --git a/Example2/Example2.pidb b/Example2/Example2.pidb
index 5ce8a32a..be8d641a 100644
Binary files a/Example2/Example2.pidb and b/Example2/Example2.pidb differ
diff --git a/Example2/bin/Debug/example2.exe b/Example2/bin/Debug/example2.exe
index b8f2e9d6..82a8d551 100755
Binary files a/Example2/bin/Debug/example2.exe and b/Example2/bin/Debug/example2.exe differ
diff --git a/Example2/bin/Debug/example2.exe.mdb b/Example2/bin/Debug/example2.exe.mdb
index c016e425..7ca41306 100644
Binary files a/Example2/bin/Debug/example2.exe.mdb and b/Example2/bin/Debug/example2.exe.mdb differ
diff --git a/Example2/bin/Debug/websocket-sharp.dll b/Example2/bin/Debug/websocket-sharp.dll
index 274194fa..da66f4cc 100755
Binary files a/Example2/bin/Debug/websocket-sharp.dll and b/Example2/bin/Debug/websocket-sharp.dll differ
diff --git a/Example2/bin/Debug/websocket-sharp.dll.mdb b/Example2/bin/Debug/websocket-sharp.dll.mdb
index 334c331d..42c27219 100644
Binary files a/Example2/bin/Debug/websocket-sharp.dll.mdb and b/Example2/bin/Debug/websocket-sharp.dll.mdb differ
diff --git a/Example2/bin/Debug_Ubuntu/example2.exe b/Example2/bin/Debug_Ubuntu/example2.exe
index 9a29b01e..2c340553 100755
Binary files a/Example2/bin/Debug_Ubuntu/example2.exe and b/Example2/bin/Debug_Ubuntu/example2.exe differ
diff --git a/Example2/bin/Debug_Ubuntu/example2.exe.mdb b/Example2/bin/Debug_Ubuntu/example2.exe.mdb
index 30dc6f54..de7247a6 100644
Binary files a/Example2/bin/Debug_Ubuntu/example2.exe.mdb and b/Example2/bin/Debug_Ubuntu/example2.exe.mdb differ
diff --git a/Example2/bin/Debug_Ubuntu/websocket-sharp.dll b/Example2/bin/Debug_Ubuntu/websocket-sharp.dll
index 5993ee69..6329426a 100755
Binary files a/Example2/bin/Debug_Ubuntu/websocket-sharp.dll and b/Example2/bin/Debug_Ubuntu/websocket-sharp.dll differ
diff --git a/Example2/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/Example2/bin/Debug_Ubuntu/websocket-sharp.dll.mdb
index 0cf18085..41f3e6c0 100644
Binary files a/Example2/bin/Debug_Ubuntu/websocket-sharp.dll.mdb and b/Example2/bin/Debug_Ubuntu/websocket-sharp.dll.mdb differ
diff --git a/Example2/bin/Release/example2.exe b/Example2/bin/Release/example2.exe
index c83adcdc..e33d6be0 100755
Binary files a/Example2/bin/Release/example2.exe and b/Example2/bin/Release/example2.exe differ
diff --git a/Example2/bin/Release/websocket-sharp.dll b/Example2/bin/Release/websocket-sharp.dll
index f9220eb0..a3a3d62a 100755
Binary files a/Example2/bin/Release/websocket-sharp.dll and b/Example2/bin/Release/websocket-sharp.dll differ
diff --git a/Example2/bin/Release_Ubuntu/example2.exe b/Example2/bin/Release_Ubuntu/example2.exe
index 2f35306d..58f11271 100755
Binary files a/Example2/bin/Release_Ubuntu/example2.exe and b/Example2/bin/Release_Ubuntu/example2.exe differ
diff --git a/Example2/bin/Release_Ubuntu/websocket-sharp.dll b/Example2/bin/Release_Ubuntu/websocket-sharp.dll
index 51c796ed..44002b79 100755
Binary files a/Example2/bin/Release_Ubuntu/websocket-sharp.dll and b/Example2/bin/Release_Ubuntu/websocket-sharp.dll differ
diff --git a/Example3/bin/Debug/Example3.exe b/Example3/bin/Debug/Example3.exe
index 80206bec..7dbe4a36 100755
Binary files a/Example3/bin/Debug/Example3.exe and b/Example3/bin/Debug/Example3.exe differ
diff --git a/Example3/bin/Debug/Example3.exe.mdb b/Example3/bin/Debug/Example3.exe.mdb
index 5ce0e558..6680b335 100644
Binary files a/Example3/bin/Debug/Example3.exe.mdb and b/Example3/bin/Debug/Example3.exe.mdb differ
diff --git a/Example3/bin/Debug/websocket-sharp.dll b/Example3/bin/Debug/websocket-sharp.dll
index 274194fa..da66f4cc 100755
Binary files a/Example3/bin/Debug/websocket-sharp.dll and b/Example3/bin/Debug/websocket-sharp.dll differ
diff --git a/Example3/bin/Debug/websocket-sharp.dll.mdb b/Example3/bin/Debug/websocket-sharp.dll.mdb
index 334c331d..42c27219 100644
Binary files a/Example3/bin/Debug/websocket-sharp.dll.mdb and b/Example3/bin/Debug/websocket-sharp.dll.mdb differ
diff --git a/Example3/bin/Debug_Ubuntu/Example3.exe b/Example3/bin/Debug_Ubuntu/Example3.exe
index 327ca32c..80dff1c8 100755
Binary files a/Example3/bin/Debug_Ubuntu/Example3.exe and b/Example3/bin/Debug_Ubuntu/Example3.exe differ
diff --git a/Example3/bin/Debug_Ubuntu/Example3.exe.mdb b/Example3/bin/Debug_Ubuntu/Example3.exe.mdb
index fe76e568..2faebf5b 100644
Binary files a/Example3/bin/Debug_Ubuntu/Example3.exe.mdb and b/Example3/bin/Debug_Ubuntu/Example3.exe.mdb differ
diff --git a/Example3/bin/Debug_Ubuntu/websocket-sharp.dll b/Example3/bin/Debug_Ubuntu/websocket-sharp.dll
index 5993ee69..6329426a 100755
Binary files a/Example3/bin/Debug_Ubuntu/websocket-sharp.dll and b/Example3/bin/Debug_Ubuntu/websocket-sharp.dll differ
diff --git a/Example3/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/Example3/bin/Debug_Ubuntu/websocket-sharp.dll.mdb
index 0cf18085..41f3e6c0 100644
Binary files a/Example3/bin/Debug_Ubuntu/websocket-sharp.dll.mdb and b/Example3/bin/Debug_Ubuntu/websocket-sharp.dll.mdb differ
diff --git a/Example3/bin/Release/Example3.exe b/Example3/bin/Release/Example3.exe
index fd129f26..789f1ce1 100755
Binary files a/Example3/bin/Release/Example3.exe and b/Example3/bin/Release/Example3.exe differ
diff --git a/Example3/bin/Release/websocket-sharp.dll b/Example3/bin/Release/websocket-sharp.dll
index f9220eb0..a3a3d62a 100755
Binary files a/Example3/bin/Release/websocket-sharp.dll and b/Example3/bin/Release/websocket-sharp.dll differ
diff --git a/Example3/bin/Release_Ubuntu/Example3.exe b/Example3/bin/Release_Ubuntu/Example3.exe
index b54bd250..b38257d3 100755
Binary files a/Example3/bin/Release_Ubuntu/Example3.exe and b/Example3/bin/Release_Ubuntu/Example3.exe differ
diff --git a/Example3/bin/Release_Ubuntu/websocket-sharp.dll b/Example3/bin/Release_Ubuntu/websocket-sharp.dll
index 51c796ed..44002b79 100755
Binary files a/Example3/bin/Release_Ubuntu/websocket-sharp.dll and b/Example3/bin/Release_Ubuntu/websocket-sharp.dll differ
diff --git a/websocket-sharp/Ext.cs b/websocket-sharp/Ext.cs
index a1082a5a..a231cd89 100644
--- a/websocket-sharp/Ext.cs
+++ b/websocket-sharp/Ext.cs
@@ -73,6 +73,22 @@ namespace WebSocketSharp {
#region Internal Method
+ internal static string GetNameInternal(this string nameAndValue, string separator)
+ {
+ int i = nameAndValue.IndexOf(separator);
+ return i > 0
+ ? nameAndValue.Substring(0, i).Trim()
+ : null;
+ }
+
+ internal static string GetValueInternal(this string nameAndValue, string separator)
+ {
+ int i = nameAndValue.IndexOf(separator);
+ return i >= 0 && i < nameAndValue.Length - 1
+ ? nameAndValue.Substring(i + 1).Trim()
+ : null;
+ }
+
internal static bool IsText(this string value)
{
int len = value.Length;
@@ -100,7 +116,7 @@ namespace WebSocketSharp {
{
foreach (char c in value)
{
- if (c < 0x20 || c >= 0x7f || _tspecials.Contains (c))
+ if (c < 0x20 || c >= 0x7f || _tspecials.Contains(c))
return false;
}
@@ -337,6 +353,28 @@ namespace WebSocketSharp {
: uriString;
}
+ ///
+ /// Gets the collection of cookies from the specified .
+ ///
+ ///
+ /// A that receives a collection of the HTTP Cookies.
+ ///
+ ///
+ /// A that contains a collection of the HTTP Headers.
+ ///
+ ///
+ /// true if gets from the response ;
+ /// from the request , false.
+ ///
+ public static CookieCollection GetCookies(this NameValueCollection headers, bool response)
+ {
+ var name = response ? "Set-Cookie" : "Cookie";
+ if (headers.IsNull() || !headers.Exists(name))
+ return new CookieCollection();
+
+ return CookieCollection.Parse(headers[name], response);
+ }
+
///
/// Gets the description of the HTTP status code using the specified .
///
@@ -365,15 +403,8 @@ namespace WebSocketSharp {
///
public static string GetName(this string nameAndValue, string separator)
{
- if (nameAndValue.IsNullOrEmpty())
- return null;
-
- if (separator.IsNullOrEmpty())
- return null;
-
- var i = nameAndValue.IndexOf(separator);
- return i > 0
- ? nameAndValue.Substring(0, i).Trim()
+ return !nameAndValue.IsNullOrEmpty() && !separator.IsNullOrEmpty()
+ ? nameAndValue.GetNameInternal(separator)
: null;
}
@@ -476,15 +507,8 @@ namespace WebSocketSharp {
///
public static string GetValue(this string nameAndValue, string separator)
{
- if (nameAndValue.IsNullOrEmpty())
- return null;
-
- if (separator.IsNullOrEmpty())
- return null;
-
- var i = nameAndValue.IndexOf(separator);
- return i >= 0 && i < nameAndValue.Length - 1
- ? nameAndValue.Substring(i + 1).Trim()
+ return !nameAndValue.IsNullOrEmpty() && !separator.IsNullOrEmpty()
+ ? nameAndValue.GetValueInternal(separator)
: null;
}
diff --git a/websocket-sharp/Handshake.cs b/websocket-sharp/Handshake.cs
index 7ccd8383..aad14a4d 100644
--- a/websocket-sharp/Handshake.cs
+++ b/websocket-sharp/Handshake.cs
@@ -4,7 +4,7 @@
*
* The MIT License
*
- * Copyright (c) 2012 sta.blockhead
+ * Copyright (c) 2012-2013 sta.blockhead
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/websocket-sharp/Net/Cookie.cs b/websocket-sharp/Net/Cookie.cs
index 30f500ad..ab2cb561 100644
--- a/websocket-sharp/Net/Cookie.cs
+++ b/websocket-sharp/Net/Cookie.cs
@@ -7,6 +7,7 @@
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
// Daniel Nauck (dna@mono-project.de)
// Sebastien Pouliot (sebastien@ximian.com)
+// sta (sta.blockhead@gmail.com)
//
// Copyright (c) 2004,2009 Novell, Inc (http://www.novell.com)
// Copyright (c) 2012-2013 sta.blockhead (sta.blockhead@gmail.com)
@@ -241,6 +242,22 @@ namespace WebSocketSharp.Net {
internal bool ExactDomain { get; set; }
+ internal int MaxAge {
+ get {
+ if (expires == DateTime.MinValue || Expired)
+ return 0;
+
+ var tmp = expires.Kind == DateTimeKind.Local
+ ? expires
+ : expires.ToLocalTime ();
+
+ var span = tmp - DateTime.Now;
+ return span <= TimeSpan.Zero
+ ? 0
+ : (int) span.TotalSeconds;
+ }
+ }
+
internal int [] Ports {
get { return ports; }
}
@@ -308,16 +325,17 @@ namespace WebSocketSharp.Net {
/// Gets or sets a value indicating whether the cookie has expired.
///
///
- /// true if the cookie has expired; otherwise, false.
+ /// true if the cookie has expired; otherwise, false. The default is false.
///
public bool Expired {
get {
return expires <= DateTime.Now &&
expires != DateTime.MinValue;
}
- set {
- if (value)
- expires = DateTime.Now;
+ set {
+ expires = value
+ ? DateTime.Now
+ : DateTime.MinValue;
}
}
@@ -326,6 +344,7 @@ namespace WebSocketSharp.Net {
///
///
/// A that contains the date and time at which the cookie expires.
+ /// The default is .
///
public DateTime Expires {
get { return expires; }
@@ -390,7 +409,7 @@ namespace WebSocketSharp.Net {
/// A that contains a list of the TCP ports to which the cookie applies.
///
///
- /// The value specified for a set operation could not be parsed or is not enclosed in double quotes.
+ /// The value specified for a set operation is not enclosed in double quotes or could not be parsed.
///
public string Port {
get { return port; }
@@ -402,11 +421,13 @@ namespace WebSocketSharp.Net {
}
if (!value.IsEnclosedIn ('"'))
- throw new CookieException ("The 'Port'='" + value + "' attribute of the cookie is invalid. Port must be enclosed in double quotes.");
+ throw new CookieException (String.Format (
+ "The 'Port={0}' attribute of the cookie is invalid. The value must be enclosed in double quotes.", value));
string error;
if (!TryCreatePorts (value, out ports, out error))
- throw new CookieException ("The 'Port'='" + value + "' attribute of the cookie is invalid. Invalid value: " + error);
+ throw new CookieException (String.Format (
+ "The 'Port={0}' attribute of the cookie is invalid. Invalid value: {1}", value, error));
port = value;
}
@@ -472,13 +493,13 @@ namespace WebSocketSharp.Net {
/// to which the cookie conforms.
///
///
- /// The value specified for a set operation is less than zero.
+ /// The value specified for a set operation is not allowed. The value must be 0 or 1.
///
public int Version {
get { return version; }
set {
- if (value < 0)
- throw new ArgumentOutOfRangeException();
+ if (value < 0 || value > 1)
+ throw new ArgumentOutOfRangeException ("value", "Must be 0 or 1.");
else
version = value;
}
@@ -536,6 +557,61 @@ namespace WebSocketSharp.Net {
return "\"" + value.Replace("\"", "\\\"") + "\"";
}
+ string ToResponseStringVersion0 ()
+ {
+ var result = new StringBuilder ();
+ result.AppendFormat ("{0}={1}", name, val);
+ if (expires != DateTime.MinValue)
+ result.AppendFormat ("; Expires={0}",
+ expires.ToUniversalTime ().ToString ("ddd, dd'-'MMM'-'yyyy HH':'mm':'ss 'GMT'",
+ CultureInfo.CreateSpecificCulture("en-US")));
+
+ if (!path.IsNullOrEmpty ())
+ result.AppendFormat ("; Path={0}", path);
+
+ if (!domain.IsNullOrEmpty ())
+ result.AppendFormat ("; Domain={0}", domain);
+
+ if (secure)
+ result.Append ("; Secure");
+
+ if (httpOnly)
+ result.Append ("; HttpOnly");
+
+ return result.ToString ();
+ }
+
+ string ToResponseStringVersion1 ()
+ {
+ var result = new StringBuilder ();
+ result.AppendFormat ("{0}={1}; Version={2}", name, val, version);
+ if (expires != DateTime.MinValue)
+ result.AppendFormat ("; Max-Age={0}", MaxAge);
+
+ if (!path.IsNullOrEmpty ())
+ result.AppendFormat ("; Path={0}", path);
+
+ if (!domain.IsNullOrEmpty ())
+ result.AppendFormat ("; Domain={0}", domain);
+
+ if (!port.IsNullOrEmpty ())
+ result.AppendFormat ("; Port={0}", port);
+
+ if (!comment.IsNullOrEmpty ())
+ result.AppendFormat ("; Comment={0}", comment.UrlEncode ());
+
+ if (!commentUri.IsNull ())
+ result.AppendFormat ("; CommentURL={0}", Quote (commentUri.OriginalString));
+
+ if (discard)
+ result.Append ("; Discard");
+
+ if (secure)
+ result.Append ("; Secure");
+
+ return result.ToString ();
+ }
+
static bool TryCreatePorts (string value, out int [] result, out string parseError)
{
var values = value.Trim ('"').Split (',');
@@ -562,60 +638,44 @@ namespace WebSocketSharp.Net {
#region Internal Methods
- // From server to client
- internal string ToClientString ()
- {
- if (name.IsEmpty ())
- return String.Empty;
-
- var result = new StringBuilder (64);
- if (version > 0)
- result.Append ("Version=").Append (version).Append ("; ");
-
- result.Append (name).Append ("=").Append (Quote (val));
- if (!path.IsNullOrEmpty ())
- result.Append ("; Path=").Append (path);
-
- if (!domain.IsNullOrEmpty ())
- result.Append ("; Domain=").Append (domain);
-
- if (!port.IsNullOrEmpty ())
- result.Append ("; Port=").Append (port);
-
- return result.ToString ();
- }
-
// From client to server
- internal string ToString (Uri uri)
+ internal string ToRequestString (Uri uri)
{
if (name.IsEmpty ())
return String.Empty;
- var result = new StringBuilder (64);
- if (version > 0)
- result.Append ("$Version=").Append (version).Append ("; ");
-
- result.Append (name).Append ("=").Append (val);
if (version == 0)
- return result.ToString ();
+ return String.Format ("{0}={1}", name, val);
+ var result = new StringBuilder ();
+ result.AppendFormat ("$Version={0}; {1}={2}", version, name, val);
if (!path.IsNullOrEmpty ())
- result.Append ("; $Path=").Append (path);
+ result.AppendFormat ("; $Path={0}", path);
else if (!uri.IsNull ())
- result.Append ("; $Path=").Append (uri.GetAbsolutePath ());
+ result.AppendFormat ("; $Path={0}", uri.GetAbsolutePath ());
else
result.Append ("; $Path=/");
bool append_domain = uri.IsNull () || uri.Host != domain;
if (append_domain && !domain.IsNullOrEmpty ())
- result.Append ("; $Domain=").Append (domain);
+ result.AppendFormat ("; $Domain={0}", domain);
if (!port.IsNullOrEmpty ())
- result.Append ("; $Port=").Append (port);
+ result.AppendFormat ("; $Port={0}", port);
return result.ToString ();
}
+ // From server to client
+ internal string ToResponseString ()
+ {
+ return name.IsEmpty ()
+ ? String.Empty
+ : version == 0
+ ? ToResponseStringVersion0 ()
+ : ToResponseStringVersion1 ();
+ }
+
#endregion
#region Public Methods
@@ -634,11 +694,11 @@ namespace WebSocketSharp.Net {
{
var cookie = comparand as Cookie;
return !cookie.IsNull() &&
- String.Compare (this.name, cookie.Name, true, CultureInfo.InvariantCulture) == 0 &&
- String.Compare (this.val, cookie.Value, false, CultureInfo.InvariantCulture) == 0 &&
- String.Compare (this.path, cookie.Path, false, CultureInfo.InvariantCulture) == 0 &&
- String.Compare (this.domain, cookie.Domain, true, CultureInfo.InvariantCulture) == 0 &&
- this.version == cookie.Version;
+ name.Equals (cookie.Name, StringComparison.InvariantCultureIgnoreCase) &&
+ val.Equals (cookie.Value, StringComparison.InvariantCulture) &&
+ path.Equals (cookie.Path, StringComparison.InvariantCulture) &&
+ domain.Equals (cookie.Domain, StringComparison.InvariantCultureIgnoreCase) &&
+ version == cookie.Version;
}
///
@@ -671,7 +731,7 @@ namespace WebSocketSharp.Net {
// i.e., only used for clients
// see para 4.2.2 of RFC 2109 and para 3.3.4 of RFC 2965
// see also bug #316017
- return ToString (null);
+ return ToRequestString (null);
}
#endregion
diff --git a/websocket-sharp/Net/CookieCollection.cs b/websocket-sharp/Net/CookieCollection.cs
index a74ff64e..b3477907 100644
--- a/websocket-sharp/Net/CookieCollection.cs
+++ b/websocket-sharp/Net/CookieCollection.cs
@@ -5,7 +5,8 @@
// Authors:
// Lawrence Pit (loz@cable.a2000.nl)
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
-// Sebastien Pouliot
+// Sebastien Pouliot (sebastien@ximian.com)
+// sta (sta.blockhead@gmail.com)
//
// Copyright (c) 2004,2009 Novell, Inc (http://www.novell.com)
// Copyright (c) 2012-2013 sta.blockhead (sta.blockhead@gmail.com)
@@ -34,7 +35,9 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
+using System.Linq;
using System.Runtime.Serialization;
+using System.Text;
namespace WebSocketSharp.Net {
@@ -90,6 +93,16 @@ namespace WebSocketSharp.Net {
get { return list; }
}
+ internal IEnumerable Sorted {
+ get {
+ return from cookie in list
+ orderby cookie.Version,
+ cookie.Name,
+ cookie.Path.Length descending
+ select cookie;
+ }
+ }
+
#endregion
#region Public Properties
@@ -137,7 +150,7 @@ namespace WebSocketSharp.Net {
/// A with the specified in the .
///
///
- /// An that is the zero-based index of the to find.
+ /// An is the zero-based index of the to find.
///
///
/// is less than zero or is greater than or
@@ -159,7 +172,7 @@ namespace WebSocketSharp.Net {
/// A with the specified in the .
///
///
- /// A that is the name of the to find.
+ /// A is the name of the to find.
///
///
/// is .
@@ -170,7 +183,7 @@ namespace WebSocketSharp.Net {
throw new ArgumentNullException ("name");
foreach (var cookie in list) {
- if (0 == String.Compare (cookie.Name, name, true, CultureInfo.InvariantCulture))
+ if (cookie.Name.Equals (name, StringComparison.InvariantCultureIgnoreCase))
return cookie;
}
@@ -197,24 +210,179 @@ namespace WebSocketSharp.Net {
#region Private Method
+ static CookieCollection ParseRequest (string value)
+ {
+ var cookies = new CookieCollection ();
+
+ Cookie cookie = null;
+ int version = 0;
+ string [] pairs = value.Split (',', ';');
+ for (int i = 0; i < pairs.Length; i++)
+ {
+ string pair = pairs [i].Trim ();
+ if (pair.IsEmpty ())
+ continue;
+
+ if (pair.StartsWith ("$version", StringComparison.InvariantCultureIgnoreCase)) {
+ version = Int32.Parse (pair.GetValueInternal ("=").Trim ('"'));
+ }
+ else if (pair.StartsWith ("$path", StringComparison.InvariantCultureIgnoreCase)) {
+ if (!cookie.IsNull ())
+ cookie.Path = pair.GetValueInternal ("=");
+ }
+ else if (pair.StartsWith ("$domain", StringComparison.InvariantCultureIgnoreCase)) {
+ if (!cookie.IsNull ())
+ cookie.Domain = pair.GetValueInternal ("=");
+ }
+ else if (pair.StartsWith ("$port", StringComparison.InvariantCultureIgnoreCase)) {
+ if (!pair.Equals ("$port", StringComparison.InvariantCultureIgnoreCase) && !pair.EndsWith ("\"")) {
+ var buffer = new StringBuilder (pair);
+ string port;
+ while (i < pairs.Length - 1) {
+ port = pairs [++i].Trim ();
+ buffer.AppendFormat (", {0}", port);
+ if (port.EndsWith ("\""))
+ break;
+ }
+
+ pair = buffer.ToString ();
+ }
+
+ if (!cookie.IsNull ())
+ cookie.Port = pair.GetValueInternal ("=");
+ }
+ else {
+ if (!cookie.IsNull ())
+ cookies.Add (cookie);
+
+ cookie = new Cookie (pair.GetNameInternal ("="), pair.GetValueInternal ("="));
+ if (version != 0)
+ cookie.Version = version;
+ }
+ }
+
+ if (!cookie.IsNull ())
+ cookies.Add (cookie);
+
+ return cookies;
+ }
+
+ static CookieCollection ParseResponse (string value)
+ {
+ var cookies = new CookieCollection ();
+
+ Cookie cookie = null;
+ string [] pairs = value.Split (',', ';');
+ for (int i = 0; i < pairs.Length; i++)
+ {
+ string pair = pairs [i].Trim ();
+ if (pair.IsEmpty ())
+ continue;
+
+ if (pair.StartsWith ("version", StringComparison.InvariantCultureIgnoreCase)) {
+ if (!cookie.IsNull ())
+ cookie.Version = Int32.Parse (pair.GetValueInternal ("=").Trim ('"'));
+ }
+ else if (pair.StartsWith ("expires", StringComparison.InvariantCultureIgnoreCase)) {
+ var buffer = new StringBuilder (pair.GetValueInternal ("="));
+ if (i < pairs.Length - 1)
+ buffer.AppendFormat (", {0}", pairs [++i].Trim ());
+
+ DateTime expires;
+ if (!DateTime.TryParseExact (buffer.ToString (),
+ new string [] { "ddd, dd'-'MMM'-'yyyy HH':'mm':'ss 'GMT'", "r" },
+ CultureInfo.CreateSpecificCulture("en-US"),
+ DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal,
+ out expires))
+ expires = DateTime.Now;
+
+ if (!cookie.IsNull () && cookie.Expires == DateTime.MinValue)
+ cookie.Expires = expires.ToLocalTime ();
+ }
+ else if (pair.StartsWith ("max-age", StringComparison.InvariantCultureIgnoreCase)) {
+ int max = Int32.Parse (pair.GetValueInternal ("=").Trim ('"'));
+ var expires = DateTime.Now.AddSeconds ((double) max);
+ if (!cookie.IsNull ())
+ cookie.Expires = expires;
+ }
+ else if (pair.StartsWith ("path", StringComparison.InvariantCultureIgnoreCase)) {
+ if (!cookie.IsNull ())
+ cookie.Path = pair.GetValueInternal ("=");
+ }
+ else if (pair.StartsWith ("domain", StringComparison.InvariantCultureIgnoreCase)) {
+ if (!cookie.IsNull ())
+ cookie.Domain = pair.GetValueInternal ("=");
+ }
+ else if (pair.StartsWith ("port", StringComparison.InvariantCultureIgnoreCase)) {
+ if (!pair.Equals ("port", StringComparison.InvariantCultureIgnoreCase) && !pair.EndsWith ("\"")) {
+ var buffer = new StringBuilder (pair);
+ string port;
+ while (i < pairs.Length - 1) {
+ port = pairs [++i].Trim ();
+ buffer.AppendFormat (", {0}", port);
+ if (port.EndsWith ("\""))
+ break;
+ }
+
+ pair = buffer.ToString ();
+ }
+
+ if (!cookie.IsNull ())
+ cookie.Port = pair.GetValueInternal ("=");
+ }
+ else if (pair.StartsWith ("comment", StringComparison.InvariantCultureIgnoreCase)) {
+ if (!cookie.IsNull ())
+ cookie.Comment = pair.GetValueInternal ("=").UrlDecode ();
+ }
+ else if (pair.StartsWith ("commenturl", StringComparison.InvariantCultureIgnoreCase)) {
+ if (!cookie.IsNull ())
+ cookie.CommentUri = pair.GetValueInternal ("=").Trim ('"').ToUri ();
+ }
+ else if (pair.StartsWith ("discard", StringComparison.InvariantCultureIgnoreCase)) {
+ if (!cookie.IsNull ())
+ cookie.Discard = true;
+ }
+ else if (pair.StartsWith ("secure", StringComparison.InvariantCultureIgnoreCase)) {
+ if (!cookie.IsNull ())
+ cookie.Secure = true;
+ }
+ else if (pair.StartsWith ("httponly", StringComparison.InvariantCultureIgnoreCase)) {
+ if (!cookie.IsNull ())
+ cookie.HttpOnly = true;
+ }
+ else {
+ if (!cookie.IsNull ())
+ cookies.Add (cookie);
+
+ cookie = new Cookie (pair.GetNameInternal ("="), pair.GetValueInternal ("="));
+ }
+ }
+
+ if (!cookie.IsNull ())
+ cookies.Add (cookie);
+
+ return cookies;
+ }
+
int SearchCookie (Cookie cookie)
{
string name = cookie.Name;
- string domain = cookie.Domain;
string path = cookie.Path;
+ string domain = cookie.Domain;
+ int version = cookie.Version;
for (int i = list.Count - 1; i >= 0; i--) {
Cookie c = list [i];
- if (0 != String.Compare (name, c.Name, true, CultureInfo.InvariantCulture))
+ if (!c.Name.Equals (name, StringComparison.InvariantCultureIgnoreCase))
continue;
- if (0 != String.Compare (domain, c.Domain, true, CultureInfo.InvariantCulture))
+ if (!c.Path.Equals (path, StringComparison.InvariantCulture))
continue;
- if (0 != String.Compare (path, c.Path, false, CultureInfo.InvariantCulture))
+ if (!c.Domain.Equals (domain, StringComparison.InvariantCultureIgnoreCase))
continue;
- if (c.Version != cookie.Version)
+ if (c.Version != version)
continue;
return i;
@@ -227,6 +395,34 @@ namespace WebSocketSharp.Net {
#region Internal Method
+ internal static CookieCollection Parse (string value, bool response)
+ {
+ return response
+ ? ParseResponse (value)
+ : ParseRequest (value);
+ }
+
+ internal void SetOrRemove (Cookie cookie)
+ {
+ int pos = SearchCookie (cookie);
+ if (pos == -1) {
+ if (!cookie.Expired)
+ list.Add (cookie);
+ }
+ else {
+ if (!cookie.Expired)
+ list [pos] = cookie;
+ else
+ list.RemoveAt (pos);
+ }
+ }
+
+ internal void SetOrRemove (CookieCollection cookies)
+ {
+ foreach (Cookie cookie in cookies)
+ SetOrRemove (cookie);
+ }
+
internal void Sort ()
{
if (list.Count > 0)
@@ -281,7 +477,7 @@ namespace WebSocketSharp.Net {
/// starting at the specified in the .
///
///
- /// An that is the destination of the elements copied from the .
+ /// An is the destination of the elements copied from the .
///
///
/// An that indicates the zero-based index in at which copying begins.
@@ -292,6 +488,22 @@ namespace WebSocketSharp.Net {
///
/// is less than zero.
///
+ ///
+ ///
+ /// is multidimensional.
+ ///
+ ///
+ /// -or-
+ ///
+ ///
+ /// The number of elements in the is greater than the available space
+ /// from index to the end of the destination .
+ ///
+ ///
+ ///
+ /// The elements in the cannot be cast automatically
+ /// to the type of the destination .
+ ///
public void CopyTo (Array array, int index)
{
if (array.IsNull ())
@@ -300,7 +512,16 @@ namespace WebSocketSharp.Net {
if (index < 0)
throw new ArgumentOutOfRangeException ("index", "Must not be less than zero.");
- // TODO: Support for ArgumentException and InvalidCastException.
+ if (array.Rank > 1)
+ throw new ArgumentException ("Must not be multidimensional.", "array");
+
+ if (array.Length - index < list.Count)
+ throw new ArgumentException (
+ "The number of elements in this collection is greater than the available space of the destination array.");
+
+ if (!array.GetType ().GetElementType ().IsAssignableFrom (typeof (Cookie)))
+ throw new InvalidCastException (
+ "The elements in this collection cannot be cast automatically to the type of the destination array.");
(list as IList).CopyTo (array, index);
}
@@ -310,7 +531,7 @@ namespace WebSocketSharp.Net {
/// starting at the specified in the .
///
///
- /// An array of that is the destination of the elements copied from the .
+ /// An array of is the destination of the elements copied from the .
///
///
/// An that indicates the zero-based index in at which copying begins.
@@ -321,6 +542,10 @@ namespace WebSocketSharp.Net {
///
/// is less than zero.
///
+ ///
+ /// The number of elements in the is greater than the available space
+ /// from index to the end of the destination .
+ ///
public void CopyTo (Cookie [] array, int index)
{
if (array.IsNull ())
@@ -329,7 +554,9 @@ namespace WebSocketSharp.Net {
if (index < 0)
throw new ArgumentOutOfRangeException ("index", "Must not be less than zero.");
- // TODO: Support for ArgumentException.
+ if (array.Length - index < list.Count)
+ throw new ArgumentException (
+ "The number of elements in this collection is greater than the available space of the destination array.");
list.CopyTo (array, index);
}
diff --git a/websocket-sharp/Net/HttpListenerResponse.cs b/websocket-sharp/Net/HttpListenerResponse.cs
index 51c2e5f3..26a999fb 100644
--- a/websocket-sharp/Net/HttpListenerResponse.cs
+++ b/websocket-sharp/Net/HttpListenerResponse.cs
@@ -555,7 +555,7 @@ namespace WebSocketSharp.Net {
if (cookies != null) {
foreach (Cookie cookie in cookies)
- headers.SetInternal ("Set-Cookie", cookie.ToClientString (), true);
+ headers.SetInternal ("Set-Cookie", cookie.ToResponseString (), true);
}
StreamWriter writer = new StreamWriter (ms, encoding, 256);
diff --git a/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs b/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs
index d0e555d8..cc25c578 100644
--- a/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs
+++ b/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs
@@ -43,6 +43,7 @@ namespace WebSocketSharp.Net.WebSockets {
{
#region Fields
+ private CookieCollection _cookies;
private TcpClient _tcpClient;
private bool _isSecure;
private RequestHandshake _request;
@@ -80,14 +81,14 @@ namespace WebSocketSharp.Net.WebSockets {
/// Gets the cookies used in the WebSocket opening handshake.
///
///
- /// A that contains the cookies.
+ /// A that contains the cookies.
///
- ///
- /// This property is not implemented.
- ///
public override CookieCollection CookieCollection {
get {
- throw new NotImplementedException();
+ if (_cookies.IsNull())
+ _cookies = _request.Cookies;
+
+ return _cookies;
}
}
diff --git a/websocket-sharp/RequestHandshake.cs b/websocket-sharp/RequestHandshake.cs
index b9b2c68a..27e18db2 100644
--- a/websocket-sharp/RequestHandshake.cs
+++ b/websocket-sharp/RequestHandshake.cs
@@ -28,6 +28,7 @@
using System;
using System.Collections.Specialized;
+using System.Linq;
using System.Text;
using WebSocketSharp.Net;
using WebSocketSharp.Net.WebSockets;
@@ -65,6 +66,12 @@ namespace WebSocketSharp {
#region Properties
+ public CookieCollection Cookies {
+ get {
+ return Headers.GetCookies(false);
+ }
+ }
+
public string HttpMethod { get; private set; }
public bool IsWebSocketRequest {
@@ -148,7 +155,7 @@ namespace WebSocketSharp {
var headers = new WebHeaderCollection();
for (int i = 1; i < request.Length; i++)
- headers.SetInternal (request[i], false);
+ headers.SetInternal(request[i], false);
return new RequestHandshake {
Headers = headers,
@@ -162,6 +169,20 @@ namespace WebSocketSharp {
#region Public Method
+ public void SetCookies(CookieCollection cookies)
+ {
+ if (cookies.IsNull() || cookies.Count == 0)
+ return;
+
+ var sorted = cookies.Sorted.ToArray();
+ var header = new StringBuilder(sorted[0].ToString());
+ for (int i = 1; i < sorted.Length; i++)
+ if (!sorted[i].Expired)
+ header.AppendFormat("; {0}", sorted[i].ToString());
+
+ AddHeader("Cookie", header.ToString());
+ }
+
public override string ToString()
{
var buffer = new StringBuilder();
diff --git a/websocket-sharp/ResponseHandshake.cs b/websocket-sharp/ResponseHandshake.cs
index 2c2e0a1d..e662694f 100644
--- a/websocket-sharp/ResponseHandshake.cs
+++ b/websocket-sharp/ResponseHandshake.cs
@@ -54,6 +54,12 @@ namespace WebSocketSharp {
#region Properties
+ public CookieCollection Cookies {
+ get {
+ return Headers.GetCookies(true);
+ }
+ }
+
public bool IsWebSocketResponse {
get {
return ProtocolVersion < HttpVersion.Version11
@@ -96,7 +102,7 @@ namespace WebSocketSharp {
var headers = new WebHeaderCollection();
for (int i = 1; i < response.Length; i++)
- headers.SetInternal (response[i], true);
+ headers.SetInternal(response[i], true);
return new ResponseHandshake {
Headers = headers,
@@ -106,6 +112,15 @@ namespace WebSocketSharp {
};
}
+ public void SetCookies(CookieCollection cookies)
+ {
+ if (cookies.IsNull() || cookies.Count == 0)
+ return;
+
+ foreach (var cookie in cookies.Sorted)
+ AddHeader("Set-Cookie", cookie.ToResponseString());
+ }
+
public override string ToString()
{
var buffer = new StringBuilder();
diff --git a/websocket-sharp/Server/WebSocketService.cs b/websocket-sharp/Server/WebSocketService.cs
index 0b66d0a8..89f538c9 100644
--- a/websocket-sharp/Server/WebSocketService.cs
+++ b/websocket-sharp/Server/WebSocketService.cs
@@ -30,6 +30,7 @@ using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Threading;
+using WebSocketSharp.Net;
using WebSocketSharp.Net.WebSockets;
namespace WebSocketSharp.Server {
@@ -148,8 +149,14 @@ namespace WebSocketSharp.Server {
if (IsBound)
return;
- _context = context;
- _sessions = sessions;
+ if (!ProcessCookies(context.CookieCollection, context.WebSocket.CookieCollection))
+ {
+ context.WebSocket.Close(HttpStatusCode.BadRequest);
+ return;
+ }
+
+ _context = context;
+ _sessions = sessions;
_websocket = context.WebSocket;
_websocket.OnOpen += onOpen;
@@ -211,6 +218,23 @@ namespace WebSocketSharp.Server {
{
}
+ ///
+ /// Processes the cookies used in the WebSocket opening handshake.
+ ///
+ ///
+ /// true if processing the cookies is successfully; otherwise, false.
+ ///
+ ///
+ /// A that contains a collection of the HTTP Cookies received from the client.
+ ///
+ ///
+ /// A that contains a collection of the HTTP Cookies to send to the client.
+ ///
+ protected virtual bool ProcessCookies(CookieCollection request, CookieCollection response)
+ {
+ return true;
+ }
+
#endregion
#region Public Methods
diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs
index ed54c587..e8f4eab0 100644
--- a/websocket-sharp/WebSocket.cs
+++ b/websocket-sharp/WebSocket.cs
@@ -67,6 +67,7 @@ namespace WebSocketSharp {
private string _base64key;
private bool _client;
private Action _closeContext;
+ private CookieCollection _cookies;
private WebSocketContext _context;
private string _extensions;
private AutoResetEvent _exitReceiving;
@@ -87,6 +88,7 @@ namespace WebSocketSharp {
private WebSocket()
{
+ _cookies = new CookieCollection();
_extensions = String.Empty;
_forClose = new Object();
_forSend = new Object();
@@ -206,8 +208,35 @@ namespace WebSocketSharp {
#endregion
+ #region Internal Property
+
+ internal CookieCollection CookieCollection {
+ get {
+ return _cookies;
+ }
+ }
+
+ #endregion
+
#region Public Properties
+ ///
+ /// Gets the cookies used in the WebSocket opening handshake.
+ ///
+ ///
+ /// An IEnumerable<Cookie> interface that provides an enumerator which supports the iteration
+ /// over the collection of cookies.
+ ///
+ public IEnumerable Cookies {
+ get {
+ lock (_cookies.SyncRoot)
+ {
+ return from Cookie cookie in _cookies
+ select cookie;
+ }
+ }
+ }
+
///
/// Gets the extensions selected by the server.
///
@@ -492,6 +521,8 @@ namespace WebSocketSharp {
if (!_protocols.IsNullOrEmpty())
req.AddHeader("Sec-WebSocket-Protocol", _protocols);
req.AddHeader("Sec-WebSocket-Version", _version);
+ if (_cookies.Count > 0)
+ req.SetCookies(_cookies);
return req;
}
@@ -501,6 +532,8 @@ namespace WebSocketSharp {
{
var res = new ResponseHandshake();
res.AddHeader("Sec-WebSocket-Accept", createResponseKey());
+ if (_cookies.Count > 0)
+ res.SetCookies(_cookies);
return res;
}
@@ -852,6 +885,9 @@ namespace WebSocketSharp {
if (res.HeaderExists("Sec-WebSocket-Extensions"))
_extensions = res.Headers["Sec-WebSocket-Extensions"];
+ if (res.Cookies.Count > 0)
+ _cookies.SetOrRemove(res.Cookies);
+
return true;
}
@@ -1353,6 +1389,32 @@ namespace WebSocketSharp {
sendAsync(Opcode.BINARY, file.OpenRead(), completed);
}
+ ///
+ /// Sets a used in the WebSocket opening handshake.
+ ///
+ ///
+ /// A that contains an HTTP Cookie to set.
+ ///
+ public void SetCookie(Cookie cookie)
+ {
+ var msg = _readyState == WsState.OPEN
+ ? "The WebSocket connection has been established already."
+ : cookie.IsNull()
+ ? "'cookie' must not be null."
+ : String.Empty;
+
+ if (!msg.IsEmpty())
+ {
+ onError(msg);
+ return;
+ }
+
+ lock (_cookies.SyncRoot)
+ {
+ _cookies.SetOrRemove(cookie);
+ }
+ }
+
#endregion
}
}
diff --git a/websocket-sharp/bin/Debug/websocket-sharp.dll b/websocket-sharp/bin/Debug/websocket-sharp.dll
index 274194fa..da66f4cc 100755
Binary files a/websocket-sharp/bin/Debug/websocket-sharp.dll and b/websocket-sharp/bin/Debug/websocket-sharp.dll differ
diff --git a/websocket-sharp/bin/Debug/websocket-sharp.dll.mdb b/websocket-sharp/bin/Debug/websocket-sharp.dll.mdb
index 334c331d..42c27219 100644
Binary files a/websocket-sharp/bin/Debug/websocket-sharp.dll.mdb and b/websocket-sharp/bin/Debug/websocket-sharp.dll.mdb differ
diff --git a/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll b/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll
index 5993ee69..6329426a 100755
Binary files a/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll and b/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll differ
diff --git a/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll.mdb
index 0cf18085..41f3e6c0 100644
Binary files a/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll.mdb and b/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll.mdb differ
diff --git a/websocket-sharp/bin/Release/websocket-sharp.dll b/websocket-sharp/bin/Release/websocket-sharp.dll
index f9220eb0..a3a3d62a 100755
Binary files a/websocket-sharp/bin/Release/websocket-sharp.dll and b/websocket-sharp/bin/Release/websocket-sharp.dll differ
diff --git a/websocket-sharp/bin/Release_Ubuntu/websocket-sharp.dll b/websocket-sharp/bin/Release_Ubuntu/websocket-sharp.dll
index 51c796ed..44002b79 100755
Binary files a/websocket-sharp/bin/Release_Ubuntu/websocket-sharp.dll and b/websocket-sharp/bin/Release_Ubuntu/websocket-sharp.dll differ
diff --git a/websocket-sharp/bin/Release_Ubuntu/websocket-sharp.xml b/websocket-sharp/bin/Release_Ubuntu/websocket-sharp.xml
index a4204a65..4ebb5c09 100644
--- a/websocket-sharp/bin/Release_Ubuntu/websocket-sharp.xml
+++ b/websocket-sharp/bin/Release_Ubuntu/websocket-sharp.xml
@@ -152,6 +152,21 @@
A that contains the URI to get the absolute path from.
+
+
+ Gets the collection of cookies from the specified .
+
+
+ A that receives a collection of the HTTP Cookies.
+
+
+ A that contains a collection of the HTTP Headers.
+
+
+ true if gets from the response ;
+ from the request , false.
+
+
Gets the description of the HTTP status code using the specified .
@@ -928,6 +943,15 @@
Occurs when the WebSocket connection has been established.
+
+
+ Gets the cookies used in the WebSocket opening handshake.
+
+
+ An IEnumerable<Cookie> interface that provides an enumerator which supports the iteration
+ over the collection of cookies.
+
+
Gets the extensions selected by the server.
@@ -1123,6 +1147,14 @@
the asynchronous operation completes.
+
+
+ Sets a used in the WebSocket opening handshake.
+
+
+ A that contains an HTTP Cookie to set.
+
+
Provides the functions of the server that receives the WebSocket connection requests.
@@ -1316,6 +1348,20 @@
Occurs when the WebSocket connection has been established.
+
+
+ Processes the cookies used in the WebSocket opening handshake.
+
+
+ true if processing the cookies is successfully; otherwise, false.
+
+
+ A that contains a collection of the HTTP Cookies received from the client.
+
+
+ A that contains a collection of the HTTP Cookies to send to the client.
+
+
Broadcasts the specified array of to the clients of every instances
@@ -1697,7 +1743,7 @@
Gets or sets a value indicating whether the cookie has expired.
- true if the cookie has expired; otherwise, false.
+ true if the cookie has expired; otherwise, false. The default is false.
@@ -1706,6 +1752,7 @@
A that contains the date and time at which the cookie expires.
+ The default is .
@@ -1752,7 +1799,7 @@
A that contains a list of the TCP ports to which the cookie applies.
- The value specified for a set operation could not be parsed or is not enclosed in double quotes.
+ The value specified for a set operation is not enclosed in double quotes or could not be parsed.
@@ -1793,7 +1840,7 @@
to which the cookie conforms.
- The value specified for a set operation is less than zero.
+ The value specified for a set operation is not allowed. The value must be 0 or 1.
@@ -1845,7 +1892,7 @@
A with the specified in the .
- An that is the zero-based index of the to find.
+ An is the zero-based index of the to find.
is less than zero or is greater than or
@@ -1860,7 +1907,7 @@
A with the specified in the .
- A that is the name of the to find.
+ A is the name of the to find.
is .
@@ -1928,7 +1975,7 @@
starting at the specified in the .
- An that is the destination of the elements copied from the .
+ An is the destination of the elements copied from the .
An that indicates the zero-based index in at which copying begins.
@@ -1939,6 +1986,22 @@
is less than zero.
+
+
+ is multidimensional.
+
+
+ -or-
+
+
+ The number of elements in the is greater than the available space
+ from index to the end of the destination .
+
+
+
+ The elements in the cannot be cast automatically
+ to the type of the destination .
+
@@ -1946,7 +2009,7 @@
starting at the specified in the .
- An array of that is the destination of the elements copied from the .
+ An array of is the destination of the elements copied from the .
An that indicates the zero-based index in at which copying begins.
@@ -1957,6 +2020,10 @@
is less than zero.
+
+ The number of elements in the is greater than the available space
+ from index to the end of the destination .
+
@@ -4652,9 +4719,6 @@
A that contains the cookies.
-
- This property is not implemented.
-
diff --git a/websocket-sharp/doc/html/WebSocketSharp.Net/Cookie.html b/websocket-sharp/doc/html/WebSocketSharp.Net/Cookie.html
index 349fd088..bcdcbb35 100644
--- a/websocket-sharp/doc/html/WebSocketSharp.Net/Cookie.html
+++ b/websocket-sharp/doc/html/WebSocketSharp.Net/Cookie.html
@@ -991,7 +991,7 @@
public
bool Expired { get; set; }
Value
- true if the cookie has expired; otherwise, false.
+ true if the cookie has expired; otherwise, false. The default is false.
Remarks