|
|
|
@ -48,7 +48,6 @@ namespace WebSocketSharp
|
|
|
|
|
|
|
|
|
|
|
|
#region Private Fields
|
|
|
|
#region Private Fields
|
|
|
|
|
|
|
|
|
|
|
|
private object _forWrite;
|
|
|
|
|
|
|
|
private Stream _innerStream;
|
|
|
|
private Stream _innerStream;
|
|
|
|
private bool _secure;
|
|
|
|
private bool _secure;
|
|
|
|
|
|
|
|
|
|
|
|
@ -60,7 +59,6 @@ namespace WebSocketSharp
|
|
|
|
{
|
|
|
|
{
|
|
|
|
_innerStream = innerStream;
|
|
|
|
_innerStream = innerStream;
|
|
|
|
_secure = secure;
|
|
|
|
_secure = secure;
|
|
|
|
_forWrite = new object ();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
@ -85,6 +83,47 @@ namespace WebSocketSharp
|
|
|
|
|
|
|
|
|
|
|
|
#region Private Methods
|
|
|
|
#region Private Methods
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static T read<T> (Stream stream, Func<string[], T> parser, int millisecondsTimeout)
|
|
|
|
|
|
|
|
where T : HttpBase
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var timeout = false;
|
|
|
|
|
|
|
|
var timer = new Timer (
|
|
|
|
|
|
|
|
state => {
|
|
|
|
|
|
|
|
timeout = true;
|
|
|
|
|
|
|
|
stream.Close ();
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
null,
|
|
|
|
|
|
|
|
millisecondsTimeout,
|
|
|
|
|
|
|
|
-1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
T http = null;
|
|
|
|
|
|
|
|
Exception exception = null;
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
http = parser (readHeaders (stream, _headersMaxLength));
|
|
|
|
|
|
|
|
var contentLen = http.Headers["Content-Length"];
|
|
|
|
|
|
|
|
if (contentLen != null && contentLen.Length > 0)
|
|
|
|
|
|
|
|
http.EntityBodyData = readEntityBody (stream, contentLen);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
catch (Exception ex) {
|
|
|
|
|
|
|
|
exception = ex;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
finally {
|
|
|
|
|
|
|
|
timer.Change (-1, -1);
|
|
|
|
|
|
|
|
timer.Dispose ();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var msg = timeout
|
|
|
|
|
|
|
|
? "A timeout has occurred while reading an HTTP request/response."
|
|
|
|
|
|
|
|
: exception != null
|
|
|
|
|
|
|
|
? "An exception has occurred while reading an HTTP request/response."
|
|
|
|
|
|
|
|
: null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (msg != null)
|
|
|
|
|
|
|
|
throw new WebSocketException (msg, exception);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return http;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static byte[] readEntityBody (Stream stream, string length)
|
|
|
|
private static byte[] readEntityBody (Stream stream, string length)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
long len;
|
|
|
|
long len;
|
|
|
|
@ -122,8 +161,7 @@ namespace WebSocketSharp
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!read)
|
|
|
|
if (!read)
|
|
|
|
throw new WebSocketException (
|
|
|
|
throw new WebSocketException ("The length of header part is greater than the max length.");
|
|
|
|
"The header part of a HTTP data is greater than the max length.");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var crlf = "\r\n";
|
|
|
|
var crlf = "\r\n";
|
|
|
|
return Encoding.UTF8.GetString (buff.ToArray ())
|
|
|
|
return Encoding.UTF8.GetString (buff.ToArray ())
|
|
|
|
@ -132,65 +170,13 @@ namespace WebSocketSharp
|
|
|
|
.Split (new[] { crlf }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
.Split (new[] { crlf }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static T readHttp<T> (Stream stream, Func<string[], T> parser, int millisecondsTimeout)
|
|
|
|
|
|
|
|
where T : HttpBase
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var timeout = false;
|
|
|
|
|
|
|
|
var timer = new Timer (
|
|
|
|
|
|
|
|
state => {
|
|
|
|
|
|
|
|
timeout = true;
|
|
|
|
|
|
|
|
stream.Close ();
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
null,
|
|
|
|
|
|
|
|
millisecondsTimeout,
|
|
|
|
|
|
|
|
-1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
T http = null;
|
|
|
|
|
|
|
|
Exception exception = null;
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
http = parser (readHeaders (stream, _headersMaxLength));
|
|
|
|
|
|
|
|
var contentLen = http.Headers["Content-Length"];
|
|
|
|
|
|
|
|
if (contentLen != null && contentLen.Length > 0)
|
|
|
|
|
|
|
|
http.EntityBodyData = readEntityBody (stream, contentLen);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
catch (Exception ex) {
|
|
|
|
|
|
|
|
exception = ex;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
finally {
|
|
|
|
|
|
|
|
timer.Change (-1, -1);
|
|
|
|
|
|
|
|
timer.Dispose ();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var msg = timeout
|
|
|
|
|
|
|
|
? "A timeout has occurred while receiving a HTTP data."
|
|
|
|
|
|
|
|
: exception != null
|
|
|
|
|
|
|
|
? "An exception has occurred while receiving a HTTP data."
|
|
|
|
|
|
|
|
: null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (msg != null)
|
|
|
|
|
|
|
|
throw new WebSocketException (msg, exception);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return http;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static HttpResponse sendHttpRequest (
|
|
|
|
private static HttpResponse sendHttpRequest (
|
|
|
|
Stream stream, HttpRequest request, int millisecondsTimeout)
|
|
|
|
Stream stream, HttpRequest request, int millisecondsTimeout)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var buff = request.ToByteArray ();
|
|
|
|
var buff = request.ToByteArray ();
|
|
|
|
stream.Write (buff, 0, buff.Length);
|
|
|
|
stream.Write (buff, 0, buff.Length);
|
|
|
|
|
|
|
|
|
|
|
|
return readHttp<HttpResponse> (stream, HttpResponse.Parse, millisecondsTimeout);
|
|
|
|
return read<HttpResponse> (stream, HttpResponse.Parse, millisecondsTimeout);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static bool writeBytes (Stream stream, byte[] data)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
stream.Write (data, 0, data.Length);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
catch {
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
@ -235,7 +221,7 @@ namespace WebSocketSharp
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var code = res.StatusCode;
|
|
|
|
var code = res.StatusCode;
|
|
|
|
if (code.Length != 3 || code[0] != '2')
|
|
|
|
if (code[0] != '2')
|
|
|
|
throw new WebSocketException (
|
|
|
|
throw new WebSocketException (
|
|
|
|
String.Format (
|
|
|
|
String.Format (
|
|
|
|
"The proxy has failed a connection to the requested host and port. ({0})", code));
|
|
|
|
"The proxy has failed a connection to the requested host and port. ({0})", code));
|
|
|
|
@ -270,12 +256,12 @@ namespace WebSocketSharp
|
|
|
|
|
|
|
|
|
|
|
|
internal HttpRequest ReadHttpRequest (int millisecondsTimeout)
|
|
|
|
internal HttpRequest ReadHttpRequest (int millisecondsTimeout)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return readHttp<HttpRequest> (_innerStream, HttpRequest.Parse, millisecondsTimeout);
|
|
|
|
return read<HttpRequest> (_innerStream, HttpRequest.Parse, millisecondsTimeout);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
internal HttpResponse ReadHttpResponse (int millisecondsTimeout)
|
|
|
|
internal HttpResponse ReadHttpResponse (int millisecondsTimeout)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return readHttp<HttpResponse> (_innerStream, HttpResponse.Parse, millisecondsTimeout);
|
|
|
|
return read<HttpResponse> (_innerStream, HttpResponse.Parse, millisecondsTimeout);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
internal WebSocketFrame ReadWebSocketFrame ()
|
|
|
|
internal WebSocketFrame ReadWebSocketFrame ()
|
|
|
|
@ -296,13 +282,13 @@ namespace WebSocketSharp
|
|
|
|
|
|
|
|
|
|
|
|
internal bool WriteBytes (byte[] data)
|
|
|
|
internal bool WriteBytes (byte[] data)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
lock (_forWrite)
|
|
|
|
try {
|
|
|
|
return writeBytes (_innerStream, data);
|
|
|
|
_innerStream.Write (data, 0, data.Length);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
internal bool WriteHttp (HttpBase http)
|
|
|
|
catch {
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
return writeBytes (_innerStream, http.ToByteArray ());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
|