diff --git a/websocket-sharp/Net/HttpListenerResponse.cs b/websocket-sharp/Net/HttpListenerResponse.cs
index 7570f20f..c0b011ff 100644
--- a/websocket-sharp/Net/HttpListenerResponse.cs
+++ b/websocket-sharp/Net/HttpListenerResponse.cs
@@ -56,6 +56,7 @@ namespace WebSocketSharp.Net
#region Private Fields
private bool _chunked;
+ private bool _closeConnection;
private Encoding _contentEncoding;
private long _contentLength;
private bool _contentLengthSet;
@@ -79,7 +80,6 @@ namespace WebSocketSharp.Net
internal HttpListenerResponse (HttpListenerContext context)
{
_context = context;
- _headers = new WebHeaderCollection ();
_keepAlive = true;
_statusCode = 200;
_statusDescription = "OK";
@@ -92,7 +92,11 @@ namespace WebSocketSharp.Net
internal bool CloseConnection {
get {
- return _headers["Connection"] == "close";
+ return _closeConnection;
+ }
+
+ set {
+ _closeConnection = value;
}
}
@@ -171,12 +175,12 @@ namespace WebSocketSharp.Net
///
/// A that represents the value of the Content-Type entity-header.
///
- ///
- /// The value specified for a set operation is empty.
- ///
///
/// The value specified for a set operation is .
///
+ ///
+ /// The value specified for a set operation is empty.
+ ///
///
/// The response has already been sent.
///
@@ -206,19 +210,12 @@ namespace WebSocketSharp.Net
///
/// A that contains the cookies sent with the response.
///
- ///
- /// The response has already been sent.
- ///
- ///
- /// This object is closed.
- ///
public CookieCollection Cookies {
get {
return _cookies ?? (_cookies = new CookieCollection ());
}
set {
- checkDisposedOrHeadersSent ();
_cookies = value;
}
}
@@ -229,31 +226,18 @@ namespace WebSocketSharp.Net
///
/// A that contains the headers sent to the client.
///
- ///
- /// The value specified for a set operation is .
- ///
///
- /// The headers has already been sent.
+ /// The value specified for a set operation isn't valid for a response.
///
public WebHeaderCollection Headers {
get {
- return _headers;
+ return _headers ?? (_headers = new WebHeaderCollection (HttpHeaderType.Response, false));
}
set {
- /*
- * "If you attempt to set a Content-Length, Keep-Alive, Transfer-Encoding,
- * or WWW-Authenticate header using the Headers property, an exception
- * will be thrown. Use the ContentLength64 or KeepAlive properties to set
- * these headers. You cannot set the Transfer-Encoding or WWW-Authenticate
- * headers manually."
- */
-
- // TODO: Check if this is marked readonly after the headers are sent.
-
- checkHeadersSent ();
- if (value == null)
- throw new ArgumentNullException ("value");
+ if (value != null && value.State != HttpHeaderType.Response)
+ throw new InvalidOperationException (
+ "The specified headers aren't valid for a response.");
_headers = value;
}
@@ -305,13 +289,13 @@ namespace WebSocketSharp.Net
///
/// A that represents the version used in the response.
///
+ ///
+ /// The value specified for a set operation is .
+ ///
///
/// The value specified for a set operation doesn't have its Major property set to 1 or
/// doesn't have its Minor property set to either 0 or 1.
///
- ///
- /// The value specified for a set operation is .
- ///
///
/// The response has already been sent.
///
@@ -344,9 +328,6 @@ namespace WebSocketSharp.Net
///
/// The value specified for a set operation is empty.
///
- ///
- /// The response has already been sent.
- ///
///
/// This object is closed.
///
@@ -356,8 +337,8 @@ namespace WebSocketSharp.Net
}
set {
- checkDisposedOrHeadersSent ();
- if (value.Length == 0)
+ checkDisposed ();
+ if (value != null && value.Length == 0)
throw new ArgumentException ("An empty string.", "value");
_location = value;
@@ -397,12 +378,12 @@ namespace WebSocketSharp.Net
///
/// The response has already been sent.
///
- ///
- /// The value specified for a set operation is invalid. Valid values are between 100 and 999.
- ///
///
/// This object is closed.
///
+ ///
+ /// The value specified for a set operation is invalid. Valid values are between 100 and 999.
+ ///
public int StatusCode {
get {
return _statusCode;
@@ -424,6 +405,9 @@ namespace WebSocketSharp.Net
///
/// A that represents the description of the status code.
///
+ ///
+ /// The value specified for a set operation is .
+ ///
///
/// The response has already been sent.
///
@@ -437,7 +421,10 @@ namespace WebSocketSharp.Net
set {
checkDisposedOrHeadersSent ();
- _statusDescription = value != null && value.Length > 0
+ if (value == null)
+ throw new ArgumentNullException ("value");
+
+ _statusDescription = value.Length > 0
? value
: _statusCode.GetStatusDescription ();
}
@@ -479,12 +466,6 @@ namespace WebSocketSharp.Net
throw new InvalidOperationException ("Cannot be changed after the headers are sent.");
}
- private void checkHeadersSent ()
- {
- if (_headersSent)
- throw new InvalidOperationException ("Cannot be changed after the headers are sent.");
- }
-
private void close (bool force)
{
_disposed = true;
@@ -510,8 +491,9 @@ namespace WebSocketSharp.Net
internal WebHeaderCollection WriteHeadersTo (MemoryStream destination, bool closing)
{
- var headers = new WebHeaderCollection ();
- headers.Add (_headers);
+ var headers = new WebHeaderCollection (HttpHeaderType.Response, true);
+ if (_headers != null)
+ headers.Add (_headers);
if (_contentType != null) {
var type = _contentType.IndexOf ("charset=", StringComparison.Ordinal) == -1 &&
@@ -546,13 +528,13 @@ namespace WebSocketSharp.Net
/*
* Apache forces closing the connection for these status codes:
- * - HttpStatusCode.BadRequest 400
- * - HttpStatusCode.RequestTimeout 408
- * - HttpStatusCode.LengthRequired 411
- * - HttpStatusCode.RequestEntityTooLarge 413
- * - HttpStatusCode.RequestUriTooLong 414
- * - HttpStatusCode.InternalServerError 500
- * - HttpStatusCode.ServiceUnavailable 503
+ * - 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 ||
@@ -620,6 +602,9 @@ namespace WebSocketSharp.Net
///
/// A that represents the value of the header to add.
///
+ ///
+ /// is or empty.
+ ///
///
///
/// or contains invalid characters.
@@ -631,30 +616,15 @@ namespace WebSocketSharp.Net
/// is a restricted header name.
///
///
- ///
- /// is or empty.
- ///
///
/// The length of is greater than 65,535 characters.
///
///
- ///
- /// The response has already been sent.
- ///
- ///
- /// -or-
- ///
- ///
- /// The header cannot be allowed to add to the current headers.
- ///
- ///
- ///
- /// This object is closed.
+ /// The header cannot be allowed to add to the current headers.
///
public void AddHeader (string name, string value)
{
- checkDisposedOrHeadersSent ();
- _headers.Set (name, value);
+ Headers.Set (name, value);
}
///
@@ -666,15 +636,8 @@ namespace WebSocketSharp.Net
///
/// is .
///
- ///
- /// The response has already been sent.
- ///
- ///
- /// This object is closed.
- ///
public void AppendCookie (Cookie cookie)
{
- checkDisposedOrHeadersSent ();
Cookies.Add (cookie);
}
@@ -688,6 +651,9 @@ namespace WebSocketSharp.Net
///
/// A that represents the value to append to the header.
///
+ ///
+ /// is or empty.
+ ///
///
///
/// or contains invalid characters.
@@ -699,30 +665,15 @@ namespace WebSocketSharp.Net
/// is a restricted header name.
///
///
- ///
- /// is or empty.
- ///
///
/// The length of is greater than 65,535 characters.
///
///
- ///
- /// The response has already been sent.
- ///
- ///
- /// -or-
- ///
- ///
- /// The current headers cannot allow the header to append a value.
- ///
- ///
- ///
- /// This object is closed.
+ /// The current headers cannot allow the header to append a value.
///
public void AppendHeader (string name, string value)
{
- checkDisposedOrHeadersSent ();
- _headers.Add (name, value);
+ Headers.Add (name, value);
}
///
@@ -781,24 +732,32 @@ namespace WebSocketSharp.Net
}
///
- /// Copies properties from the specified to this response.
+ /// Copies some properties from the specified to
+ /// this response.
///
///
/// A to copy.
///
- ///
- /// The response has already been sent.
- ///
- ///
- /// This object is closed.
+ ///
+ /// is .
///
public void CopyFrom (HttpListenerResponse templateResponse)
{
- checkDisposedOrHeadersSent ();
+ if (templateResponse == null)
+ throw new ArgumentNullException ("templateResponse");
+
+ if (templateResponse._headers != null) {
+ if (_headers != null)
+ _headers.Clear ();
+
+ Headers.Add (templateResponse._headers);
+ }
+ else if (_headers != null) {
+ _headers = null;
+ }
- _headers.Clear ();
- _headers.Add (templateResponse._headers);
_contentLength = templateResponse._contentLength;
+ _contentLengthSet = templateResponse._contentLengthSet;
_statusCode = templateResponse._statusCode;
_statusDescription = templateResponse._statusDescription;
_keepAlive = templateResponse._keepAlive;
@@ -806,22 +765,29 @@ namespace WebSocketSharp.Net
}
///
- /// Configures the response to redirect the client's request to the specified
- /// .
+ /// Configures the response to redirect the client's request to
+ /// the specified .
///
///
/// A that represents the URL to redirect the client's request to.
///
- ///
- /// The response has already been sent.
+ ///
+ /// is .
///
- ///
- /// This object is closed.
+ ///
+ /// is empty.
///
public void Redirect (string url)
{
- StatusCode = (int) HttpStatusCode.Redirect;
+ if (url == null)
+ throw new ArgumentNullException ("url");
+
+ if (url.Length == 0)
+ throw new ArgumentException ("An empty string.", "url");
+
_location = url;
+ _statusCode = 302;
+ _statusDescription = "Found";
}
///
@@ -830,21 +796,14 @@ namespace WebSocketSharp.Net
///
/// A to set.
///
- ///
- /// already exists in the cookies and couldn't be replaced.
- ///
///
/// is .
///
- ///
- /// The response has already been sent.
- ///
- ///
- /// This object is closed.
+ ///
+ /// already exists in the cookies and couldn't be replaced.
///
public void SetCookie (Cookie cookie)
{
- checkDisposedOrHeadersSent ();
if (cookie == null)
throw new ArgumentNullException ("cookie");
diff --git a/websocket-sharp/Net/ResponseStream.cs b/websocket-sharp/Net/ResponseStream.cs
index 250d2b9f..ad3c760a 100644
--- a/websocket-sharp/Net/ResponseStream.cs
+++ b/websocket-sharp/Net/ResponseStream.cs
@@ -130,7 +130,7 @@ namespace WebSocketSharp.Net
if (!_response.HeadersSent) {
if (!flushHeaders (closing)) {
if (closing)
- _response.Headers.InternalSet ("Connection", "close", true);
+ _response.CloseConnection = true;
return false;
}
@@ -181,7 +181,7 @@ namespace WebSocketSharp.Net
return false;
_write (buff.GetBuffer (), (int) start, (int) len);
- _response.Headers = headers;
+ _response.CloseConnection = headers["Connection"] == "close";
_response.HeadersSent = true;
}