Moved some methods from WebSocketStream class to HttpBase class
This commit is contained in:
parent
a0764d89ff
commit
48c6fac2f5
@ -27,8 +27,11 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using WebSocketSharp.Net;
|
||||
|
||||
namespace WebSocketSharp
|
||||
@ -38,6 +41,7 @@ namespace WebSocketSharp
|
||||
#region Private Fields
|
||||
|
||||
private NameValueCollection _headers;
|
||||
private const int _headersMaxLength = 8192;
|
||||
private Version _version;
|
||||
|
||||
#endregion
|
||||
@ -48,7 +52,7 @@ namespace WebSocketSharp
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Const Fields
|
||||
#region Protected Fields
|
||||
|
||||
protected const string CrLf = "\r\n";
|
||||
|
||||
@ -107,6 +111,96 @@ namespace WebSocketSharp
|
||||
return Encoding.GetEncoding (charset);
|
||||
}
|
||||
|
||||
private static byte[] readEntityBody (Stream stream, string length)
|
||||
{
|
||||
long len;
|
||||
if (!Int64.TryParse (length, out len))
|
||||
throw new ArgumentException ("Cannot be parsed.", "length");
|
||||
|
||||
if (len < 0)
|
||||
throw new ArgumentOutOfRangeException ("length", "Less than zero.");
|
||||
|
||||
return len > 1024
|
||||
? stream.ReadBytes (len, 1024)
|
||||
: len > 0
|
||||
? stream.ReadBytes ((int) len)
|
||||
: null;
|
||||
}
|
||||
|
||||
private static string[] readHeaders (Stream stream, int maxLength)
|
||||
{
|
||||
var buff = new List<byte> ();
|
||||
var cnt = 0;
|
||||
Action<int> add = i => {
|
||||
buff.Add ((byte) i);
|
||||
cnt++;
|
||||
};
|
||||
|
||||
var read = false;
|
||||
while (cnt < maxLength) {
|
||||
if (stream.ReadByte ().EqualsWith ('\r', add) &&
|
||||
stream.ReadByte ().EqualsWith ('\n', add) &&
|
||||
stream.ReadByte ().EqualsWith ('\r', add) &&
|
||||
stream.ReadByte ().EqualsWith ('\n', add)) {
|
||||
read = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!read)
|
||||
throw new WebSocketException ("The length of header part is greater than the max length.");
|
||||
|
||||
return Encoding.UTF8.GetString (buff.ToArray ())
|
||||
.Replace (CrLf + " ", " ")
|
||||
.Replace (CrLf + "\t", " ")
|
||||
.Split (new[] { CrLf }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected 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;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using WebSocketSharp.Net;
|
||||
|
||||
@ -137,6 +138,14 @@ namespace WebSocketSharp
|
||||
return req;
|
||||
}
|
||||
|
||||
internal HttpResponse GetResponse (Stream stream, int millisecondsTimeout)
|
||||
{
|
||||
var buff = ToByteArray ();
|
||||
stream.Write (buff, 0, buff.Length);
|
||||
|
||||
return Read<HttpResponse> (stream, HttpResponse.Parse, millisecondsTimeout);
|
||||
}
|
||||
|
||||
internal static HttpRequest Parse (string[] headerParts)
|
||||
{
|
||||
var requestLine = headerParts[0].Split (new[] { ' ' }, 3);
|
||||
@ -151,6 +160,11 @@ namespace WebSocketSharp
|
||||
requestLine[0], requestLine[1], new Version (requestLine[2].Substring (5)), headers);
|
||||
}
|
||||
|
||||
internal static HttpRequest Read (Stream stream, int millisecondsTimeout)
|
||||
{
|
||||
return Read<HttpRequest> (stream, Parse, millisecondsTimeout);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using WebSocketSharp.Net;
|
||||
|
||||
@ -173,6 +174,11 @@ namespace WebSocketSharp
|
||||
statusLine[1], statusLine[2], new Version (statusLine[0].Substring (5)), headers);
|
||||
}
|
||||
|
||||
internal static HttpResponse Read (Stream stream, int millisecondsTimeout)
|
||||
{
|
||||
return Read<HttpResponse> (stream, Parse, millisecondsTimeout);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
@ -27,12 +27,9 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using WebSocketSharp.Net;
|
||||
using WebSocketSharp.Net.Security;
|
||||
|
||||
@ -40,12 +37,6 @@ namespace WebSocketSharp
|
||||
{
|
||||
internal class WebSocketStream : IDisposable
|
||||
{
|
||||
#region Private Const Fields
|
||||
|
||||
private const int _headersMaxLength = 8192;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private Stream _innerStream;
|
||||
@ -81,106 +72,6 @@ namespace WebSocketSharp
|
||||
|
||||
#endregion
|
||||
|
||||
#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)
|
||||
{
|
||||
long len;
|
||||
if (!Int64.TryParse (length, out len))
|
||||
throw new ArgumentException ("Cannot be parsed.", "length");
|
||||
|
||||
if (len < 0)
|
||||
throw new ArgumentOutOfRangeException ("length", "Less than zero.");
|
||||
|
||||
return len > 1024
|
||||
? stream.ReadBytes (len, 1024)
|
||||
: len > 0
|
||||
? stream.ReadBytes ((int) len)
|
||||
: null;
|
||||
}
|
||||
|
||||
private static string[] readHeaders (Stream stream, int maxLength)
|
||||
{
|
||||
var buff = new List<byte> ();
|
||||
var cnt = 0;
|
||||
Action<int> add = i => {
|
||||
buff.Add ((byte) i);
|
||||
cnt++;
|
||||
};
|
||||
|
||||
var read = false;
|
||||
while (cnt < maxLength) {
|
||||
if (stream.ReadByte ().EqualsWith ('\r', add) &&
|
||||
stream.ReadByte ().EqualsWith ('\n', add) &&
|
||||
stream.ReadByte ().EqualsWith ('\r', add) &&
|
||||
stream.ReadByte ().EqualsWith ('\n', add)) {
|
||||
read = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!read)
|
||||
throw new WebSocketException ("The length of header part is greater than the max length.");
|
||||
|
||||
var crlf = "\r\n";
|
||||
return Encoding.UTF8.GetString (buff.ToArray ())
|
||||
.Replace (crlf + " ", " ")
|
||||
.Replace (crlf + "\t", " ")
|
||||
.Split (new[] { crlf }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
private static HttpResponse sendHttpRequest (
|
||||
Stream stream, HttpRequest request, int millisecondsTimeout)
|
||||
{
|
||||
var buff = request.ToByteArray ();
|
||||
stream.Write (buff, 0, buff.Length);
|
||||
|
||||
return read<HttpResponse> (stream, HttpResponse.Parse, millisecondsTimeout);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal Methods
|
||||
|
||||
internal static WebSocketStream CreateClientStream (
|
||||
@ -199,7 +90,7 @@ namespace WebSocketSharp
|
||||
var netStream = tcpClient.GetStream ();
|
||||
if (proxy) {
|
||||
var req = HttpRequest.CreateConnectRequest (targetUri);
|
||||
var res = sendHttpRequest (netStream, req, 90000);
|
||||
var res = req.GetResponse (netStream, 90000);
|
||||
if (res.IsProxyAuthenticationRequired) {
|
||||
var authChal = res.ProxyAuthenticationChallenge;
|
||||
if (authChal != null && proxyCredentials != null) {
|
||||
@ -213,7 +104,7 @@ namespace WebSocketSharp
|
||||
|
||||
var authRes = new AuthenticationResponse (authChal, proxyCredentials, 0);
|
||||
req.Headers["Proxy-Authorization"] = authRes.ToString ();
|
||||
res = sendHttpRequest (netStream, req, 15000);
|
||||
res = req.GetResponse (netStream, 15000);
|
||||
}
|
||||
|
||||
if (res.IsProxyAuthenticationRequired)
|
||||
@ -256,12 +147,12 @@ namespace WebSocketSharp
|
||||
|
||||
internal HttpRequest ReadHttpRequest (int millisecondsTimeout)
|
||||
{
|
||||
return read<HttpRequest> (_innerStream, HttpRequest.Parse, millisecondsTimeout);
|
||||
return HttpRequest.Read (_innerStream, millisecondsTimeout);
|
||||
}
|
||||
|
||||
internal HttpResponse ReadHttpResponse (int millisecondsTimeout)
|
||||
{
|
||||
return read<HttpResponse> (_innerStream, HttpResponse.Parse, millisecondsTimeout);
|
||||
return HttpResponse.Read (_innerStream, millisecondsTimeout);
|
||||
}
|
||||
|
||||
internal WebSocketFrame ReadWebSocketFrame ()
|
||||
@ -277,7 +168,7 @@ namespace WebSocketSharp
|
||||
|
||||
internal HttpResponse SendHttpRequest (HttpRequest request, int millisecondsTimeout)
|
||||
{
|
||||
return sendHttpRequest (_innerStream, request, millisecondsTimeout);
|
||||
return request.GetResponse (_innerStream, millisecondsTimeout);
|
||||
}
|
||||
|
||||
internal bool WriteBytes (byte[] data)
|
||||
|
Loading…
Reference in New Issue
Block a user