Refactored HttpListenerResponse.cs
This commit is contained in:
parent
de88dc3b15
commit
6a063c64d4
@ -33,7 +33,7 @@
|
|||||||
#region Authors
|
#region Authors
|
||||||
/*
|
/*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Gonzalo Paniagua Javier <gonzalo@novell.com>
|
* - Gonzalo Paniagua Javier <gonzalo@novell.com>
|
||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -41,14 +41,12 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace WebSocketSharp.Net
|
namespace WebSocketSharp.Net
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides access to a response to a request being processed by the
|
/// Provides the access to a response to a request received by the <see cref="HttpListener"/>.
|
||||||
/// <see cref="HttpListener"/>.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// The HttpListenerResponse class cannot be inherited.
|
/// The HttpListenerResponse class cannot be inherited.
|
||||||
@ -67,6 +65,7 @@ namespace WebSocketSharp.Net
|
|||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private bool _forceCloseChunked;
|
private bool _forceCloseChunked;
|
||||||
private WebHeaderCollection _headers;
|
private WebHeaderCollection _headers;
|
||||||
|
private bool _headersSent;
|
||||||
private bool _keepAlive;
|
private bool _keepAlive;
|
||||||
private string _location;
|
private string _location;
|
||||||
private ResponseStream _outputStream;
|
private ResponseStream _outputStream;
|
||||||
@ -76,12 +75,6 @@ namespace WebSocketSharp.Net
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Internal Fields
|
|
||||||
|
|
||||||
internal bool HeadersSent;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Internal Constructors
|
#region Internal Constructors
|
||||||
|
|
||||||
internal HttpListenerResponse (HttpListenerContext context)
|
internal HttpListenerResponse (HttpListenerContext context)
|
||||||
@ -104,37 +97,37 @@ namespace WebSocketSharp.Net
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal bool HeadersSent {
|
||||||
|
get {
|
||||||
|
return _headersSent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Public Properties
|
#region Public Properties
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the encoding that can be used with the entity body data
|
/// Gets or sets the encoding for the entity body data included in the response.
|
||||||
/// included in the response.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// A <see cref="Encoding"/> that represents the encoding that can be used
|
/// A <see cref="Encoding"/> that represents the encoding for the entity body data, or
|
||||||
/// with the entity body data.
|
/// <see langword="null"/> if no encoding is specified.
|
||||||
/// </value>
|
/// </value>
|
||||||
/// <exception cref="InvalidOperationException">
|
/// <exception cref="InvalidOperationException">
|
||||||
/// The response has been sent already.
|
/// The response has already been sent.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="ObjectDisposedException">
|
/// <exception cref="ObjectDisposedException">
|
||||||
/// This object is closed.
|
/// This object is closed.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public Encoding ContentEncoding {
|
public Encoding ContentEncoding {
|
||||||
get {
|
get {
|
||||||
return _contentEncoding ?? (_contentEncoding = Encoding.Default);
|
checkDisposedOrHeadersSent ();
|
||||||
|
return _contentEncoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
set {
|
set {
|
||||||
if (_disposed)
|
checkDisposedOrHeadersSent ();
|
||||||
throw new ObjectDisposedException (GetType ().ToString ());
|
|
||||||
|
|
||||||
if (HeadersSent)
|
|
||||||
throw new InvalidOperationException (
|
|
||||||
"Cannot be changed after headers are sent.");
|
|
||||||
|
|
||||||
_contentEncoding = value;
|
_contentEncoding = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,35 +136,28 @@ namespace WebSocketSharp.Net
|
|||||||
/// Gets or sets the size of the entity body data included in the response.
|
/// Gets or sets the size of the entity body data included in the response.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// A <see cref="long"/> that represents the value of the Content-Length
|
/// A <see cref="long"/> that represents the value of the Content-Length entity-header field.
|
||||||
/// entity-header field. The value is a number of bytes in the entity body
|
/// The value is a number of bytes in the entity body data.
|
||||||
/// data.
|
|
||||||
/// </value>
|
/// </value>
|
||||||
/// <exception cref="ArgumentOutOfRangeException">
|
/// <exception cref="ArgumentOutOfRangeException">
|
||||||
/// The value specified for a set operation is less than zero.
|
/// The value specified for a set operation is less than zero.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="InvalidOperationException">
|
/// <exception cref="InvalidOperationException">
|
||||||
/// The response has been sent already.
|
/// The response has already been sent.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="ObjectDisposedException">
|
/// <exception cref="ObjectDisposedException">
|
||||||
/// This object is closed.
|
/// This object is closed.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public long ContentLength64 {
|
public long ContentLength64 {
|
||||||
get {
|
get {
|
||||||
|
checkDisposedOrHeadersSent ();
|
||||||
return _contentLength;
|
return _contentLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
set {
|
set {
|
||||||
if (_disposed)
|
checkDisposedOrHeadersSent ();
|
||||||
throw new ObjectDisposedException (GetType ().ToString ());
|
|
||||||
|
|
||||||
if (HeadersSent)
|
|
||||||
throw new InvalidOperationException (
|
|
||||||
"Cannot be changed after headers are sent.");
|
|
||||||
|
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
throw new ArgumentOutOfRangeException (
|
throw new ArgumentOutOfRangeException ("Less than zero.", "value");
|
||||||
"Must not be less than zero.", "value");
|
|
||||||
|
|
||||||
_contentLengthSet = true;
|
_contentLengthSet = true;
|
||||||
_contentLength = value;
|
_contentLength = value;
|
||||||
@ -182,8 +168,8 @@ namespace WebSocketSharp.Net
|
|||||||
/// Gets or sets the media type of the entity body included in the response.
|
/// Gets or sets the media type of the entity body included in the response.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// The type of the content. A <see cref="string"/> that represents the value
|
/// The type of the content. A <see cref="string"/> that represents the value of
|
||||||
/// of the Content-Type entity-header field.
|
/// the Content-Type entity-header field.
|
||||||
/// </value>
|
/// </value>
|
||||||
/// <exception cref="ArgumentException">
|
/// <exception cref="ArgumentException">
|
||||||
/// The value specified for a set operation is empty.
|
/// The value specified for a set operation is empty.
|
||||||
@ -192,30 +178,24 @@ namespace WebSocketSharp.Net
|
|||||||
/// The value specified for a set operation is <see langword="null"/>.
|
/// The value specified for a set operation is <see langword="null"/>.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="InvalidOperationException">
|
/// <exception cref="InvalidOperationException">
|
||||||
/// The response has been sent already.
|
/// The response has already been sent.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="ObjectDisposedException">
|
/// <exception cref="ObjectDisposedException">
|
||||||
/// This object is closed.
|
/// This object is closed.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public string ContentType {
|
public string ContentType {
|
||||||
get {
|
get {
|
||||||
|
checkDisposedOrHeadersSent ();
|
||||||
return _contentType;
|
return _contentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
set {
|
set {
|
||||||
if (_disposed)
|
checkDisposedOrHeadersSent ();
|
||||||
throw new ObjectDisposedException (GetType ().ToString ());
|
|
||||||
|
|
||||||
if (HeadersSent)
|
|
||||||
throw new InvalidOperationException (
|
|
||||||
"Cannot be changed after headers are sent.");
|
|
||||||
|
|
||||||
if (value == null)
|
if (value == null)
|
||||||
throw new ArgumentNullException ("value");
|
throw new ArgumentNullException ("value");
|
||||||
|
|
||||||
if (value.Length == 0)
|
if (value.Length == 0)
|
||||||
throw new ArgumentException (
|
throw new ArgumentException ("An empty string.", "value");
|
||||||
"Must not be empty.", "value");
|
|
||||||
|
|
||||||
_contentType = value;
|
_contentType = value;
|
||||||
}
|
}
|
||||||
@ -225,15 +205,22 @@ namespace WebSocketSharp.Net
|
|||||||
/// Gets or sets the cookies returned with the response.
|
/// Gets or sets the cookies returned with the response.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// A <see cref="CookieCollection"/> that contains the cookies returned with
|
/// A <see cref="CookieCollection"/> that contains the cookies returned with the response.
|
||||||
/// the response.
|
|
||||||
/// </value>
|
/// </value>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// The response has already been sent.
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="ObjectDisposedException">
|
||||||
|
/// This object is closed.
|
||||||
|
/// </exception>
|
||||||
public CookieCollection Cookies {
|
public CookieCollection Cookies {
|
||||||
get {
|
get {
|
||||||
|
checkDisposedOrHeadersSent ();
|
||||||
return _cookies ?? (_cookies = new CookieCollection ());
|
return _cookies ?? (_cookies = new CookieCollection ());
|
||||||
}
|
}
|
||||||
|
|
||||||
set {
|
set {
|
||||||
|
checkDisposedOrHeadersSent ();
|
||||||
_cookies = value;
|
_cookies = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -242,9 +229,14 @@ namespace WebSocketSharp.Net
|
|||||||
/// Gets or sets the HTTP headers returned to the client.
|
/// Gets or sets the HTTP headers returned to the client.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// A <see cref="WebHeaderCollection"/> that contains the HTTP headers
|
/// A <see cref="WebHeaderCollection"/> that contains the headers returned to the client.
|
||||||
/// returned to the client.
|
|
||||||
/// </value>
|
/// </value>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// The response has already been sent.
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="ObjectDisposedException">
|
||||||
|
/// This object is closed.
|
||||||
|
/// </exception>
|
||||||
public WebHeaderCollection Headers {
|
public WebHeaderCollection Headers {
|
||||||
get {
|
get {
|
||||||
return _headers;
|
return _headers;
|
||||||
@ -259,41 +251,34 @@ namespace WebSocketSharp.Net
|
|||||||
* headers manually."
|
* headers manually."
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: Support for InvalidOperationException.
|
|
||||||
|
|
||||||
// TODO: Check if this is marked readonly after headers are sent.
|
// TODO: Check if this is marked readonly after headers are sent.
|
||||||
|
|
||||||
|
checkDisposedOrHeadersSent ();
|
||||||
_headers = value;
|
_headers = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether the server requests a persistent
|
/// Gets or sets a value indicating whether the server requests a persistent connection.
|
||||||
/// connection.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// <c>true</c> if the server requests a persistent connection; otherwise,
|
/// <c>true</c> if the server requests a persistent connection; otherwise, <c>false</c>.
|
||||||
/// <c>false</c>. The default is <c>true</c>.
|
/// The default value is <c>true</c>.
|
||||||
/// </value>
|
/// </value>
|
||||||
/// <exception cref="InvalidOperationException">
|
/// <exception cref="InvalidOperationException">
|
||||||
/// The response has been sent already.
|
/// The response has already been sent.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="ObjectDisposedException">
|
/// <exception cref="ObjectDisposedException">
|
||||||
/// This object is closed.
|
/// This object is closed.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public bool KeepAlive {
|
public bool KeepAlive {
|
||||||
get {
|
get {
|
||||||
|
checkDisposedOrHeadersSent ();
|
||||||
return _keepAlive;
|
return _keepAlive;
|
||||||
}
|
}
|
||||||
|
|
||||||
set {
|
set {
|
||||||
if (_disposed)
|
checkDisposedOrHeadersSent ();
|
||||||
throw new ObjectDisposedException (GetType ().ToString ());
|
|
||||||
|
|
||||||
if (HeadersSent)
|
|
||||||
throw new InvalidOperationException (
|
|
||||||
"Cannot be changed after headers are sent.");
|
|
||||||
|
|
||||||
_keepAlive = value;
|
_keepAlive = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,8 +297,7 @@ namespace WebSocketSharp.Net
|
|||||||
if (_disposed)
|
if (_disposed)
|
||||||
throw new ObjectDisposedException (GetType ().ToString ());
|
throw new ObjectDisposedException (GetType ().ToString ());
|
||||||
|
|
||||||
return _outputStream ??
|
return _outputStream ?? (_outputStream = _context.Connection.GetResponseStream ());
|
||||||
(_outputStream = _context.Connection.GetResponseStream ());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,94 +305,77 @@ namespace WebSocketSharp.Net
|
|||||||
/// Gets or sets the HTTP version used in the response.
|
/// Gets or sets the HTTP version used in the response.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// A <see cref="Version"/> that represents the HTTP version used in the
|
/// A <see cref="Version"/> that represents the HTTP version used in the response.
|
||||||
/// response.
|
|
||||||
/// </value>
|
/// </value>
|
||||||
/// <exception cref="ArgumentException">
|
/// <exception cref="ArgumentException">
|
||||||
/// The value specified for a set operation doesn't have its <c>Major</c>
|
/// The value specified for a set operation doesn't have its <c>Major</c> property set to 1 or
|
||||||
/// property set to 1 or doesn't have its <c>Minor</c> property set to
|
/// doesn't have its <c>Minor</c> property set to either 0 or 1.
|
||||||
/// either 0 or 1.
|
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="ArgumentNullException">
|
/// <exception cref="ArgumentNullException">
|
||||||
/// The value specified for a set operation is <see langword="null"/>.
|
/// The value specified for a set operation is <see langword="null"/>.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="InvalidOperationException">
|
/// <exception cref="InvalidOperationException">
|
||||||
/// The response has been sent already.
|
/// The response has already been sent.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="ObjectDisposedException">
|
/// <exception cref="ObjectDisposedException">
|
||||||
/// This object is closed.
|
/// This object is closed.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public Version ProtocolVersion {
|
public Version ProtocolVersion {
|
||||||
get {
|
get {
|
||||||
|
checkDisposedOrHeadersSent ();
|
||||||
return _version;
|
return _version;
|
||||||
}
|
}
|
||||||
|
|
||||||
set {
|
set {
|
||||||
if (_disposed)
|
checkDisposedOrHeadersSent ();
|
||||||
throw new ObjectDisposedException (GetType ().ToString ());
|
|
||||||
|
|
||||||
if (HeadersSent)
|
|
||||||
throw new InvalidOperationException (
|
|
||||||
"Cannot be changed after headers are sent.");
|
|
||||||
|
|
||||||
if (value == null)
|
if (value == null)
|
||||||
throw new ArgumentNullException ("value");
|
throw new ArgumentNullException ("value");
|
||||||
|
|
||||||
if (value.Major != 1 || (value.Minor != 0 && value.Minor != 1))
|
if (value.Major != 1 || (value.Minor != 0 && value.Minor != 1))
|
||||||
throw new ArgumentException ("Must be 1.0 or 1.1.", "value");
|
throw new ArgumentException ("Neither 1.0 nor 1.1.", "value");
|
||||||
|
|
||||||
_version = value;
|
_version = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the URL to which the client is redirected to locate
|
/// Gets or sets the URL to which the client is redirected to locate a requested resource.
|
||||||
/// a requested resource.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// A <see cref="string"/> that represents the value of the Location
|
/// A <see cref="string"/> that represents the value of the Location response-header field.
|
||||||
/// response-header field.
|
|
||||||
/// </value>
|
/// </value>
|
||||||
/// <exception cref="ArgumentException">
|
/// <exception cref="ArgumentException">
|
||||||
/// The value specified for a set operation is empty.
|
/// The value specified for a set operation is empty.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="InvalidOperationException">
|
/// <exception cref="InvalidOperationException">
|
||||||
/// The response has been sent already.
|
/// The response has already been sent.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="ObjectDisposedException">
|
/// <exception cref="ObjectDisposedException">
|
||||||
/// This object is closed.
|
/// This object is closed.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public string RedirectLocation {
|
public string RedirectLocation {
|
||||||
get {
|
get {
|
||||||
|
checkDisposedOrHeadersSent ();
|
||||||
return _location;
|
return _location;
|
||||||
}
|
}
|
||||||
|
|
||||||
set {
|
set {
|
||||||
if (_disposed)
|
checkDisposedOrHeadersSent ();
|
||||||
throw new ObjectDisposedException (GetType ().ToString ());
|
|
||||||
|
|
||||||
if (HeadersSent)
|
|
||||||
throw new InvalidOperationException (
|
|
||||||
"Cannot be changed after headers are sent.");
|
|
||||||
|
|
||||||
if (value.Length == 0)
|
if (value.Length == 0)
|
||||||
throw new ArgumentException (
|
throw new ArgumentException ("An empty string.", "value");
|
||||||
"Must not be empty.", "value");
|
|
||||||
|
|
||||||
_location = value;
|
_location = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether the response uses the chunked
|
/// Gets or sets a value indicating whether the response uses the chunked transfer encoding.
|
||||||
/// transfer encoding.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// <c>true</c> if the response uses the chunked transfer encoding;
|
/// <c>true</c> if the response uses the chunked transfer encoding; otherwise, <c>false</c>.
|
||||||
/// otherwise, <c>false</c>.
|
|
||||||
/// </value>
|
/// </value>
|
||||||
/// <exception cref="InvalidOperationException">
|
/// <exception cref="InvalidOperationException">
|
||||||
/// The response has been sent already.
|
/// The response has already been sent.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="ObjectDisposedException">
|
/// <exception cref="ObjectDisposedException">
|
||||||
/// This object is closed.
|
/// This object is closed.
|
||||||
@ -419,13 +386,7 @@ namespace WebSocketSharp.Net
|
|||||||
}
|
}
|
||||||
|
|
||||||
set {
|
set {
|
||||||
if (_disposed)
|
checkDisposedOrHeadersSent ();
|
||||||
throw new ObjectDisposedException (GetType ().ToString ());
|
|
||||||
|
|
||||||
if (HeadersSent)
|
|
||||||
throw new InvalidOperationException (
|
|
||||||
"Cannot be changed after headers are sent.");
|
|
||||||
|
|
||||||
_chunked = value;
|
_chunked = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -434,32 +395,26 @@ namespace WebSocketSharp.Net
|
|||||||
/// Gets or sets the HTTP status code returned to the client.
|
/// Gets or sets the HTTP status code returned to the client.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// An <see cref="int"/> that represents the HTTP status code for the
|
/// An <see cref="int"/> that represents the HTTP status code for the response to the request.
|
||||||
/// response to the request. The default is <see cref="HttpStatusCode.OK"/>.
|
/// The default value is <see cref="HttpStatusCode.OK"/>.
|
||||||
/// </value>
|
/// </value>
|
||||||
/// <exception cref="InvalidOperationException">
|
/// <exception cref="InvalidOperationException">
|
||||||
/// The response has been sent already.
|
/// The response has already been sent.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="System.Net.ProtocolViolationException">
|
/// <exception cref="System.Net.ProtocolViolationException">
|
||||||
/// The value specified for a set operation is invalid. Valid values are
|
/// The value specified for a set operation is invalid. Valid values are between 100 and 999.
|
||||||
/// between 100 and 999.
|
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="ObjectDisposedException">
|
/// <exception cref="ObjectDisposedException">
|
||||||
/// This object is closed.
|
/// This object is closed.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public int StatusCode {
|
public int StatusCode {
|
||||||
get {
|
get {
|
||||||
|
checkDisposedOrHeadersSent ();
|
||||||
return _statusCode;
|
return _statusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
set {
|
set {
|
||||||
if (_disposed)
|
checkDisposedOrHeadersSent ();
|
||||||
throw new ObjectDisposedException (GetType ().ToString ());
|
|
||||||
|
|
||||||
if (HeadersSent)
|
|
||||||
throw new InvalidOperationException (
|
|
||||||
"Cannot be changed after headers are sent.");
|
|
||||||
|
|
||||||
if (value < 100 || value > 999)
|
if (value < 100 || value > 999)
|
||||||
throw new System.Net.ProtocolViolationException (
|
throw new System.Net.ProtocolViolationException (
|
||||||
"StatusCode must be between 100 and 999.");
|
"StatusCode must be between 100 and 999.");
|
||||||
@ -470,19 +425,25 @@ namespace WebSocketSharp.Net
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the description of the HTTP status code returned to the
|
/// Gets or sets the description of the HTTP status code returned to the client.
|
||||||
/// client.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// A <see cref="String"/> that represents the description of the HTTP status
|
/// A <see cref="string"/> that represents the description of the HTTP status code.
|
||||||
/// code returned to the client.
|
|
||||||
/// </value>
|
/// </value>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// The response has already been sent.
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="ObjectDisposedException">
|
||||||
|
/// This object is closed.
|
||||||
|
/// </exception>
|
||||||
public string StatusDescription {
|
public string StatusDescription {
|
||||||
get {
|
get {
|
||||||
|
checkDisposedOrHeadersSent ();
|
||||||
return _statusDescription;
|
return _statusDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
set {
|
set {
|
||||||
|
checkDisposedOrHeadersSent ();
|
||||||
_statusDescription = value == null || value.Length == 0
|
_statusDescription = value == null || value.Length == 0
|
||||||
? _statusCode.GetStatusDescription ()
|
? _statusCode.GetStatusDescription ()
|
||||||
: value;
|
: value;
|
||||||
@ -498,8 +459,8 @@ namespace WebSocketSharp.Net
|
|||||||
if (Cookies.Count == 0)
|
if (Cookies.Count == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
var found = findCookie (cookie);
|
var found = findCookie (cookie).ToList ();
|
||||||
if (found.Count () == 0)
|
if (found.Count == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
foreach (var c in found)
|
foreach (var c in found)
|
||||||
@ -509,6 +470,15 @@ namespace WebSocketSharp.Net
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkDisposedOrHeadersSent ()
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
throw new ObjectDisposedException (GetType ().ToString ());
|
||||||
|
|
||||||
|
if (_headersSent)
|
||||||
|
throw new InvalidOperationException ("Cannot be changed after headers are sent.");
|
||||||
|
}
|
||||||
|
|
||||||
private void close (bool force)
|
private void close (bool force)
|
||||||
{
|
{
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
@ -521,11 +491,11 @@ namespace WebSocketSharp.Net
|
|||||||
var domain = cookie.Domain;
|
var domain = cookie.Domain;
|
||||||
var path = cookie.Path;
|
var path = cookie.Path;
|
||||||
|
|
||||||
return from Cookie c in Cookies
|
foreach (Cookie c in Cookies)
|
||||||
where c.Name.Equals (name, StringComparison.OrdinalIgnoreCase) &&
|
if (c.Name.Equals (name, StringComparison.OrdinalIgnoreCase) &&
|
||||||
c.Domain.Equals (domain, StringComparison.OrdinalIgnoreCase) &&
|
c.Domain.Equals (domain, StringComparison.OrdinalIgnoreCase) &&
|
||||||
c.Path.Equals (path, StringComparison.Ordinal)
|
c.Path.Equals (path, StringComparison.Ordinal))
|
||||||
select c;
|
yield return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -535,15 +505,12 @@ namespace WebSocketSharp.Net
|
|||||||
internal void SendHeaders (bool closing, MemoryStream stream)
|
internal void SendHeaders (bool closing, MemoryStream stream)
|
||||||
{
|
{
|
||||||
if (_contentType != null) {
|
if (_contentType != null) {
|
||||||
if (_contentEncoding != null &&
|
var contentType = _contentEncoding != null &&
|
||||||
_contentType.IndexOf ("charset=", StringComparison.Ordinal) == -1) {
|
_contentType.IndexOf ("charset=", StringComparison.Ordinal) == -1
|
||||||
var charset = _contentEncoding.WebName;
|
? _contentType + "; charset=" + _contentEncoding.WebName
|
||||||
_headers.SetInternally (
|
: _contentType;
|
||||||
"Content-Type", _contentType + "; charset=" + charset, true);
|
|
||||||
}
|
_headers.SetInternally ("Content-Type", contentType, true);
|
||||||
else {
|
|
||||||
_headers.SetInternally ("Content-Type", _contentType, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_headers ["Server"] == null)
|
if (_headers ["Server"] == null)
|
||||||
@ -551,8 +518,7 @@ namespace WebSocketSharp.Net
|
|||||||
|
|
||||||
var provider = CultureInfo.InvariantCulture;
|
var provider = CultureInfo.InvariantCulture;
|
||||||
if (_headers ["Date"] == null)
|
if (_headers ["Date"] == null)
|
||||||
_headers.SetInternally (
|
_headers.SetInternally ("Date", DateTime.UtcNow.ToString ("r", provider), true);
|
||||||
"Date", DateTime.UtcNow.ToString ("r", provider), true);
|
|
||||||
|
|
||||||
if (!_chunked) {
|
if (!_chunked) {
|
||||||
if (!_contentLengthSet && closing) {
|
if (!_contentLengthSet && closing) {
|
||||||
@ -561,8 +527,7 @@ namespace WebSocketSharp.Net
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_contentLengthSet)
|
if (_contentLengthSet)
|
||||||
_headers.SetInternally (
|
_headers.SetInternally ("Content-Length", _contentLength.ToString (provider), true);
|
||||||
"Content-Length", _contentLength.ToString (provider), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var version = _context.Request.ProtocolVersion;
|
var version = _context.Request.ProtocolVersion;
|
||||||
@ -570,13 +535,13 @@ namespace WebSocketSharp.Net
|
|||||||
_chunked = true;
|
_chunked = true;
|
||||||
|
|
||||||
/* Apache forces closing the connection for these status codes:
|
/* Apache forces closing the connection for these status codes:
|
||||||
* HttpStatusCode.BadRequest 400
|
* - HttpStatusCode.BadRequest 400
|
||||||
* HttpStatusCode.RequestTimeout 408
|
* - HttpStatusCode.RequestTimeout 408
|
||||||
* HttpStatusCode.LengthRequired 411
|
* - HttpStatusCode.LengthRequired 411
|
||||||
* HttpStatusCode.RequestEntityTooLarge 413
|
* - HttpStatusCode.RequestEntityTooLarge 413
|
||||||
* HttpStatusCode.RequestUriTooLong 414
|
* - HttpStatusCode.RequestUriTooLong 414
|
||||||
* HttpStatusCode.InternalServerError 500
|
* - HttpStatusCode.InternalServerError 500
|
||||||
* HttpStatusCode.ServiceUnavailable 503
|
* - HttpStatusCode.ServiceUnavailable 503
|
||||||
*/
|
*/
|
||||||
var connClose = _statusCode == 400 ||
|
var connClose = _statusCode == 400 ||
|
||||||
_statusCode == 408 ||
|
_statusCode == 408 ||
|
||||||
@ -609,8 +574,8 @@ namespace WebSocketSharp.Net
|
|||||||
|
|
||||||
if (!connClose) {
|
if (!connClose) {
|
||||||
_headers.SetInternally (
|
_headers.SetInternally (
|
||||||
"Keep-Alive",
|
"Keep-Alive", String.Format ("timeout=15,max={0}", 100 - reuses), true);
|
||||||
String.Format ("timeout=15,max={0}", 100 - reuses), true);
|
|
||||||
if (_context.Request.ProtocolVersion <= HttpVersion.Version10)
|
if (_context.Request.ProtocolVersion <= HttpVersion.Version10)
|
||||||
_headers.SetInternally ("Connection", "keep-alive", true);
|
_headers.SetInternally ("Connection", "keep-alive", true);
|
||||||
}
|
}
|
||||||
@ -618,25 +583,25 @@ namespace WebSocketSharp.Net
|
|||||||
if (_location != null)
|
if (_location != null)
|
||||||
_headers.SetInternally ("Location", _location, true);
|
_headers.SetInternally ("Location", _location, true);
|
||||||
|
|
||||||
if (_cookies != null) {
|
if (_cookies != null)
|
||||||
foreach (Cookie cookie in _cookies)
|
foreach (Cookie cookie in _cookies)
|
||||||
_headers.SetInternally ("Set-Cookie", cookie.ToResponseString (), true);
|
_headers.SetInternally ("Set-Cookie", cookie.ToResponseString (), true);
|
||||||
}
|
|
||||||
|
|
||||||
var encoding = _contentEncoding ?? Encoding.Default;
|
var encoding = _contentEncoding ?? Encoding.Default;
|
||||||
var writer = new StreamWriter (stream, encoding, 256);
|
var writer = new StreamWriter (stream, encoding, 256);
|
||||||
writer.Write (
|
writer.Write ("HTTP/{0} {1} {2}\r\n", _version, _statusCode, _statusDescription);
|
||||||
"HTTP/{0} {1} {2}\r\n", _version, _statusCode, _statusDescription);
|
|
||||||
var headers = _headers.ToStringMultiValue (true);
|
var headers = _headers.ToStringMultiValue (true);
|
||||||
writer.Write (headers);
|
writer.Write (headers);
|
||||||
writer.Flush ();
|
writer.Flush ();
|
||||||
|
|
||||||
var preamble = encoding.CodePage == 65001 ? 3 : encoding.GetPreamble ().Length;
|
var preamble = encoding.CodePage == 65001 ? 3 : encoding.GetPreamble ().Length;
|
||||||
if (_outputStream == null)
|
if (_outputStream == null)
|
||||||
_outputStream = _context.Connection.GetResponseStream ();
|
_outputStream = _context.Connection.GetResponseStream ();
|
||||||
|
|
||||||
// Assumes that the stream was at position 0.
|
// Assumes that the stream was at position 0.
|
||||||
stream.Position = preamble;
|
stream.Position = preamble;
|
||||||
HeadersSent = true;
|
_headersSent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -655,86 +620,123 @@ namespace WebSocketSharp.Net
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the specified HTTP header <paramref name="name"/> and
|
/// Adds an HTTP header with the specified <paramref name="name"/> and <paramref name="value"/>
|
||||||
/// <paramref name="value"/> to the headers for this response.
|
/// to the headers for the response.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">
|
/// <param name="name">
|
||||||
/// A <see cref="string"/> that contains the name of the HTTP header to add.
|
/// A <see cref="string"/> that represents the name of the header to add.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="value">
|
/// <param name="value">
|
||||||
/// A <see cref="string"/> that contains the value of the HTTP header to add.
|
/// A <see cref="string"/> that represents the value of the header to add.
|
||||||
/// </param>
|
/// </param>
|
||||||
|
/// <exception cref="ArgumentException">
|
||||||
|
/// <para>
|
||||||
|
/// <paramref name="name"/> or <paramref name="value"/> contains invalid characters.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// -or-
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// <paramref name="name"/> is a restricted header name.
|
||||||
|
/// </para>
|
||||||
|
/// </exception>
|
||||||
/// <exception cref="ArgumentNullException">
|
/// <exception cref="ArgumentNullException">
|
||||||
/// <paramref name="name"/> is <see langword="null"/> or empty.
|
/// <paramref name="name"/> is <see langword="null"/> or empty.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="ArgumentOutOfRangeException">
|
/// <exception cref="ArgumentOutOfRangeException">
|
||||||
/// The length of <paramref name="value"/> is greater than 65,535 characters.
|
/// The length of <paramref name="value"/> is greater than 65,535 characters.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// <para>
|
||||||
|
/// The response has already been sent.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// -or-
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// The header cannot be allowed to add to the current headers.
|
||||||
|
/// </para>
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="ObjectDisposedException">
|
||||||
|
/// This object is closed.
|
||||||
|
/// </exception>
|
||||||
public void AddHeader (string name, string value)
|
public void AddHeader (string name, string value)
|
||||||
{
|
{
|
||||||
if (name == null || name.Length == 0)
|
checkDisposedOrHeadersSent ();
|
||||||
throw new ArgumentNullException ("name");
|
|
||||||
|
|
||||||
// TODO: Check for forbidden headers and invalid characters.
|
|
||||||
if (value.Length > 65535)
|
|
||||||
throw new ArgumentOutOfRangeException (
|
|
||||||
"value", "Greater than 65,535 characters.");
|
|
||||||
|
|
||||||
_headers.Set (name, value);
|
_headers.Set (name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the specified <see cref="Cookie"/> to the <see cref="Cookies"/> sent
|
/// Appends the specified <paramref name="cookie"/> to the cookies sent with the response.
|
||||||
/// with the response.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cookie">
|
/// <param name="cookie">
|
||||||
/// A <see cref="Cookie"/> to add to the <see cref="Cookies"/>.
|
/// A <see cref="Cookie"/> to append.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <exception cref="ArgumentNullException">
|
/// <exception cref="ArgumentNullException">
|
||||||
/// <paramref name="cookie"/> is <see langword="null"/>.
|
/// <paramref name="cookie"/> is <see langword="null"/>.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// The response has already been sent.
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="ObjectDisposedException">
|
||||||
|
/// This object is closed.
|
||||||
|
/// </exception>
|
||||||
public void AppendCookie (Cookie cookie)
|
public void AppendCookie (Cookie cookie)
|
||||||
{
|
{
|
||||||
if (cookie == null)
|
checkDisposedOrHeadersSent ();
|
||||||
throw new ArgumentNullException ("cookie");
|
|
||||||
|
|
||||||
Cookies.Add (cookie);
|
Cookies.Add (cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Appends a <paramref name="value"/> to the specified HTTP header sent with
|
/// Appends a <paramref name="value"/> to the specified HTTP header sent with the response.
|
||||||
/// the response.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">
|
/// <param name="name">
|
||||||
/// A <see cref="string"/> that contains the name of the HTTP header to
|
/// A <see cref="string"/> that represents the name of the header to append
|
||||||
/// append <paramref name="value"/> to.
|
/// <paramref name="value"/> to.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="value">
|
/// <param name="value">
|
||||||
/// A <see cref="string"/> that contains the value to append to the HTTP
|
/// A <see cref="string"/> that represents the value to append to the header.
|
||||||
/// header.
|
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <exception cref="ArgumentException">
|
/// <exception cref="ArgumentException">
|
||||||
|
/// <para>
|
||||||
|
/// <paramref name="name"/> or <paramref name="value"/> contains invalid characters.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// -or-
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// <paramref name="name"/> is a restricted header name.
|
||||||
|
/// </para>
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="ArgumentNullException">
|
||||||
/// <paramref name="name"/> is <see langword="null"/> or empty.
|
/// <paramref name="name"/> is <see langword="null"/> or empty.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="ArgumentOutOfRangeException">
|
/// <exception cref="ArgumentOutOfRangeException">
|
||||||
/// The length of <paramref name="value"/> is greater than 65,535 characters.
|
/// The length of <paramref name="value"/> is greater than 65,535 characters.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// <para>
|
||||||
|
/// The response has already been sent.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// -or-
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// The current headers cannot allow the header to append a value.
|
||||||
|
/// </para>
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="ObjectDisposedException">
|
||||||
|
/// This object is closed.
|
||||||
|
/// </exception>
|
||||||
public void AppendHeader (string name, string value)
|
public void AppendHeader (string name, string value)
|
||||||
{
|
{
|
||||||
// TODO: Check for forbidden headers and invalid characters.
|
checkDisposedOrHeadersSent ();
|
||||||
if (name == null || name.Length == 0)
|
|
||||||
throw new ArgumentException ("Must not be null or empty.", "name");
|
|
||||||
|
|
||||||
if (value.Length > 65535)
|
|
||||||
throw new ArgumentOutOfRangeException (
|
|
||||||
"value", "Greater than 65,535 characters.");
|
|
||||||
|
|
||||||
_headers.Add (name, value);
|
_headers.Add (name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends the response to the client and releases the resources associated
|
/// Sends the response to the client, and releases the resources used by
|
||||||
/// with the <see cref="HttpListenerResponse"/> instance.
|
/// this <see cref="HttpListenerResponse"/> instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Close ()
|
public void Close ()
|
||||||
{
|
{
|
||||||
@ -745,47 +747,68 @@ namespace WebSocketSharp.Net
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends the response with the specified array of <see cref="byte"/> to the
|
/// Sends the response with the specified array of <see cref="byte"/> to the client, and
|
||||||
/// client and releases the resources associated with the
|
/// releases the resources used by this <see cref="HttpListenerResponse"/> instance.
|
||||||
/// <see cref="HttpListenerResponse"/> instance.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="responseEntity">
|
/// <param name="responseEntity">
|
||||||
/// An array of <see cref="byte"/> that contains the response entity body
|
/// An array of <see cref="byte"/> that contains the response entity body data.
|
||||||
/// data.
|
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="willBlock">
|
/// <param name="willBlock">
|
||||||
/// <c>true</c> if this method blocks execution while flushing the stream to
|
/// <c>true</c> if this method blocks execution while flushing the stream to the client;
|
||||||
/// the client; otherwise, <c>false</c>.
|
/// otherwise, <c>false</c>.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <exception cref="ArgumentNullException">
|
/// <exception cref="ArgumentNullException">
|
||||||
/// <paramref name="responseEntity"/> is <see langword="null"/>.
|
/// <paramref name="responseEntity"/> is <see langword="null"/>.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// The response has already been sent.
|
||||||
|
/// </exception>
|
||||||
/// <exception cref="ObjectDisposedException">
|
/// <exception cref="ObjectDisposedException">
|
||||||
/// This object is closed.
|
/// This object is closed.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public void Close (byte [] responseEntity, bool willBlock)
|
public void Close (byte [] responseEntity, bool willBlock)
|
||||||
{
|
{
|
||||||
if (_disposed)
|
|
||||||
throw new ObjectDisposedException (GetType ().ToString ());
|
|
||||||
|
|
||||||
if (responseEntity == null)
|
if (responseEntity == null)
|
||||||
throw new ArgumentNullException ("responseEntity");
|
throw new ArgumentNullException ("responseEntity");
|
||||||
|
|
||||||
// TODO: If willBlock -> BeginWrite + Close?
|
var len = responseEntity.Length;
|
||||||
ContentLength64 = responseEntity.Length;
|
ContentLength64 = len;
|
||||||
OutputStream.Write (responseEntity, 0, (int) _contentLength);
|
|
||||||
|
var output = OutputStream;
|
||||||
|
if (willBlock) {
|
||||||
|
output.Write (responseEntity, 0, len);
|
||||||
close (false);
|
close (false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
output.BeginWrite (
|
||||||
|
responseEntity,
|
||||||
|
0,
|
||||||
|
len,
|
||||||
|
ar => {
|
||||||
|
output.EndWrite (ar);
|
||||||
|
close (false);
|
||||||
|
},
|
||||||
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Copies properties from the specified <see cref="HttpListenerResponse"/>
|
/// Copies properties from the specified <see cref="HttpListenerResponse"/> to this response.
|
||||||
/// to this response.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="templateResponse">
|
/// <param name="templateResponse">
|
||||||
/// A <see cref="HttpListenerResponse"/> to copy.
|
/// A <see cref="HttpListenerResponse"/> to copy.
|
||||||
/// </param>
|
/// </param>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// The response has already been sent.
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="ObjectDisposedException">
|
||||||
|
/// This object is closed.
|
||||||
|
/// </exception>
|
||||||
public void CopyFrom (HttpListenerResponse templateResponse)
|
public void CopyFrom (HttpListenerResponse templateResponse)
|
||||||
{
|
{
|
||||||
|
checkDisposedOrHeadersSent ();
|
||||||
|
|
||||||
_headers.Clear ();
|
_headers.Clear ();
|
||||||
_headers.Add (templateResponse._headers);
|
_headers.Add (templateResponse._headers);
|
||||||
_contentLength = templateResponse._contentLength;
|
_contentLength = templateResponse._contentLength;
|
||||||
@ -800,9 +823,14 @@ namespace WebSocketSharp.Net
|
|||||||
/// <paramref name="url"/>.
|
/// <paramref name="url"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="url">
|
/// <param name="url">
|
||||||
/// A <see cref="string"/> that represents the URL to redirect the client's
|
/// A <see cref="string"/> that represents the URL to redirect the client's request to.
|
||||||
/// request to.
|
|
||||||
/// </param>
|
/// </param>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// The response has already been sent.
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="ObjectDisposedException">
|
||||||
|
/// This object is closed.
|
||||||
|
/// </exception>
|
||||||
public void Redirect (string url)
|
public void Redirect (string url)
|
||||||
{
|
{
|
||||||
StatusCode = (int) HttpStatusCode.Redirect;
|
StatusCode = (int) HttpStatusCode.Redirect;
|
||||||
@ -810,21 +838,26 @@ namespace WebSocketSharp.Net
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds or updates a <see cref="Cookie"/> in the <see cref="Cookies"/> sent
|
/// Adds or updates a <paramref name="cookie"/> in the cookies sent with the response.
|
||||||
/// with the response.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cookie">
|
/// <param name="cookie">
|
||||||
/// A <see cref="Cookie"/> to set.
|
/// A <see cref="Cookie"/> to set.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <exception cref="ArgumentException">
|
/// <exception cref="ArgumentException">
|
||||||
/// <paramref name="cookie"/> already exists in the <see cref="Cookies"/> and
|
/// <paramref name="cookie"/> already exists in the cookies, and couldn't be replaced.
|
||||||
/// could not be replaced.
|
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <exception cref="ArgumentNullException">
|
/// <exception cref="ArgumentNullException">
|
||||||
/// <paramref name="cookie"/> is <see langword="null"/>.
|
/// <paramref name="cookie"/> is <see langword="null"/>.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
|
/// <exception cref="InvalidOperationException">
|
||||||
|
/// The response has already been sent.
|
||||||
|
/// </exception>
|
||||||
|
/// <exception cref="ObjectDisposedException">
|
||||||
|
/// This object is closed.
|
||||||
|
/// </exception>
|
||||||
public void SetCookie (Cookie cookie)
|
public void SetCookie (Cookie cookie)
|
||||||
{
|
{
|
||||||
|
checkDisposedOrHeadersSent ();
|
||||||
if (cookie == null)
|
if (cookie == null)
|
||||||
throw new ArgumentNullException ("cookie");
|
throw new ArgumentNullException ("cookie");
|
||||||
|
|
||||||
@ -843,8 +876,11 @@ namespace WebSocketSharp.Net
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void IDisposable.Dispose ()
|
void IDisposable.Dispose ()
|
||||||
{
|
{
|
||||||
|
if (_disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
// TODO: Abort or Close?
|
// TODO: Abort or Close?
|
||||||
close (true);
|
close (true); // Same as Abort.
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
Loading…
Reference in New Issue
Block a user