Permalink
Browse files

Fixed #53 now completely. Prepared SSL part for future timeout implem…

…entation.
  • Loading branch information...
1 parent 97085f0 commit ec45134374fab8bf0acfa2482d07ac4fcc667b1a @Bobris committed Nov 21, 2015
@@ -0,0 +1,8 @@
+
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Common Practices and Code Improvements", "RECS0033:Convert 'if' to '||' expression", Justification = "Cannot be similified - bool could be set to true from inside and still returning false", Scope = "member", Target = "~M:Nowin.Transport2HttpHandler.ProcessReceive~System.Boolean")]
+
@@ -8,7 +8,8 @@ public interface ITransportLayerHandler : ILayerHandler
{
ITransportLayerCallback Callback { set; }
void PrepareAccept();
- void FinishAccept(byte[] buffer, int offset, int length, IPEndPoint remoteEndPoint, IPEndPoint localEndPoint, X509Certificate remoteCertificate);
+ void FinishAccept(byte[] buffer, int offset, int length, IPEndPoint remoteEndPoint, IPEndPoint localEndPoint);
+ void SetRemoteCertificate(X509Certificate remoteCertificate);
// length==-1 for connection closed
void FinishReceive(byte[] buffer, int offset, int length);
View
@@ -49,6 +49,7 @@
<Compile Include="DictionaryExtensions.cs" />
<Compile Include="ExecutionContextFlow.cs" />
<Compile Include="ExecutionContextFlowSuppresser.cs" />
+ <Compile Include="GlobalSuppressions.cs" />
<Compile Include="IDateHeaderValueProvider.cs" />
<Compile Include="IHttpLayerCallback.cs" />
<Compile Include="IHttpLayerHandler.cs" />
@@ -229,7 +229,7 @@ public void HandleRequest()
return;
}
if (!Callback.HeadersSend || Callback.ResponseStatusCode != 500)
- Callback.ResponseStatusCode = Callback.HeadersSend ? 599 : 500;
+ Callback.ResponseStatusCode = Callback.HeadersSend ? 599 : 5000;
Callback.ResponseReasonPhase = null;
Callback.ResponseFinished();
}
@@ -240,7 +240,7 @@ static void SetReponseStatusCodeForFails(Task t, IHttpLayerCallback callback)
if (t.IsFaulted || t.IsCanceled)
{
if (!t.IsFaulted || !callback.HeadersSend || callback.ResponseStatusCode != 500)
- callback.ResponseStatusCode = callback.HeadersSend ? 599 : 500;
+ callback.ResponseStatusCode = callback.HeadersSend ? 599 : 5000;
callback.ResponseReasonPhase = null;
}
}
@@ -132,7 +132,7 @@ void ProcessAccept()
{
_server.ReportNewConnectedClient();
_handler.FinishAccept(_receiveEvent.Buffer, _receiveEvent.Offset, bytesTransfered,
- remoteEndpoint, localEndpoint, null);
+ remoteEndpoint, localEndpoint);
return;
}
}
@@ -23,8 +23,6 @@ class SslTransportHandler : ITransportLayerHandler, ITransportLayerCallback
int _recvOffset;
int _recvLength;
readonly InputStream _inputStream;
- IPEndPoint _remoteEndPoint;
- IPEndPoint _localEndPoint;
public SslTransportHandler(ITransportLayerHandler next, X509Certificate serverCertificate, SslProtocols protocols, bool clientCertificateRequired)
{
@@ -179,13 +177,21 @@ public void Dispose()
public void PrepareAccept()
{
_ssl = null;
+ var t = _authenticateTask;
+ _authenticateTask = null;
+ if (t != null && !t.IsCompleted)
+ {
+ t.ContinueWith((t2, next) =>
+ {
+ ((ITransportLayerHandler)next).PrepareAccept();
+ }, _next);
+ return;
+ }
_next.PrepareAccept();
}
- public void FinishAccept(byte[] buffer, int offset, int length, IPEndPoint remoteEndPoint, IPEndPoint localEndPoint, X509Certificate clientCertificate)
+ public void FinishAccept(byte[] buffer, int offset, int length, IPEndPoint remoteEndPoint, IPEndPoint localEndPoint)
{
- _remoteEndPoint = remoteEndPoint;
- _localEndPoint = localEndPoint;
Debug.Assert(length == 0);
try
{
@@ -196,22 +202,21 @@ public void FinishAccept(byte[] buffer, int offset, int length, IPEndPoint remot
if (t.IsFaulted || t.IsCanceled)
self.Callback.StartDisconnect();
else
- self._ssl.ReadAsync(self._recvBuffer, self._recvOffset, self._recvLength).ContinueWith((t2, selfObject2) =>
- {
- var self2 = (SslTransportHandler)selfObject2;
- if (t2.IsFaulted || t2.IsCanceled)
- self.Callback.StartDisconnect();
- else
- self2._next.FinishAccept(self2._recvBuffer, self2._recvOffset, t2.Result, self2._remoteEndPoint, self2._localEndPoint, _ssl.RemoteCertificate);
- }, self);
+ _next.SetRemoteCertificate(_ssl.RemoteCertificate);
}, this);
+ _next.FinishAccept(_recvBuffer, _recvOffset, 0, remoteEndPoint, localEndPoint);
}
catch (Exception)
{
Callback.StartDisconnect();
}
}
+ public void SetRemoteCertificate(X509Certificate remoteCertificate)
+ {
+ throw new InvalidOperationException();
+ }
+
public void FinishReceive(byte[] buffer, int offset, int length)
{
_inputStream.FinishReceive(length);
@@ -237,6 +242,29 @@ public void StartReceive(byte[] buffer, int offset, int length)
_recvLength = length;
try
{
+ if (!_authenticateTask.IsCompleted)
+ {
+ _authenticateTask.ContinueWith((t, selfObject) =>
+ {
+ var self = (SslTransportHandler)selfObject;
+ if (t.IsCanceled || t.IsFaulted)
+ {
+ self._next.FinishReceive(null, 0, -1);
+ }
+ else
+ {
+ _ssl.ReadAsync(self._recvBuffer, self._recvOffset, self._recvLength).ContinueWith((t2, selfObject2) =>
+ {
+ var self2 = (SslTransportHandler)selfObject2;
+ if (t2.IsFaulted || t2.IsCanceled || t2.Result == 0)
+ self._next.FinishReceive(null, 0, -1);
+ else
+ self._next.FinishReceive(self2._recvBuffer, self2._recvOffset, t2.Result);
+ }, self);
+ }
+ }, this);
+ return;
+ }
_ssl.ReadAsync(buffer, offset, length).ContinueWith((t, selfObject) =>
{
var self = (SslTransportHandler)selfObject;
@@ -281,16 +309,7 @@ public void StartSend(byte[] buffer, int offset, int length)
public void StartDisconnect()
{
- var t = _authenticateTask;
- _authenticateTask = null;
- if (t != null)
- {
- t.ContinueWith((t2, callback) => ((ITransportLayerCallback)callback).StartDisconnect(), Callback);
- }
- else
- {
- Callback.StartDisconnect();
- }
+ Callback.StartDisconnect();
}
}
}
@@ -38,6 +38,7 @@ class Transport2HttpHandler : ITransportLayerHandler, IHttpLayerCallback
CancellationTokenSource _cancellation;
int _responseHeaderPos;
int _acceptCounter;
+ bool _afterReceiveContinueWithAccept;
bool _clientClosedConnection;
bool _lastPacket;
bool _responseIsChunked;
@@ -546,7 +547,7 @@ string ParseHttpMethod(byte[] buffer, ref int pos)
{
var b = buffer[p];
- if (b == (byte)' ')
+ if (b == ' ')
{
pos = p + 1;
break;
@@ -963,19 +964,23 @@ void RealPrepareAccept()
{
lock (_receiveProcessingLock)
{
+ if (_receiving)
+ {
+ _afterReceiveContinueWithAccept = true;
+ return;
+ }
_acceptCounter++;
_disconnecting = 0;
_clientClosedConnection = false;
}
Callback.StartAccept(_buffer, StartBufferOffset, ReceiveBufferSize);
}
- public void FinishAccept(byte[] buffer, int offset, int length, IPEndPoint remoteEndPoint, IPEndPoint localEndPoint, X509Certificate clientCertificate)
+ public void FinishAccept(byte[] buffer, int offset, int length, IPEndPoint remoteEndPoint, IPEndPoint localEndPoint)
{
ResetForNextRequest();
ReceiveBufferPos = 0;
_remoteEndPoint = remoteEndPoint;
- _clientCertificate = clientCertificate;
_knownIsLocal = false;
_remoteIpAddress = null;
_remotePort = null;
@@ -990,12 +995,27 @@ public void FinishAccept(byte[] buffer, int offset, int length, IPEndPoint remot
FinishReceive(buffer, offset, length);
}
+ public void SetRemoteCertificate(X509Certificate remoteCertificate)
+ {
+ _clientCertificate = remoteCertificate;
+ }
+
public void FinishReceive(byte[] buffer, int offset, int length)
{
+ TraceSources.CoreDebug.TraceInformation("======= Offset {0}, Length {1}", offset - StartBufferOffset, length);
if (length == -1)
{
+ lock (_receiveProcessingLock)
+ {
+ _receiving = false;
+ }
+ if (_afterReceiveContinueWithAccept)
+ {
+ _afterReceiveContinueWithAccept = false;
+ RealPrepareAccept();
+ return;
+ }
_clientClosedConnection = true;
- _receiving = false;
if (_waitingForRequest)
{
CloseConnection();
@@ -1018,14 +1038,22 @@ public void FinishReceive(byte[] buffer, int offset, int length)
}
Debug.Assert(StartBufferOffset + ReceiveBufferPos == offset || _waitingForRequest);
Debug.Assert(_receiveBufferFullness == offset);
- TraceSources.CoreDebug.TraceInformation("======= Offset {0}, Length {1}", offset - StartBufferOffset, length);
TraceSources.CoreDebug.TraceInformation(Encoding.UTF8.GetString(buffer, offset, length));
- bool startNextRecv;
+ var startNextRecv = false;
lock (_receiveProcessingLock)
{
_receiving = false;
- _receiveBufferFullness = offset + length;
- startNextRecv = ProcessReceive();
+ if (!_afterReceiveContinueWithAccept)
+ {
+ _receiveBufferFullness = offset + length;
+ startNextRecv = ProcessReceive();
+ }
+ }
+ if (_afterReceiveContinueWithAccept)
+ {
+ _afterReceiveContinueWithAccept = false;
+ RealPrepareAccept();
+ return;
}
if (startNextRecv)
{
@@ -1117,7 +1145,11 @@ bool ProcessReceive()
}
else if (_startedReceiveRequestData)
{
- _startedReceiveRequestData = _reqRespStream.ProcessDataAndShouldReadMore();
+ _startedReceiveRequestData = false;
+ if (_reqRespStream.ProcessDataAndShouldReadMore())
+ {
+ _startedReceiveRequestData = true;
+ }
}
else
{
@@ -62,11 +62,10 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
+ <Reference Include="System.Net" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Net.Http.WebRequest" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
@@ -116,11 +116,11 @@ public void ThrowAppRespond500()
[Fact]
public void AsyncThrowAppRespond500()
{
- var callCancelled = false;
+ var ev = new EventWaitHandle(false,EventResetMode.ManualReset);
var listener = CreateServer(
async env =>
{
- GetCallCancelled(env).Register(() => callCancelled = true);
+ GetCallCancelled(env).Register(() => ev.Set());
await Task.Delay(1);
throw new InvalidOperationException();
});
@@ -129,8 +129,7 @@ public void AsyncThrowAppRespond500()
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
Assert.NotNull(response.Content.Headers.ContentLength);
Assert.Equal(0, response.Content.Headers.ContentLength.Value);
- Thread.Sleep(200);
- Assert.True(callCancelled);
+ ev.WaitOne();
}
[Fact]
@@ -1359,8 +1358,8 @@ public void CommonDisconnectWaitsWithNextRequest()
{
Assert.False(insideDelay);
var disconnectAction = env.Get<Action>("common.Disconnect");
- disconnectAction();
insideDelay = true;
+ disconnectAction();
await Task.Delay(100);
insideDelay = false;
throw new Exception("disconnect");
@@ -12,16 +12,11 @@ namespace NowinTests
{
public class NowinTestsPlain : NowinTestsBase
{
- int Port { get { return 8082; } }
- protected override string HttpClientAddress
- {
- get { return "http://localhost:8082/"; }
- }
+ int Port => 8082;
- protected override string ExpectedRequestScheme
- {
- get { return "http"; }
- }
+ protected override string HttpClientAddress => "http://localhost:8082/";
+
+ protected override string ExpectedRequestScheme => "http";
protected override IDisposable CreateServer(Func<IDictionary<string, object>, Task> app)
{
@@ -39,7 +34,7 @@ public void ClosingClientConnectionDoesCancelAsyncServer()
{
var callCancelled = false;
var finished = false;
- using (var listener = CreateServer(
+ using (CreateServer(
async env =>
{
GetCallCancelled(env).Register(() => callCancelled = true);
@@ -59,8 +54,8 @@ public void ClosingClientConnectionDoesCancelAsyncServer()
using (var connStream = client.GetStream())
{
var request = Encoding.UTF8.GetBytes("GET / HTTP/1.1\r\n"
- + "Host: localhost:8080\r\n"
- + "\r\n");
+ + "Host: localhost:8080\r\n"
+ + "\r\n");
connStream.Write(request, 0, request.Length);
connStream.Flush();
}
@@ -75,7 +70,7 @@ public void ClosingClientConnectionDoesCancelAsyncServer()
public void ClosingClientConnectionDoesCancelSyncServer()
{
var callCancelled = false;
- using (var listener = CreateServer(
+ using (CreateServer(
async env =>
{
GetCallCancelled(env).Register(() => callCancelled = true);
@@ -92,8 +87,8 @@ public void ClosingClientConnectionDoesCancelSyncServer()
using (var connStream = client.GetStream())
{
var request = Encoding.UTF8.GetBytes("GET / HTTP/1.1\r\n"
- + "Host: localhost:8080\r\n"
- + "\r\n");
+ + "Host: localhost:8080\r\n"
+ + "\r\n");
connStream.Write(request, 0, request.Length);
connStream.Flush();
}

0 comments on commit ec45134

Please sign in to comment.