|
|
|
@ -756,107 +756,6 @@ namespace WebSocketSharp.Net
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region Internal Methods
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal WebHeaderCollection WriteHeadersTo (MemoryStream destination)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var headers = new WebHeaderCollection (HttpHeaderType.Response, true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_headers != null)
|
|
|
|
|
|
|
|
headers.Add (_headers);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_contentType != null) {
|
|
|
|
|
|
|
|
headers.InternalSet (
|
|
|
|
|
|
|
|
"Content-Type",
|
|
|
|
|
|
|
|
createContentTypeHeaderText (_contentType, _contentEncoding),
|
|
|
|
|
|
|
|
true
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (headers["Server"] == null)
|
|
|
|
|
|
|
|
headers.InternalSet ("Server", "websocket-sharp/1.0", true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (headers["Date"] == null) {
|
|
|
|
|
|
|
|
headers.InternalSet (
|
|
|
|
|
|
|
|
"Date",
|
|
|
|
|
|
|
|
DateTime.UtcNow.ToString ("r", CultureInfo.InvariantCulture),
|
|
|
|
|
|
|
|
true
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_sendChunked) {
|
|
|
|
|
|
|
|
headers.InternalSet ("Transfer-Encoding", "chunked", true);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
headers.InternalSet (
|
|
|
|
|
|
|
|
"Content-Length",
|
|
|
|
|
|
|
|
_contentLength.ToString (CultureInfo.InvariantCulture),
|
|
|
|
|
|
|
|
true
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* Apache forces closing the connection for these status codes:
|
|
|
|
|
|
|
|
* - 400 Bad Request
|
|
|
|
|
|
|
|
* - 408 Request Timeout
|
|
|
|
|
|
|
|
* - 411 Length Required
|
|
|
|
|
|
|
|
* - 413 Request Entity Too Large
|
|
|
|
|
|
|
|
* - 414 Request-Uri Too Long
|
|
|
|
|
|
|
|
* - 500 Internal Server Error
|
|
|
|
|
|
|
|
* - 503 Service Unavailable
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
var closeConn = !_context.Request.KeepAlive
|
|
|
|
|
|
|
|
|| !_keepAlive
|
|
|
|
|
|
|
|
|| _statusCode == 400
|
|
|
|
|
|
|
|
|| _statusCode == 408
|
|
|
|
|
|
|
|
|| _statusCode == 411
|
|
|
|
|
|
|
|
|| _statusCode == 413
|
|
|
|
|
|
|
|
|| _statusCode == 414
|
|
|
|
|
|
|
|
|| _statusCode == 500
|
|
|
|
|
|
|
|
|| _statusCode == 503;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var reuses = _context.Connection.Reuses;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (closeConn || reuses >= 100) {
|
|
|
|
|
|
|
|
headers.InternalSet ("Connection", "close", true);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
headers.InternalSet (
|
|
|
|
|
|
|
|
"Keep-Alive",
|
|
|
|
|
|
|
|
String.Format ("timeout=15,max={0}", 100 - reuses),
|
|
|
|
|
|
|
|
true
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_context.Request.ProtocolVersion < HttpVersion.Version11)
|
|
|
|
|
|
|
|
headers.InternalSet ("Connection", "keep-alive", true);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_location != null)
|
|
|
|
|
|
|
|
headers.InternalSet ("Location", _location, true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_cookies != null) {
|
|
|
|
|
|
|
|
foreach (var cookie in _cookies)
|
|
|
|
|
|
|
|
headers.InternalSet ("Set-Cookie", cookie.ToResponseString (), true);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var enc = Encoding.UTF8;
|
|
|
|
|
|
|
|
var writer = new StreamWriter (destination, enc, 256);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
writer.Write (
|
|
|
|
|
|
|
|
"HTTP/{0} {1} {2}\r\n", _version, _statusCode, _statusDescription
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
writer.Write (headers.ToStringMultiValue (true));
|
|
|
|
|
|
|
|
writer.Flush ();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Assumes that the destination was at position 0.
|
|
|
|
|
|
|
|
destination.Position = enc.GetPreamble ().Length;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return headers;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region Public Methods
|
|
|
|
#region Public Methods
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
|