Fix for extensions for server

This commit is contained in:
sta 2014-02-10 17:17:57 +09:00
parent 685c4067a1
commit 5b9d219938
2 changed files with 57 additions and 56 deletions

View File

@ -426,11 +426,6 @@ namespace WebSocketSharp
: stream.ToByteArray (); : stream.ToByteArray ();
} }
internal static bool Equals (this string value, CompressionMethod method)
{
return value == method.ToCompressionExtension ();
}
/// <summary> /// <summary>
/// Determines whether the specified <see cref="int"/> equals the specified /// Determines whether the specified <see cref="int"/> equals the specified
/// <see cref="char"/>, and invokes the specified Action&lt;int&gt; delegate /// <see cref="char"/>, and invokes the specified Action&lt;int&gt; delegate
@ -709,10 +704,9 @@ namespace WebSocketSharp
null); null);
} }
internal static string RemovePrefix ( internal static string RemovePrefix (this string value, params string [] prefixes)
this string value, params string [] prefixes)
{ {
int i = 0; var i = 0;
foreach (var prefix in prefixes) { foreach (var prefix in prefixes) {
if (value.StartsWith (prefix)) { if (value.StartsWith (prefix)) {
i = prefix.Length; i = prefix.Length;
@ -728,13 +722,16 @@ namespace WebSocketSharp
internal static IEnumerable<string> SplitHeaderValue ( internal static IEnumerable<string> SplitHeaderValue (
this string value, params char [] separator) this string value, params char [] separator)
{ {
var len = value.Length;
var separators = new string (separator); var separators = new string (separator);
var buffer = new StringBuilder (64);
int len = value.Length; var buffer = new StringBuilder (32);
bool quoted = false; var quoted = false;
bool escaped = false; var escaped = false;
for (int i = 0; i < len; i++) {
char c = value [i]; char c;
for (var i = 0; i < len; i++) {
c = value [i];
if (c == '"') { if (c == '"') {
if (escaped) if (escaped)
escaped = !escaped; escaped = !escaped;
@ -749,6 +746,7 @@ namespace WebSocketSharp
if (!quoted) { if (!quoted) {
yield return buffer.ToString (); yield return buffer.ToString ();
buffer.Length = 0; buffer.Length = 0;
continue; continue;
} }
} }
@ -791,22 +789,22 @@ namespace WebSocketSharp
: buffer.Reverse ().ToArray (); : buffer.Reverse ().ToArray ();
} }
internal static string ToCompressionExtension (this CompressionMethod method) internal static CompressionMethod ToCompressionMethod (this string value)
{
foreach (CompressionMethod method in Enum.GetValues (typeof (CompressionMethod)))
if (method.ToExtensionString () == value)
return method;
return CompressionMethod.NONE;
}
internal static string ToExtensionString (this CompressionMethod method)
{ {
return method != CompressionMethod.NONE return method != CompressionMethod.NONE
? String.Format ("permessage-{0}", method.ToString ().ToLower ()) ? String.Format ("permessage-{0}", method.ToString ().ToLower ())
: String.Empty; : String.Empty;
} }
internal static CompressionMethod ToCompressionMethod (this string value)
{
foreach (CompressionMethod method in Enum.GetValues (typeof (CompressionMethod)))
if (value.Equals (method))
return method;
return CompressionMethod.NONE;
}
internal static System.Net.IPAddress ToIPAddress ( internal static System.Net.IPAddress ToIPAddress (
this string hostNameOrAddress) this string hostNameOrAddress)
{ {

View File

@ -593,9 +593,7 @@ namespace WebSocketSharp
{ {
_logger.Debug ( _logger.Debug (
String.Format ( String.Format (
"A WebSocket connection request from {0}:\n{1}", "A WebSocket connection request from {0}:\n{1}", _context.UserEndPoint, _context));
_context.UserEndPoint,
_context));
var msg = checkIfValidHandshakeRequest (_context); var msg = checkIfValidHandshakeRequest (_context);
if (msg != null) { if (msg != null) {
@ -608,13 +606,12 @@ namespace WebSocketSharp
} }
if (_protocol != null && if (_protocol != null &&
!_context.SecWebSocketProtocols.Contains ( !_context.SecWebSocketProtocols.Contains (protocol => protocol == _protocol))
protocol => protocol == _protocol))
_protocol = null; _protocol = null;
var extensions = _context.Headers ["Sec-WebSocket-Extensions"]; var extensions = _context.Headers ["Sec-WebSocket-Extensions"];
if (extensions != null && extensions.Length > 0) if (extensions != null && extensions.Length > 0)
processRequestedExtensions (extensions); acceptSecWebSocketExtensionsHeader (extensions);
return send (createHandshakeResponse ()); return send (createHandshakeResponse ());
} }
@ -636,6 +633,34 @@ namespace WebSocketSharp
return true; return true;
} }
// As server
private void acceptSecWebSocketExtensionsHeader (string value)
{
var extensions = new StringBuilder (32);
var compress = false;
foreach (var extension in value.SplitHeaderValue (',')) {
var trimed = extension.Trim ();
var unprefixed = trimed.RemovePrefix ("x-webkit-");
if (!compress && unprefixed.IsCompressionExtension ()) {
var method = unprefixed.ToCompressionMethod ();
if (method != CompressionMethod.NONE) {
_compression = method;
compress = true;
extensions.Append (trimed + ", ");
}
}
}
var len = extensions.Length;
if (len > 0) {
extensions.Length = len - 2;
_extensions = extensions.ToString ();
}
}
private bool acceptUnsupportedFrame ( private bool acceptUnsupportedFrame (
WsFrame frame, CloseStatusCode code, string reason) WsFrame frame, CloseStatusCode code, string reason)
{ {
@ -682,8 +707,7 @@ namespace WebSocketSharp
? "Invalid Host header." ? "Invalid Host header."
: !validateSecWebSocketKeyHeader (headers ["Sec-WebSocket-Key"]) : !validateSecWebSocketKeyHeader (headers ["Sec-WebSocket-Key"])
? "Invalid Sec-WebSocket-Key header." ? "Invalid Sec-WebSocket-Key header."
: !validateSecWebSocketVersionClientHeader ( : !validateSecWebSocketVersionClientHeader (headers ["Sec-WebSocket-Version"])
headers ["Sec-WebSocket-Version"])
? "Invalid Sec-WebSocket-Version header." ? "Invalid Sec-WebSocket-Version header."
: !validateCookies (context.CookieCollection, _cookies) : !validateCookies (context.CookieCollection, _cookies)
? "Invalid Cookies." ? "Invalid Cookies."
@ -883,8 +907,9 @@ namespace WebSocketSharp
private string createExtensionsRequest () private string createExtensionsRequest ()
{ {
var extensions = new StringBuilder (32); var extensions = new StringBuilder (32);
if (_compression != CompressionMethod.NONE) if (_compression != CompressionMethod.NONE)
extensions.Append (_compression.ToCompressionExtension ()); extensions.Append (_compression.ToExtensionString ());
return extensions.Length > 0 return extensions.Length > 0
? extensions.ToString () ? extensions.ToString ()
@ -1015,28 +1040,6 @@ namespace WebSocketSharp
} }
} }
// As server
private void processRequestedExtensions (string extensions)
{
var comp = false;
var buffer = new List<string> ();
foreach (var e in extensions.SplitHeaderValue (',')) {
var extension = e.Trim ();
var tmp = extension.RemovePrefix ("x-webkit-");
if (!comp && tmp.IsCompressionExtension ()) {
var method = tmp.ToCompressionMethod ();
if (method != CompressionMethod.NONE) {
_compression = method;
comp = true;
buffer.Add (extension);
}
}
}
if (buffer.Count > 0)
_extensions = buffer.ToArray ().ToString (", ");
}
// As client // As client
private HandshakeResponse receiveHandshakeResponse () private HandshakeResponse receiveHandshakeResponse ()
{ {
@ -1374,7 +1377,7 @@ namespace WebSocketSharp
var extensions = value.SplitHeaderValue (','); var extensions = value.SplitHeaderValue (',');
if (extensions.Contains ( if (extensions.Contains (
extension => !extension.Trim ().Equals (_compression))) extension => extension.Trim () != _compression.ToExtensionString ()))
return false; return false;
_extensions = value; _extensions = value;