Browse Source

Modified HttpListener.cs

pull/14/head
sta 13 years ago
parent
commit
a376daedf0
  1. BIN
      Example/bin/Debug_Ubuntu/example.exe
  2. BIN
      Example/bin/Debug_Ubuntu/example.exe.mdb
  3. BIN
      Example/bin/Debug_Ubuntu/websocket-sharp.dll
  4. BIN
      Example/bin/Debug_Ubuntu/websocket-sharp.dll.mdb
  5. BIN
      Example1/bin/Debug_Ubuntu/example1.exe
  6. BIN
      Example1/bin/Debug_Ubuntu/example1.exe.mdb
  7. BIN
      Example1/bin/Debug_Ubuntu/websocket-sharp.dll
  8. BIN
      Example1/bin/Debug_Ubuntu/websocket-sharp.dll.mdb
  9. BIN
      Example2/bin/Debug_Ubuntu/example2.exe
  10. BIN
      Example2/bin/Debug_Ubuntu/example2.exe.mdb
  11. BIN
      Example2/bin/Debug_Ubuntu/websocket-sharp.dll
  12. BIN
      Example2/bin/Debug_Ubuntu/websocket-sharp.dll.mdb
  13. BIN
      Example3/bin/Debug_Ubuntu/Example3.exe
  14. BIN
      Example3/bin/Debug_Ubuntu/Example3.exe.mdb
  15. BIN
      Example3/bin/Debug_Ubuntu/websocket-sharp.dll
  16. BIN
      Example3/bin/Debug_Ubuntu/websocket-sharp.dll.mdb
  17. 21
      websocket-sharp/Net/HttpConnection.cs
  18. 110
      websocket-sharp/Net/HttpListener.cs
  19. 1
      websocket-sharp/Net/HttpListenerRequest.cs
  20. 29
      websocket-sharp/Net/HttpListenerResponse.cs
  21. 203
      websocket-sharp/Net/ResponseStream.cs
  22. BIN
      websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll
  23. BIN
      websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll.mdb
  24. BIN
      websocket-sharp/websocket-sharp.pidb

BIN
Example/bin/Debug_Ubuntu/example.exe

BIN
Example/bin/Debug_Ubuntu/example.exe.mdb

BIN
Example/bin/Debug_Ubuntu/websocket-sharp.dll

BIN
Example/bin/Debug_Ubuntu/websocket-sharp.dll.mdb

BIN
Example1/bin/Debug_Ubuntu/example1.exe

BIN
Example1/bin/Debug_Ubuntu/example1.exe.mdb

BIN
Example1/bin/Debug_Ubuntu/websocket-sharp.dll

BIN
Example1/bin/Debug_Ubuntu/websocket-sharp.dll.mdb

BIN
Example2/bin/Debug_Ubuntu/example2.exe

BIN
Example2/bin/Debug_Ubuntu/example2.exe.mdb

BIN
Example2/bin/Debug_Ubuntu/websocket-sharp.dll

BIN
Example2/bin/Debug_Ubuntu/websocket-sharp.dll.mdb

BIN
Example3/bin/Debug_Ubuntu/Example3.exe

BIN
Example3/bin/Debug_Ubuntu/Example3.exe.mdb

BIN
Example3/bin/Debug_Ubuntu/websocket-sharp.dll

BIN
Example3/bin/Debug_Ubuntu/websocket-sharp.dll.mdb

21
websocket-sharp/Net/HttpConnection.cs

@ -1,6 +1,6 @@
//
// HttpConnection.cs
// Copied from System.Net.HttpConnection
// Copied from System.Net.HttpConnection.cs
//
// Author:
// Gonzalo Paniagua Javier (gonzalo@novell.com)
@ -222,10 +222,12 @@ namespace WebSocketSharp.Net {
} catch {
if (ms != null && ms.Length > 0)
SendError ();
if (sock != null) {
CloseSocket ();
Unbind ();
}
return;
}
@ -252,6 +254,7 @@ namespace WebSocketSharp.Net {
Close (true);
return;
}
HttpListener listener = context.Listener;
if (last_listener != listener) {
RemoveConnection ();
@ -263,6 +266,7 @@ namespace WebSocketSharp.Net {
listener.RegisterContext (context);
return;
}
stream.BeginRead (buffer, 0, BufferSize, onread_cb, this);
}
@ -340,6 +344,7 @@ namespace WebSocketSharp.Net {
{
if (current_line == null)
current_line = new StringBuilder ();
int last = offset + len;
used = 0;
for (int i = offset; i < last && line_state != LineState.LF; i++) {
@ -396,15 +401,6 @@ namespace WebSocketSharp.Net {
force_close |= !context.Request.KeepAlive;
if (!force_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 (chunked && context.Response.ForceCloseChunked == false) {
@ -433,6 +429,7 @@ namespace WebSocketSharp.Net {
if (s != null)
s.Close ();
}
Unbind ();
RemoveConnection ();
return;
@ -447,9 +444,11 @@ namespace WebSocketSharp.Net {
{
if (buffer == null)
buffer = new byte [BufferSize];
try {
if (reuses == 1)
s_timeout = 15000;
timer.Change (s_timeout, Timeout.Infinite);
stream.BeginRead (buffer, 0, BufferSize, onread_cb, this);
} catch {
@ -478,6 +477,7 @@ namespace WebSocketSharp.Net {
i_stream = new RequestStream (stream, buffer, position, length - position, contentlength);
}
}
return i_stream;
}
@ -489,6 +489,7 @@ namespace WebSocketSharp.Net {
bool ign = (listener == null) ? true : listener.IgnoreWriteExceptions;
o_stream = new ResponseStream (stream, context.Response, ign);
}
return o_stream;
}

110
websocket-sharp/Net/HttpListener.cs

@ -177,48 +177,67 @@ namespace WebSocketSharp.Net {
#region Private Methods
void Cleanup (bool close_existing)
void Cleanup (bool force)
{
lock (((ICollection)registry).SyncRoot) {
if (close_existing) {
// 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);
}
if (!force)
SendServiceUnavailable ();
lock (((ICollection)connections).SyncRoot) {
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);
}
CleanupContextRegistry ();
CleanupConnections ();
CleanupWaitQueue ();
}
}
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);
}
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);
}
}
lock (((ICollection)wait_queue).SyncRoot) {
Exception exc = new ObjectDisposedException ("listener");
foreach (ListenerAsyncResult ares in wait_queue) {
ares.Complete (exc);
}
wait_queue.Clear ();
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);
}
wait_queue.Clear ();
}
}
void Close (bool force)
{
CheckDisposed ();
EndPointManager.RemoveListener (this);
Cleanup (force);
}
@ -234,6 +253,22 @@ namespace WebSocketSharp.Net {
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
#region Internal Methods
@ -322,11 +357,6 @@ namespace WebSocketSharp.Net {
if (disposed)
return;
if (!listening) {
disposed = true;
return;
}
Close (true);
disposed = true;
}
@ -383,11 +413,6 @@ namespace WebSocketSharp.Net {
if (disposed)
return;
if (!listening) {
disposed = true;
return;
}
Close (false);
disposed = true;
}
@ -487,8 +512,9 @@ namespace WebSocketSharp.Net {
if (!listening)
return;
EndPointManager.RemoveListener (this);
listening = false;
EndPointManager.RemoveListener (this);
SendServiceUnavailable ();
}
#endregion

1
websocket-sharp/Net/HttpListenerRequest.cs

@ -459,6 +459,7 @@ namespace WebSocketSharp.Net {
IAsyncResult ares = InputStream.BeginRead (bytes, 0, length, null, null);
if (!ares.IsCompleted && !ares.AsyncWaitHandle.WaitOne (100))
return false;
if (InputStream.EndRead (ares) <= 0)
return true;
} catch {

29
websocket-sharp/Net/HttpListenerResponse.cs

@ -166,7 +166,7 @@ namespace WebSocketSharp.Net {
if (HeadersSent)
throw new InvalidOperationException ("Cannot be changed after headers are sent.");
keep_alive = value;
}
}
@ -175,10 +175,11 @@ namespace WebSocketSharp.Net {
get {
if (output_stream == null)
output_stream = context.Connection.GetResponseStream ();
return output_stream;
}
}
public Version ProtocolVersion {
get { return version; }
set {
@ -209,7 +210,7 @@ namespace WebSocketSharp.Net {
if (HeadersSent)
throw new InvalidOperationException ("Cannot be changed after headers are sent.");
location = value;
}
}
@ -222,7 +223,7 @@ namespace WebSocketSharp.Net {
if (HeadersSent)
throw new InvalidOperationException ("Cannot be changed after headers are sent.");
chunked = value;
}
}
@ -261,11 +262,6 @@ namespace WebSocketSharp.Net {
context.Connection.Close (force);
}
void IDisposable.Dispose ()
{
Close (true); // TODO: Abort or Close?
}
bool FindCookie (Cookie cookie)
{
string name = cookie.Name;
@ -396,6 +392,15 @@ namespace WebSocketSharp.Net {
#endregion
#region Explicit Interface Implementation
void IDisposable.Dispose ()
{
Close (true); // TODO: Abort or Close?
}
#endregion
#region Public Methods
public void Abort ()
@ -413,7 +418,7 @@ namespace WebSocketSharp.Net {
if (name == "")
throw new ArgumentException ("'name' cannot be empty", "name");
// TODO: check for forbidden headers and invalid characters
if (value.Length > 65535)
throw new ArgumentOutOfRangeException ("value");
@ -425,7 +430,7 @@ namespace WebSocketSharp.Net {
{
if (cookie == null)
throw new ArgumentNullException ("cookie");
Cookies.Add (cookie);
}
@ -436,7 +441,7 @@ namespace WebSocketSharp.Net {
if (name == "")
throw new ArgumentException ("'name' cannot be empty", "name");
if (value.Length > 65535)
throw new ArgumentOutOfRangeException ("value");

203
websocket-sharp/Net/ResponseStream.cs

@ -1,6 +1,6 @@
//
// ResponseStream.cs
// Copied from System.Net.ResponseStream
// Copied from System.Net.ResponseStream.cs
//
// Author:
// 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
// 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?
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;
bool ignore_errors;
bool disposed;
bool trailer_sent;
System.IO.Stream stream;
Stream stream;
bool trailer_sent;
#endregion
#region Constructor
internal ResponseStream (System.IO.Stream stream, HttpListenerResponse response, bool ignore_errors)
{
this.stream = stream;
this.response = response;
this.ignore_errors = ignore_errors;
this.stream = stream;
}
#endregion
#region Properties
public override bool CanRead {
get { return false; }
}
@ -77,99 +92,63 @@ namespace WebSocketSharp.Net {
set { throw new NotSupportedException (); }
}
#endregion
public override void Close ()
#region Private Methods
static byte [] GetChunkSizeBytes (int size, bool final)
{
if (disposed == false) {
disposed = true;
byte [] bytes = null;
MemoryStream ms = GetHeaders (true);
bool chunked = response.SendChunked;
if (ms != null) {
long start = ms.Position;
if (chunked && !trailer_sent) {
bytes = GetChunkSizeBytes (0, true);
ms.Position = ms.Length;
ms.Write (bytes, 0, bytes.Length);
}
InternalWrite (ms.GetBuffer (), (int) start, (int) (ms.Length - start));
trailer_sent = true;
} else if (chunked && !trailer_sent) {
bytes = GetChunkSizeBytes (0, true);
InternalWrite (bytes, 0, bytes.Length);
trailer_sent = true;
}
response.Close ();
}
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;
}
public override void Flush ()
{
}
#endregion
static byte [] crlf = new byte [] { 13, 10 };
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);
}
#region Internal Method
internal void InternalWrite (byte [] buffer, int offset, int count)
{
if (ignore_errors) {
try {
stream.Write (buffer, offset, count);
} catch { }
} catch {
}
} else {
stream.Write (buffer, offset, count);
}
}
public override void Write (byte [] buffer, int offset, int count)
{
if (disposed)
throw new ObjectDisposedException (GetType ().ToString ());
#endregion
byte [] bytes = null;
MemoryStream ms = GetHeaders (false);
bool chunked = response.SendChunked;
if (ms != null) {
long start = ms.Position; // After the possible preamble for the encoding
ms.Position = ms.Length;
if (chunked) {
bytes = GetChunkSizeBytes (count, false);
ms.Write (bytes, 0, bytes.Length);
}
#region Public Methods
int new_count = Math.Min (count, 16384 - (int) ms.Position + (int) start);
ms.Write (buffer, offset, new_count);
count -= new_count;
offset += new_count;
InternalWrite (ms.GetBuffer (), (int) start, (int) (ms.Length - start));
ms.SetLength (0);
ms.Capacity = 0; // 'dispose' the buffer in ms.
} else if (chunked) {
bytes = GetChunkSizeBytes (count, false);
InternalWrite (bytes, 0, bytes.Length);
}
if (count > 0)
InternalWrite (buffer, offset, count);
if (chunked)
InternalWrite (crlf, 0, 2);
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)
public override IAsyncResult BeginWrite (
byte [] buffer,
int offset,
int count,
AsyncCallback cback,
object state)
{
if (disposed)
throw new ObjectDisposedException (GetType ().ToString ());
@ -196,6 +175,37 @@ namespace WebSocketSharp.Net {
return stream.BeginWrite (buffer, offset, count, cback, state);
}
public override void Close ()
{
if (disposed == false) {
disposed = true;
byte [] bytes = null;
MemoryStream ms = GetHeaders (true);
bool chunked = response.SendChunked;
if (ms != null) {
long start = ms.Position;
if (chunked && !trailer_sent) {
bytes = GetChunkSizeBytes (0, true);
ms.Position = ms.Length;
ms.Write (bytes, 0, bytes.Length);
}
InternalWrite (ms.GetBuffer (), (int) start, (int) (ms.Length - start));
trailer_sent = true;
} else if (chunked && !trailer_sent) {
bytes = GetChunkSizeBytes (0, true);
InternalWrite (bytes, 0, bytes.Length);
trailer_sent = true;
}
response.Close ();
}
}
public override int EndRead (IAsyncResult ares)
{
throw new NotSupportedException ();
}
public override void EndWrite (IAsyncResult ares)
{
if (disposed)
@ -206,7 +216,8 @@ namespace WebSocketSharp.Net {
stream.EndWrite (ares);
if (response.SendChunked)
stream.Write (crlf, 0, 2);
} catch { }
} catch {
}
} else {
stream.EndWrite (ares);
if (response.SendChunked)
@ -214,30 +225,60 @@ namespace WebSocketSharp.Net {
}
}
public override int Read ([In,Out] byte[] buffer, int offset, int count)
public override void Flush ()
{
throw new NotSupportedException ();
}
public override IAsyncResult BeginRead (byte [] buffer, int offset, int count,
AsyncCallback cback, object state)
public override int Read ([In,Out] byte[] buffer, int offset, int count)
{
throw new NotSupportedException ();
}
public override int EndRead (IAsyncResult ares)
public override long Seek (long offset, SeekOrigin origin)
{
throw new NotSupportedException ();
}
public override long Seek (long offset, SeekOrigin origin)
public override void SetLength (long value)
{
throw new NotSupportedException ();
}
public override void SetLength (long value)
public override void Write (byte [] buffer, int offset, int count)
{
throw new NotSupportedException ();
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; // After the possible preamble for the encoding
ms.Position = ms.Length;
if (chunked) {
bytes = GetChunkSizeBytes (count, false);
ms.Write (bytes, 0, bytes.Length);
}
int new_count = Math.Min (count, 16384 - (int) ms.Position + (int) start);
ms.Write (buffer, offset, new_count);
count -= new_count;
offset += new_count;
InternalWrite (ms.GetBuffer (), (int) start, (int) (ms.Length - start));
ms.SetLength (0);
ms.Capacity = 0; // 'dispose' the buffer in ms.
} else if (chunked) {
bytes = GetChunkSizeBytes (count, false);
InternalWrite (bytes, 0, bytes.Length);
}
if (count > 0)
InternalWrite (buffer, offset, count);
if (chunked)
InternalWrite (crlf, 0, 2);
}
#endregion
}
}

BIN
websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll

BIN
websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll.mdb

BIN
websocket-sharp/websocket-sharp.pidb

Loading…
Cancel
Save