Refactored HttpConnection.cs

This commit is contained in:
sta 2014-04-26 16:18:23 +09:00
parent 138628b470
commit fe28277f14
3 changed files with 55 additions and 63 deletions

View File

@ -218,7 +218,7 @@ namespace WebSocketSharp.Net
HttpConnection conn = null; HttpConnection conn = null;
try { try {
conn = new HttpConnection (accepted, listener, listener._secure, listener._cert); conn = new HttpConnection (accepted, listener);
lock (((ICollection) listener._unregistered).SyncRoot) lock (((ICollection) listener._unregistered).SyncRoot)
listener._unregistered [conn] = conn; listener._unregistered [conn] = conn;

View File

@ -8,7 +8,7 @@
* The MIT License * The MIT License
* *
* Copyright (c) 2005 Novell, Inc. (http://www.novell.com) * Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
* Copyright (c) 2012-2013 sta.blockhead * Copyright (c) 2012-2014 sta.blockhead
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -33,7 +33,7 @@
#region Authors #region Authors
/* /*
* Authors: * Authors:
* Gonzalo Paniagua Javier <gonzalo@novell.com> * - Gonzalo Paniagua Javier <gonzalo@novell.com>
*/ */
#endregion #endregion
@ -100,27 +100,25 @@ namespace WebSocketSharp.Net
#region Public Constructors #region Public Constructors
public HttpConnection ( public HttpConnection (Socket socket, EndPointListener listener)
Socket socket,
EndPointListener listener,
bool secure,
X509Certificate2 cert)
{ {
_socket = socket; _socket = socket;
_epListener = listener; _epListener = listener;
_secure = secure; _secure = listener.IsSecure;
var netStream = new NetworkStream (socket, false); var netStream = new NetworkStream (socket, false);
if (!secure) if (!_secure) {
_stream = netStream; _stream = netStream;
}
else { else {
var sslStream = new SslStream (netStream, false); var sslStream = new SslStream (netStream, false);
sslStream.AuthenticateAsServer (cert); sslStream.AuthenticateAsServer (listener.Certificate);
_stream = sslStream; _stream = sslStream;
} }
_timeout = 90000; // 90k ms for first request, 15k ms from then on. _timeout = 90000; // 90k ms for first request, 15k ms from then on.
_timer = new Timer (onTimeout, null, Timeout.Infinite, Timeout.Infinite); _timer = new Timer (onTimeout, this, Timeout.Infinite, Timeout.Infinite);
init (); init ();
} }
@ -211,80 +209,77 @@ namespace WebSocketSharp.Net
private static void onRead (IAsyncResult asyncResult) private static void onRead (IAsyncResult asyncResult)
{ {
var conn = (HttpConnection) asyncResult.AsyncState; var conn = (HttpConnection) asyncResult.AsyncState;
conn.onReadInternal (asyncResult); conn._timer.Change (Timeout.Infinite, Timeout.Infinite);
}
private void onReadInternal (IAsyncResult asyncResult)
{
_timer.Change (Timeout.Infinite, Timeout.Infinite);
var read = -1; var read = -1;
try { try {
read = _stream.EndRead (asyncResult); read = conn._stream.EndRead (asyncResult);
_requestBuffer.Write (_buffer, 0, read); conn._requestBuffer.Write (conn._buffer, 0, read);
if (_requestBuffer.Length > 32768) { if (conn._requestBuffer.Length > 32768) {
SendError (); conn.SendError ();
Close (true); conn.Close (true);
return; return;
} }
} }
catch { catch {
if (_requestBuffer != null && _requestBuffer.Length > 0) if (conn._requestBuffer != null && conn._requestBuffer.Length > 0)
SendError (); conn.SendError ();
if (_socket != null) { if (conn._socket != null) {
closeSocket (); conn.closeSocket ();
unbind (); conn.unbind ();
} }
return; return;
} }
if (read <= 0) { if (read <= 0) {
closeSocket (); conn.closeSocket ();
unbind (); conn.unbind ();
return; return;
} }
if (processInput (_requestBuffer.GetBuffer ())) { if (conn.processInput (conn._requestBuffer.GetBuffer ())) {
if (!_context.HaveError) if (!conn._context.HaveError) {
_context.Request.FinishInitialization (); conn._context.Request.FinishInitialization ();
}
else { else {
SendError (); conn.SendError ();
Close (true); conn.Close (true);
return; return;
} }
if (!_epListener.BindContext (_context)) { if (!conn._epListener.BindContext (conn._context)) {
SendError ("Invalid host", 400); conn.SendError ("Invalid host.", 400);
Close (true); conn.Close (true);
return; return;
} }
var listener = _context.Listener; var listener = conn._context.Listener;
if (_lastListener != listener) { if (conn._lastListener != listener) {
removeConnection (); conn.removeConnection ();
listener.AddConnection (this); listener.AddConnection (conn);
_lastListener = listener; conn._lastListener = listener;
} }
_contextWasBound = true; conn._contextWasBound = true;
listener.RegisterContext (_context); listener.RegisterContext (conn._context);
return; return;
} }
_stream.BeginRead (_buffer, 0, _bufferSize, onRead, this); conn._stream.BeginRead (conn._buffer, 0, _bufferSize, onRead, conn);
} }
private void onTimeout (object unused) private static void onTimeout (object state)
{ {
closeSocket (); var conn = (HttpConnection) state;
unbind (); conn.closeSocket ();
conn.unbind ();
} }
// true -> Done processing. // true -> Done processing.
@ -295,8 +290,7 @@ namespace WebSocketSharp.Net
var used = 0; var used = 0;
string line; string line;
try { try {
while ((line = readLine ( while ((line = readLine (data, _position, length - _position, ref used)) != null) {
data, _position, length - _position, ref used)) != null) {
_position += used; _position += used;
if (line.Length == 0) { if (line.Length == 0) {
if (_inputState == InputState.RequestLine) if (_inputState == InputState.RequestLine)
@ -332,8 +326,7 @@ namespace WebSocketSharp.Net
return false; return false;
} }
private string readLine ( private string readLine (byte [] buffer, int offset, int length, ref int used)
byte [] buffer, int offset, int length, ref int used)
{ {
if (_currentLine == null) if (_currentLine == null)
_currentLine = new StringBuilder (); _currentLine = new StringBuilder ();
@ -343,15 +336,12 @@ namespace WebSocketSharp.Net
for (int i = offset; i < last && _lineState != LineState.LF; i++) { for (int i = offset; i < last && _lineState != LineState.LF; i++) {
used++; used++;
var b = buffer [i]; var b = buffer [i];
if (b == 13) { if (b == 13)
_lineState = LineState.CR; _lineState = LineState.CR;
} else if (b == 10)
else if (b == 10) {
_lineState = LineState.LF; _lineState = LineState.LF;
} else
else {
_currentLine.Append ((char) b); _currentLine.Append ((char) b);
}
} }
string result = null; string result = null;
@ -505,8 +495,8 @@ namespace WebSocketSharp.Net
var description = status.GetStatusDescription (); var description = status.GetStatusDescription ();
var error = message != null && message.Length > 0 var error = message != null && message.Length > 0
? String.Format ("<h1>{0} ({1})</h1>", description, message) ? String.Format ("<h1>{0} ({1})</h1>", description, message)
: String.Format ("<h1>{0}</h1>", description); : String.Format ("<h1>{0}</h1>", description);
var entity = res.ContentEncoding.GetBytes (error); var entity = res.ContentEncoding.GetBytes (error);
res.Close (entity, false); res.Close (entity, false);

View File

@ -452,7 +452,8 @@ namespace WebSocketSharp.Net
internal void AddConnection (HttpConnection connection) internal void AddConnection (HttpConnection connection)
{ {
_connections [connection] = connection; lock (((ICollection) _connections).SyncRoot)
_connections [connection] = connection;
} }
internal ListenerAsyncResult BeginGetContext (ListenerAsyncResult asyncResult) internal ListenerAsyncResult BeginGetContext (ListenerAsyncResult asyncResult)
@ -509,7 +510,8 @@ namespace WebSocketSharp.Net
internal void RemoveConnection (HttpConnection connection) internal void RemoveConnection (HttpConnection connection)
{ {
_connections.Remove (connection); lock (((ICollection) _connections).SyncRoot)
_connections.Remove (connection);
} }
internal AuthenticationSchemes SelectAuthenticationScheme (HttpListenerContext context) internal AuthenticationSchemes SelectAuthenticationScheme (HttpListenerContext context)