Modified HttpListener.cs
This commit is contained in:
parent
f521779ed7
commit
a376daedf0
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// HttpConnection.cs
|
// HttpConnection.cs
|
||||||
// Copied from System.Net.HttpConnection
|
// Copied from System.Net.HttpConnection.cs
|
||||||
//
|
//
|
||||||
// Author:
|
// Author:
|
||||||
// Gonzalo Paniagua Javier (gonzalo@novell.com)
|
// Gonzalo Paniagua Javier (gonzalo@novell.com)
|
||||||
@ -222,10 +222,12 @@ namespace WebSocketSharp.Net {
|
|||||||
} catch {
|
} catch {
|
||||||
if (ms != null && ms.Length > 0)
|
if (ms != null && ms.Length > 0)
|
||||||
SendError ();
|
SendError ();
|
||||||
|
|
||||||
if (sock != null) {
|
if (sock != null) {
|
||||||
CloseSocket ();
|
CloseSocket ();
|
||||||
Unbind ();
|
Unbind ();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,6 +254,7 @@ namespace WebSocketSharp.Net {
|
|||||||
Close (true);
|
Close (true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpListener listener = context.Listener;
|
HttpListener listener = context.Listener;
|
||||||
if (last_listener != listener) {
|
if (last_listener != listener) {
|
||||||
RemoveConnection ();
|
RemoveConnection ();
|
||||||
@ -263,6 +266,7 @@ namespace WebSocketSharp.Net {
|
|||||||
listener.RegisterContext (context);
|
listener.RegisterContext (context);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.BeginRead (buffer, 0, BufferSize, onread_cb, this);
|
stream.BeginRead (buffer, 0, BufferSize, onread_cb, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,6 +344,7 @@ namespace WebSocketSharp.Net {
|
|||||||
{
|
{
|
||||||
if (current_line == null)
|
if (current_line == null)
|
||||||
current_line = new StringBuilder ();
|
current_line = new StringBuilder ();
|
||||||
|
|
||||||
int last = offset + len;
|
int last = offset + len;
|
||||||
used = 0;
|
used = 0;
|
||||||
for (int i = offset; i < last && line_state != LineState.LF; i++) {
|
for (int i = offset; i < last && line_state != LineState.LF; i++) {
|
||||||
@ -396,15 +401,6 @@ namespace WebSocketSharp.Net {
|
|||||||
force_close |= !context.Request.KeepAlive;
|
force_close |= !context.Request.KeepAlive;
|
||||||
if (!force_close)
|
if (!force_close)
|
||||||
force_close = (context.Response.Headers ["connection"] == "close");
|
force_close = (context.Response.Headers ["connection"] == "close");
|
||||||
/*
|
|
||||||
if (!force_close) {
|
|
||||||
// bool conn_close = (status_code == 400 || status_code == 408 || status_code == 411 ||
|
|
||||||
// status_code == 413 || status_code == 414 || status_code == 500 ||
|
|
||||||
// status_code == 503);
|
|
||||||
|
|
||||||
force_close |= (context.Request.ProtocolVersion <= HttpVersion.Version10);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!force_close && context.Request.FlushInput ()) {
|
if (!force_close && context.Request.FlushInput ()) {
|
||||||
if (chunked && context.Response.ForceCloseChunked == false) {
|
if (chunked && context.Response.ForceCloseChunked == false) {
|
||||||
@ -433,6 +429,7 @@ namespace WebSocketSharp.Net {
|
|||||||
if (s != null)
|
if (s != null)
|
||||||
s.Close ();
|
s.Close ();
|
||||||
}
|
}
|
||||||
|
|
||||||
Unbind ();
|
Unbind ();
|
||||||
RemoveConnection ();
|
RemoveConnection ();
|
||||||
return;
|
return;
|
||||||
@ -447,9 +444,11 @@ namespace WebSocketSharp.Net {
|
|||||||
{
|
{
|
||||||
if (buffer == null)
|
if (buffer == null)
|
||||||
buffer = new byte [BufferSize];
|
buffer = new byte [BufferSize];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (reuses == 1)
|
if (reuses == 1)
|
||||||
s_timeout = 15000;
|
s_timeout = 15000;
|
||||||
|
|
||||||
timer.Change (s_timeout, Timeout.Infinite);
|
timer.Change (s_timeout, Timeout.Infinite);
|
||||||
stream.BeginRead (buffer, 0, BufferSize, onread_cb, this);
|
stream.BeginRead (buffer, 0, BufferSize, onread_cb, this);
|
||||||
} catch {
|
} catch {
|
||||||
@ -478,6 +477,7 @@ namespace WebSocketSharp.Net {
|
|||||||
i_stream = new RequestStream (stream, buffer, position, length - position, contentlength);
|
i_stream = new RequestStream (stream, buffer, position, length - position, contentlength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return i_stream;
|
return i_stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,6 +489,7 @@ namespace WebSocketSharp.Net {
|
|||||||
bool ign = (listener == null) ? true : listener.IgnoreWriteExceptions;
|
bool ign = (listener == null) ? true : listener.IgnoreWriteExceptions;
|
||||||
o_stream = new ResponseStream (stream, context.Response, ign);
|
o_stream = new ResponseStream (stream, context.Response, ign);
|
||||||
}
|
}
|
||||||
|
|
||||||
return o_stream;
|
return o_stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,48 +177,67 @@ namespace WebSocketSharp.Net {
|
|||||||
|
|
||||||
#region Private Methods
|
#region Private Methods
|
||||||
|
|
||||||
void Cleanup (bool close_existing)
|
void Cleanup (bool force)
|
||||||
{
|
{
|
||||||
lock (((ICollection)registry).SyncRoot) {
|
lock (((ICollection)registry).SyncRoot) {
|
||||||
if (close_existing) {
|
if (!force)
|
||||||
// Need to copy this since closing will call UnregisterContext
|
SendServiceUnavailable ();
|
||||||
ICollection keys = registry.Keys;
|
|
||||||
var all = new HttpListenerContext [keys.Count];
|
CleanupContextRegistry ();
|
||||||
keys.CopyTo (all, 0);
|
CleanupConnections ();
|
||||||
registry.Clear ();
|
CleanupWaitQueue ();
|
||||||
for (int i = all.Length - 1; i >= 0; i--)
|
}
|
||||||
all [i].Connection.Close (true);
|
}
|
||||||
|
|
||||||
|
void CleanupConnections ()
|
||||||
|
{
|
||||||
|
lock (((ICollection)connections).SyncRoot) {
|
||||||
|
if (connections.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Need to copy this since closing will call RemoveConnection
|
||||||
|
ICollection keys = connections.Keys;
|
||||||
|
var conns = new HttpConnection [keys.Count];
|
||||||
|
keys.CopyTo (conns, 0);
|
||||||
|
connections.Clear ();
|
||||||
|
for (int i = conns.Length - 1; i >= 0; i--)
|
||||||
|
conns [i].Close (true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CleanupContextRegistry ()
|
||||||
|
{
|
||||||
|
lock (((ICollection)registry).SyncRoot) {
|
||||||
|
if (registry.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Need to copy this since closing will call UnregisterContext
|
||||||
|
ICollection keys = registry.Keys;
|
||||||
|
var all = new HttpListenerContext [keys.Count];
|
||||||
|
keys.CopyTo (all, 0);
|
||||||
|
registry.Clear ();
|
||||||
|
for (int i = all.Length - 1; i >= 0; i--)
|
||||||
|
all [i].Connection.Close (true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CleanupWaitQueue ()
|
||||||
|
{
|
||||||
|
lock (((ICollection)wait_queue).SyncRoot) {
|
||||||
|
if (wait_queue.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var exc = new ObjectDisposedException (GetType ().ToString ());
|
||||||
|
foreach (var ares in wait_queue) {
|
||||||
|
ares.Complete (exc);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (((ICollection)connections).SyncRoot) {
|
wait_queue.Clear ();
|
||||||
ICollection keys = connections.Keys;
|
|
||||||
var conns = new HttpConnection [keys.Count];
|
|
||||||
keys.CopyTo (conns, 0);
|
|
||||||
connections.Clear ();
|
|
||||||
for (int i = conns.Length - 1; i >= 0; i--)
|
|
||||||
conns [i].Close (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (((ICollection)ctx_queue).SyncRoot) {
|
|
||||||
var ctxs = ctx_queue.ToArray ();
|
|
||||||
ctx_queue.Clear ();
|
|
||||||
for (int i = ctxs.Length - 1; i >= 0; i--)
|
|
||||||
ctxs [i].Connection.Close (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (((ICollection)wait_queue).SyncRoot) {
|
|
||||||
Exception exc = new ObjectDisposedException ("listener");
|
|
||||||
foreach (ListenerAsyncResult ares in wait_queue) {
|
|
||||||
ares.Complete (exc);
|
|
||||||
}
|
|
||||||
wait_queue.Clear ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Close (bool force)
|
void Close (bool force)
|
||||||
{
|
{
|
||||||
CheckDisposed ();
|
|
||||||
EndPointManager.RemoveListener (this);
|
EndPointManager.RemoveListener (this);
|
||||||
Cleanup (force);
|
Cleanup (force);
|
||||||
}
|
}
|
||||||
@ -234,6 +253,22 @@ namespace WebSocketSharp.Net {
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SendServiceUnavailable ()
|
||||||
|
{
|
||||||
|
lock (((ICollection)ctx_queue).SyncRoot) {
|
||||||
|
if (ctx_queue.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var ctxs = ctx_queue.ToArray ();
|
||||||
|
ctx_queue.Clear ();
|
||||||
|
foreach (var ctx in ctxs) {
|
||||||
|
var res = ctx.Response;
|
||||||
|
res.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
|
||||||
|
res.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Internal Methods
|
#region Internal Methods
|
||||||
@ -322,11 +357,6 @@ namespace WebSocketSharp.Net {
|
|||||||
if (disposed)
|
if (disposed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!listening) {
|
|
||||||
disposed = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Close (true);
|
Close (true);
|
||||||
disposed = true;
|
disposed = true;
|
||||||
}
|
}
|
||||||
@ -383,11 +413,6 @@ namespace WebSocketSharp.Net {
|
|||||||
if (disposed)
|
if (disposed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!listening) {
|
|
||||||
disposed = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Close (false);
|
Close (false);
|
||||||
disposed = true;
|
disposed = true;
|
||||||
}
|
}
|
||||||
@ -487,8 +512,9 @@ namespace WebSocketSharp.Net {
|
|||||||
if (!listening)
|
if (!listening)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EndPointManager.RemoveListener (this);
|
|
||||||
listening = false;
|
listening = false;
|
||||||
|
EndPointManager.RemoveListener (this);
|
||||||
|
SendServiceUnavailable ();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -459,6 +459,7 @@ namespace WebSocketSharp.Net {
|
|||||||
IAsyncResult ares = InputStream.BeginRead (bytes, 0, length, null, null);
|
IAsyncResult ares = InputStream.BeginRead (bytes, 0, length, null, null);
|
||||||
if (!ares.IsCompleted && !ares.AsyncWaitHandle.WaitOne (100))
|
if (!ares.IsCompleted && !ares.AsyncWaitHandle.WaitOne (100))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (InputStream.EndRead (ares) <= 0)
|
if (InputStream.EndRead (ares) <= 0)
|
||||||
return true;
|
return true;
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -166,7 +166,7 @@ namespace WebSocketSharp.Net {
|
|||||||
|
|
||||||
if (HeadersSent)
|
if (HeadersSent)
|
||||||
throw new InvalidOperationException ("Cannot be changed after headers are sent.");
|
throw new InvalidOperationException ("Cannot be changed after headers are sent.");
|
||||||
|
|
||||||
keep_alive = value;
|
keep_alive = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,10 +175,11 @@ namespace WebSocketSharp.Net {
|
|||||||
get {
|
get {
|
||||||
if (output_stream == null)
|
if (output_stream == null)
|
||||||
output_stream = context.Connection.GetResponseStream ();
|
output_stream = context.Connection.GetResponseStream ();
|
||||||
|
|
||||||
return output_stream;
|
return output_stream;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Version ProtocolVersion {
|
public Version ProtocolVersion {
|
||||||
get { return version; }
|
get { return version; }
|
||||||
set {
|
set {
|
||||||
@ -209,7 +210,7 @@ namespace WebSocketSharp.Net {
|
|||||||
|
|
||||||
if (HeadersSent)
|
if (HeadersSent)
|
||||||
throw new InvalidOperationException ("Cannot be changed after headers are sent.");
|
throw new InvalidOperationException ("Cannot be changed after headers are sent.");
|
||||||
|
|
||||||
location = value;
|
location = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -222,7 +223,7 @@ namespace WebSocketSharp.Net {
|
|||||||
|
|
||||||
if (HeadersSent)
|
if (HeadersSent)
|
||||||
throw new InvalidOperationException ("Cannot be changed after headers are sent.");
|
throw new InvalidOperationException ("Cannot be changed after headers are sent.");
|
||||||
|
|
||||||
chunked = value;
|
chunked = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -261,11 +262,6 @@ namespace WebSocketSharp.Net {
|
|||||||
context.Connection.Close (force);
|
context.Connection.Close (force);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IDisposable.Dispose ()
|
|
||||||
{
|
|
||||||
Close (true); // TODO: Abort or Close?
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FindCookie (Cookie cookie)
|
bool FindCookie (Cookie cookie)
|
||||||
{
|
{
|
||||||
string name = cookie.Name;
|
string name = cookie.Name;
|
||||||
@ -396,6 +392,15 @@ namespace WebSocketSharp.Net {
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Explicit Interface Implementation
|
||||||
|
|
||||||
|
void IDisposable.Dispose ()
|
||||||
|
{
|
||||||
|
Close (true); // TODO: Abort or Close?
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Public Methods
|
#region Public Methods
|
||||||
|
|
||||||
public void Abort ()
|
public void Abort ()
|
||||||
@ -413,7 +418,7 @@ namespace WebSocketSharp.Net {
|
|||||||
|
|
||||||
if (name == "")
|
if (name == "")
|
||||||
throw new ArgumentException ("'name' cannot be empty", "name");
|
throw new ArgumentException ("'name' cannot be empty", "name");
|
||||||
|
|
||||||
// TODO: check for forbidden headers and invalid characters
|
// TODO: check for forbidden headers and invalid characters
|
||||||
if (value.Length > 65535)
|
if (value.Length > 65535)
|
||||||
throw new ArgumentOutOfRangeException ("value");
|
throw new ArgumentOutOfRangeException ("value");
|
||||||
@ -425,7 +430,7 @@ namespace WebSocketSharp.Net {
|
|||||||
{
|
{
|
||||||
if (cookie == null)
|
if (cookie == null)
|
||||||
throw new ArgumentNullException ("cookie");
|
throw new ArgumentNullException ("cookie");
|
||||||
|
|
||||||
Cookies.Add (cookie);
|
Cookies.Add (cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,7 +441,7 @@ namespace WebSocketSharp.Net {
|
|||||||
|
|
||||||
if (name == "")
|
if (name == "")
|
||||||
throw new ArgumentException ("'name' cannot be empty", "name");
|
throw new ArgumentException ("'name' cannot be empty", "name");
|
||||||
|
|
||||||
if (value.Length > 65535)
|
if (value.Length > 65535)
|
||||||
throw new ArgumentOutOfRangeException ("value");
|
throw new ArgumentOutOfRangeException ("value");
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// ResponseStream.cs
|
// ResponseStream.cs
|
||||||
// Copied from System.Net.ResponseStream
|
// Copied from System.Net.ResponseStream.cs
|
||||||
//
|
//
|
||||||
// Author:
|
// Author:
|
||||||
// Gonzalo Paniagua Javier (gonzalo@novell.com)
|
// Gonzalo Paniagua Javier (gonzalo@novell.com)
|
||||||
@ -40,22 +40,37 @@ namespace WebSocketSharp.Net {
|
|||||||
// Update: we send a single packet for the first non-chunked Write
|
// Update: we send a single packet for the first non-chunked Write
|
||||||
// What happens when we set content-length to X and write X-1 bytes then close?
|
// What happens when we set content-length to X and write X-1 bytes then close?
|
||||||
// what if we don't set content-length at all?
|
// what if we don't set content-length at all?
|
||||||
class ResponseStream : Stream
|
class ResponseStream : Stream {
|
||||||
{
|
|
||||||
|
|
||||||
|
#region Private Static Field
|
||||||
|
|
||||||
|
static byte [] crlf = new byte [] { 13, 10 };
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Fields
|
||||||
|
|
||||||
|
bool disposed;
|
||||||
|
bool ignore_errors;
|
||||||
HttpListenerResponse response;
|
HttpListenerResponse response;
|
||||||
bool ignore_errors;
|
Stream stream;
|
||||||
bool disposed;
|
bool trailer_sent;
|
||||||
bool trailer_sent;
|
|
||||||
System.IO.Stream stream;
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
internal ResponseStream (System.IO.Stream stream, HttpListenerResponse response, bool ignore_errors)
|
internal ResponseStream (System.IO.Stream stream, HttpListenerResponse response, bool ignore_errors)
|
||||||
{
|
{
|
||||||
|
this.stream = stream;
|
||||||
this.response = response;
|
this.response = response;
|
||||||
this.ignore_errors = ignore_errors;
|
this.ignore_errors = ignore_errors;
|
||||||
this.stream = stream;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
public override bool CanRead {
|
public override bool CanRead {
|
||||||
get { return false; }
|
get { return false; }
|
||||||
}
|
}
|
||||||
@ -77,6 +92,88 @@ namespace WebSocketSharp.Net {
|
|||||||
set { throw new NotSupportedException (); }
|
set { throw new NotSupportedException (); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Methods
|
||||||
|
|
||||||
|
static byte [] GetChunkSizeBytes (int size, bool final)
|
||||||
|
{
|
||||||
|
string str = String.Format ("{0:x}\r\n{1}", size, final ? "\r\n" : "");
|
||||||
|
return Encoding.ASCII.GetBytes (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryStream GetHeaders (bool closing)
|
||||||
|
{
|
||||||
|
if (response.HeadersSent)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
MemoryStream ms = new MemoryStream ();
|
||||||
|
response.SendHeaders (closing, ms);
|
||||||
|
|
||||||
|
return ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Internal Method
|
||||||
|
|
||||||
|
internal void InternalWrite (byte [] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
if (ignore_errors) {
|
||||||
|
try {
|
||||||
|
stream.Write (buffer, offset, count);
|
||||||
|
} catch {
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stream.Write (buffer, offset, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
|
|
||||||
|
public override IAsyncResult BeginRead (
|
||||||
|
byte [] buffer,
|
||||||
|
int offset,
|
||||||
|
int count,
|
||||||
|
AsyncCallback cback,
|
||||||
|
object state)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IAsyncResult BeginWrite (
|
||||||
|
byte [] buffer,
|
||||||
|
int offset,
|
||||||
|
int count,
|
||||||
|
AsyncCallback cback,
|
||||||
|
object state)
|
||||||
|
{
|
||||||
|
if (disposed)
|
||||||
|
throw new ObjectDisposedException (GetType ().ToString ());
|
||||||
|
|
||||||
|
byte [] bytes = null;
|
||||||
|
MemoryStream ms = GetHeaders (false);
|
||||||
|
bool chunked = response.SendChunked;
|
||||||
|
if (ms != null) {
|
||||||
|
long start = ms.Position;
|
||||||
|
ms.Position = ms.Length;
|
||||||
|
if (chunked) {
|
||||||
|
bytes = GetChunkSizeBytes (count, false);
|
||||||
|
ms.Write (bytes, 0, bytes.Length);
|
||||||
|
}
|
||||||
|
ms.Write (buffer, offset, count);
|
||||||
|
buffer = ms.GetBuffer ();
|
||||||
|
offset = (int) start;
|
||||||
|
count = (int) (ms.Position - start);
|
||||||
|
} else if (chunked) {
|
||||||
|
bytes = GetChunkSizeBytes (count, false);
|
||||||
|
InternalWrite (bytes, 0, bytes.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stream.BeginWrite (buffer, offset, count, cback, state);
|
||||||
|
}
|
||||||
|
|
||||||
public override void Close ()
|
public override void Close ()
|
||||||
{
|
{
|
||||||
@ -99,39 +196,52 @@ namespace WebSocketSharp.Net {
|
|||||||
InternalWrite (bytes, 0, bytes.Length);
|
InternalWrite (bytes, 0, bytes.Length);
|
||||||
trailer_sent = true;
|
trailer_sent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
response.Close ();
|
response.Close ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryStream GetHeaders (bool closing)
|
public override int EndRead (IAsyncResult ares)
|
||||||
{
|
{
|
||||||
if (response.HeadersSent)
|
throw new NotSupportedException ();
|
||||||
return null;
|
}
|
||||||
MemoryStream ms = new MemoryStream ();
|
|
||||||
response.SendHeaders (closing, ms);
|
public override void EndWrite (IAsyncResult ares)
|
||||||
return ms;
|
{
|
||||||
|
if (disposed)
|
||||||
|
throw new ObjectDisposedException (GetType ().ToString ());
|
||||||
|
|
||||||
|
if (ignore_errors) {
|
||||||
|
try {
|
||||||
|
stream.EndWrite (ares);
|
||||||
|
if (response.SendChunked)
|
||||||
|
stream.Write (crlf, 0, 2);
|
||||||
|
} catch {
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stream.EndWrite (ares);
|
||||||
|
if (response.SendChunked)
|
||||||
|
stream.Write (crlf, 0, 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Flush ()
|
public override void Flush ()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte [] crlf = new byte [] { 13, 10 };
|
public override int Read ([In,Out] byte[] buffer, int offset, int count)
|
||||||
static byte [] GetChunkSizeBytes (int size, bool final)
|
|
||||||
{
|
{
|
||||||
string str = String.Format ("{0:x}\r\n{1}", size, final ? "\r\n" : "");
|
throw new NotSupportedException ();
|
||||||
return Encoding.ASCII.GetBytes (str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void InternalWrite (byte [] buffer, int offset, int count)
|
public override long Seek (long offset, SeekOrigin origin)
|
||||||
{
|
{
|
||||||
if (ignore_errors) {
|
throw new NotSupportedException ();
|
||||||
try {
|
}
|
||||||
stream.Write (buffer, offset, count);
|
|
||||||
} catch { }
|
public override void SetLength (long value)
|
||||||
} else {
|
{
|
||||||
stream.Write (buffer, offset, count);
|
throw new NotSupportedException ();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Write (byte [] buffer, int offset, int count)
|
public override void Write (byte [] buffer, int offset, int count)
|
||||||
@ -164,80 +274,11 @@ namespace WebSocketSharp.Net {
|
|||||||
|
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
InternalWrite (buffer, offset, count);
|
InternalWrite (buffer, offset, count);
|
||||||
|
|
||||||
if (chunked)
|
if (chunked)
|
||||||
InternalWrite (crlf, 0, 2);
|
InternalWrite (crlf, 0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IAsyncResult BeginWrite (byte [] buffer, int offset, int count,
|
#endregion
|
||||||
AsyncCallback cback, object state)
|
|
||||||
{
|
|
||||||
if (disposed)
|
|
||||||
throw new ObjectDisposedException (GetType ().ToString ());
|
|
||||||
|
|
||||||
byte [] bytes = null;
|
|
||||||
MemoryStream ms = GetHeaders (false);
|
|
||||||
bool chunked = response.SendChunked;
|
|
||||||
if (ms != null) {
|
|
||||||
long start = ms.Position;
|
|
||||||
ms.Position = ms.Length;
|
|
||||||
if (chunked) {
|
|
||||||
bytes = GetChunkSizeBytes (count, false);
|
|
||||||
ms.Write (bytes, 0, bytes.Length);
|
|
||||||
}
|
|
||||||
ms.Write (buffer, offset, count);
|
|
||||||
buffer = ms.GetBuffer ();
|
|
||||||
offset = (int) start;
|
|
||||||
count = (int) (ms.Position - start);
|
|
||||||
} else if (chunked) {
|
|
||||||
bytes = GetChunkSizeBytes (count, false);
|
|
||||||
InternalWrite (bytes, 0, bytes.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
return stream.BeginWrite (buffer, offset, count, cback, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void EndWrite (IAsyncResult ares)
|
|
||||||
{
|
|
||||||
if (disposed)
|
|
||||||
throw new ObjectDisposedException (GetType ().ToString ());
|
|
||||||
|
|
||||||
if (ignore_errors) {
|
|
||||||
try {
|
|
||||||
stream.EndWrite (ares);
|
|
||||||
if (response.SendChunked)
|
|
||||||
stream.Write (crlf, 0, 2);
|
|
||||||
} catch { }
|
|
||||||
} else {
|
|
||||||
stream.EndWrite (ares);
|
|
||||||
if (response.SendChunked)
|
|
||||||
stream.Write (crlf, 0, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int Read ([In,Out] byte[] buffer, int offset, int count)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException ();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IAsyncResult BeginRead (byte [] buffer, int offset, int count,
|
|
||||||
AsyncCallback cback, object state)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException ();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int EndRead (IAsyncResult ares)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException ();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override long Seek (long offset, SeekOrigin origin)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException ();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SetLength (long value)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user