Пример #1
0
        public IEnumerable <object> BeginRequestInternal(ISocket socket)
        {
            var bufferHeaders = new ContinuationState <LinkedList <ArraySegment <byte> > >(socket.BufferHeaders());

            yield return(bufferHeaders);

            var headerBuffers = bufferHeaders.Result;

            Dictionary <string, object> env = new Dictionary <string, object>();

            var bodyDataReadWithHeaders = headerBuffers.Last.Value;

            headerBuffers.RemoveLast();

            var headersString = headerBuffers.GetString();
            var reader        = new StringReader(headersString);
            var requestLine   = reader.ReadRequestLine();
            var headers       = reader.ReadHeaders();

            env["Owin.RequestMethod"]  = requestLine.Verb;
            env["Owin.RequestUri"]     = requestLine.RequestUri;
            env["Owin.RequestHeaders"] = headers;
            env["Owin.BaseUri"]        = "";
            env["Owin.RemoteEndPoint"] = socket.RemoteEndPoint;
            env["Owin.RequestBody"]    = CreateReadBody(socket, bodyDataReadWithHeaders);

            // TODO provide better values
            env["Owin.ServerName"] = "";
            env["Owin.ServerPort"] = 0;
            env["Owin.UriScheme"]  = "http";

            yield return(env);
        }
Пример #2
0
        public IEnumerable<object> BeginRequestInternal(ISocket socket)
        {
            var bufferHeaders = new ContinuationState<LinkedList<ArraySegment<byte>>>(socket.BufferHeaders());
            yield return bufferHeaders;

            var headerBuffers = bufferHeaders.Result;

            Dictionary<string, object> env = new Dictionary<string, object>();

            var bodyDataReadWithHeaders = headerBuffers.Last.Value;
            headerBuffers.RemoveLast();

            var headersString = headerBuffers.GetString();
            var reader = new StringReader(headersString);
            var requestLine = reader.ReadRequestLine();
            var headers = reader.ReadHeaders();

            env["Owin.RequestMethod"] = requestLine.Verb;
            env["Owin.RequestUri"] = requestLine.RequestUri;
            env["Owin.RequestHeaders"] = headers;
            env["Owin.BaseUri"] = "";
            env["Owin.RemoteEndPoint"] = socket.RemoteEndPoint;
            env["Owin.RequestBody"] = CreateReadBody(socket, bodyDataReadWithHeaders);

            // TODO provide better values
            env["Owin.ServerName"] = "";
            env["Owin.ServerPort"] = 0;
            env["Owin.UriScheme"] = "http";

            yield return env;
        }
Пример #3
0
        static IEnumerable<object> ProcessSocketInternal(this ISocket socket, IHttpSupport http, OwinApplication application)
        {
            var beginRequest = http.BeginRequest(socket);
            yield return beginRequest;

            var request = beginRequest.Result;

            var invoke = new ContinuationState<Tuple<string, IDictionary<string, IList<string>>, IEnumerable<object>>>
                ((r, e) =>
                    application(request,
                                (s,h,b) =>
                                    r(new Tuple<string,IDictionary<string,IList<string>>,IEnumerable<object>>(s, h, b)),
                                e));

            yield return invoke;

            var response = invoke.Result;

            yield return http.BeginResponse(socket, response.Item1, response.Item2);

            foreach (var obj in response.Item3)
            {
                var objectToWrite = obj;

                if (obj is Action<Action<object>, Action<Exception>>)
                {
                    var cs = new ContinuationState<object>(obj as Action<Action<object>, Action<Exception>>);

                    yield return cs;

                    objectToWrite = cs.Result;
                }

                if (objectToWrite is FileInfo)
                {
                    yield return new ContinuationState(socket.WriteFile((objectToWrite as FileInfo).Name));
                    continue;
                }

                var chunk = default(ArraySegment<byte>);

                if (obj is ArraySegment<byte>)
                    chunk = (ArraySegment<byte>)obj;
                else if (obj is byte[])
                    chunk = new ArraySegment<byte>(obj as byte[]);
                else
                    continue;
                    //throw new ArgumentException("Invalid object of type " + obj.GetType() + " '" + obj.ToString() + "'");

                var write = socket.WriteChunk(chunk);
                yield return write;

                // TODO enumerate to completion
                if (write.Exception != null)
                    throw write.Exception;
            }

            socket.Dispose();
        }
Пример #4
0
        // this is horribly inefficient right now.
        static IEnumerable <object> BufferHeadersInternal(ISocket socket)
        {
            LinkedList <ArraySegment <byte> > result = new LinkedList <ArraySegment <byte> >();

            int bufferPosition = 0, totalBytesRead = 0;

            byte[] buffer = null;

            while (true)
            {
                if (buffer == null || bufferPosition > BufferSize / 2)
                {
                    buffer         = new byte[BufferSize];
                    bufferPosition = 0;
                }

                int bytesRead = 0;

                //Trace.Write("About to read header chunk.");
                var read = new ContinuationState <int>(socket.Read(buffer, bufferPosition, buffer.Length - bufferPosition));
                yield return(read);

                bytesRead = read.Result;

                //Trace.Write("Read {0} bytes.", bytesRead);

                result.AddLast(new ArraySegment <byte>(buffer, bufferPosition, bytesRead));

                if (bytesRead == 0)
                {
                    break;
                }

                bufferPosition += bytesRead;
                totalBytesRead += bytesRead;

                // TODO: would be nice to have a state machine and only parse once. for now
                // let's just hope to catch it on the first go-round.
                var bodyDataPosition = IndexOfAfterCRLFCRLF(result);

                if (bodyDataPosition != -1)
                {
                    var last = result.Last.Value;
                    result.RemoveLast();
                    var overlapLength = totalBytesRead - bodyDataPosition;
                    result.AddLast(new ArraySegment <byte>(last.Array, last.Offset, last.Count - overlapLength));
                    result.AddLast(new ArraySegment <byte>(last.Array, last.Offset + last.Count - overlapLength, overlapLength));
                    break;
                }

                // TODO test this
                if (totalBytesRead > MaxHeaderLength)
                {
                    throw new Exception("Request headers data exceeds max header length.");
                }
            }

            yield return(result);
        }
 public BuildingState(ContinuationState state)
 {
     State             = state;
     CurrentPropertyId = null;
     Properties        = null;
     Types             = null;
     Positions         = null;
 }
Пример #6
0
        IEnumerable <object> Nest_ResultStateTrampoline(IDisposable disposable)
        {
            using (disposable)
            {
                var state = new ContinuationState <object>((r, e) => r("result"));
                yield return(state);

                yield return(state.Result);
            }
        }
Пример #7
0
 public BuildingState(ContinuationState state)
 {
     State           = state;
     MaxPropertyId   = 0;
     CurrentProperty = null;
     Properties      = null;
     Types           = null;
     Positions       = null;
     FirstWrite      = 0;
 }
Пример #8
0
        IEnumerable <object> Nest_ExceptionStateTrampoline(IDisposable disposable)
        {
            using (disposable)
            {
                var state = new ContinuationState <object>((r, e) => e(new Exception("Nest_ExceptionState Exception")));
                yield return(state);

                yield return(state.Result);
            }
        }
Пример #9
0
        static IEnumerable<object> HostInternal(this IKayakServer server, OwinApplication application, Action<Action> trampoline)
        {
            while (true)
            {
                var accept = new ContinuationState<ISocket>((r, e) => server.GetConnection()(r));
                yield return accept;

                if (accept.Result == null)
                    break;

                accept.Result.ProcessSocket(new HttpSupport(), application, trampoline);
            }
        }
Пример #10
0
        static IEnumerable <object> WriteChunkInternal(this ISocket socket, ArraySegment <byte> chunk)
        {
            int bytesWritten = 0;

            while (bytesWritten < chunk.Count)
            {
                var write = new ContinuationState <int>(socket.Write(chunk.Array, chunk.Offset + bytesWritten, chunk.Count - bytesWritten));
                yield return(write);

                bytesWritten += write.Result;
            }

            yield return(default(Unit));
        }
Пример #11
0
        static IEnumerable<object> WriteChunkInternal(this ISocket socket, ArraySegment<byte> chunk)
        {
            int bytesWritten = 0;

            while (bytesWritten < chunk.Count)
            {
                var write = new ContinuationState<int>(socket.Write(chunk.Array, chunk.Offset + bytesWritten, chunk.Count - bytesWritten));
                yield return write;

                bytesWritten += write.Result;
            }

            yield return default(Unit);
        }
Пример #12
0
        static IEnumerable <object> HostInternal(this IKayakServer server, OwinApplication application, Action <Action> trampoline)
        {
            while (true)
            {
                var accept = new ContinuationState <ISocket>((r, e) => server.GetConnection()(r));
                yield return(accept);

                if (accept.Result == null)
                {
                    break;
                }

                accept.Result.ProcessSocket(new HttpSupport(), application, trampoline);
            }
        }
Пример #13
0
        internal void AddContinuation(
            ITestOperationState first,
            ContinuationState continuation)
        {
            first.BuildDescription(this);

            switch (continuation)
            {
            case ContinuationState.Available available:
                available.State.BuildDescription(this);
                break;

            case ContinuationState.NotAvailable notAvailable:
                this.AddStatus(notAvailable.CreationStatus, "...");
                break;
            }
        }
Пример #14
0
        private static void AsyncReplyComplete(IAsyncResult result, ContinuationState state)
        {
            try
            {
                state.Request.EndReply(result);
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                state.ChannelHandler.HandleError(e);
            }

            try
            {
                state.Reply.Close();
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                state.ChannelHandler.HandleError(e);
            }

            try
            {
                state.ChannelHandler.HandleErrorContinuation(state.Exception, state.Request, state.Channel, ref state.FaultInfo, true);
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                state.ChannelHandler.HandleError(e);
            }

            state.ChannelHandler.EnsurePump();
        }
Пример #15
0
        static IEnumerable<object> ProcessSocketInternal(this ISocket socket, IHttpSupport http, OwinApplication application)
        {
            var beginRequest = http.BeginRequest(socket);
            yield return beginRequest;

            var request = beginRequest.Result;

            var invoke = new ContinuationState<Tuple<string, IDictionary<string, IEnumerable<string>>, IEnumerable<object>>>
                ((r, e) => application(request, r, e));

            yield return invoke;

            var response = invoke.Result;

            yield return http.BeginResponse(socket, response.Item1, response.Item2);

            foreach (var obj in response.Item3)
            {
                var objectToWrite = obj;

                if (obj is Action<Action<object>, Action<Exception>>)
                {
                    var cs = new ContinuationState<object>(obj as Action<Action<object>, Action<Exception>>);

                    yield return cs;

                    objectToWrite = cs.Result;
                }

                if (objectToWrite is FileInfo)
                {
                    yield return new ContinuationState(socket.WriteFile((objectToWrite as FileInfo).Name));
                }
                var write = socket.WriteFileOrData(objectToWrite);
                yield return write;

                if (write.Exception != null)
                    throw write.Exception;
            }

            // HTTP/1.1 support might only close the connection if client wants to
            //Trace.Write("Closed connection.");
            socket.Dispose();
        }
Пример #16
0
 IEnumerable<object> Nest_ExceptionStateTrampoline(IDisposable disposable)
 {
     using (disposable)
     {
         var state = new ContinuationState<object>((r, e) => e(new Exception("Nest_ExceptionState Exception")));
         yield return state;
         yield return state.Result;
     }
 }
Пример #17
0
        private void ProvideFaultAndReplyFailure(RequestContext request, Exception exception, ref ErrorHandlerFaultInfo faultInfo, out bool replied, out bool replySentAsync)
        {
            replied        = false;
            replySentAsync = false;
            bool requestMessageIsFault = false;

            try
            {
                requestMessageIsFault = request.RequestMessage.IsFault;
            }
#pragma warning suppress 56500 // covered by FxCOP
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }
                // do not propagate non-fatal exceptions
            }

            bool enableFaults = false;
            if (_listener != null)
            {
                enableFaults = _listener.ChannelDispatcher.EnableFaults;
            }
            else if (_channel != null && _channel.IsClient)
            {
                enableFaults = _channel.ClientRuntime.EnableFaults;
            }

            if ((!requestMessageIsFault) && enableFaults)
            {
                this.ProvideFault(exception, ref faultInfo);
                if (faultInfo.Fault != null)
                {
                    Message reply = faultInfo.Fault;
                    try
                    {
                        try
                        {
                            if (this.PrepareReply(request, reply))
                            {
                                if (_sendAsynchronously)
                                {
                                    var state = new ContinuationState {
                                        ChannelHandler = this, Channel = _channel, Exception = exception, FaultInfo = faultInfo, Request = request, Reply = reply
                                    };
                                    var result = request.BeginReply(reply, ChannelHandler.s_onAsyncReplyComplete, state);
                                    if (result.CompletedSynchronously)
                                    {
                                        ChannelHandler.AsyncReplyComplete(result, state);
                                        replied = true;
                                    }
                                    else
                                    {
                                        replySentAsync = true;
                                    }
                                }
                                else
                                {
                                    request.Reply(reply);
                                    replied = true;
                                }
                            }
                        }
                        finally
                        {
                            if (!replySentAsync)
                            {
                                reply.Close();
                            }
                        }
                    }
#pragma warning suppress 56500 // covered by FxCOP
                    catch (Exception e)
                    {
                        if (Fx.IsFatal(e))
                        {
                            throw;
                        }
                        this.HandleError(e);
                    }
                }
            }
        }
Пример #18
0
        static void AsyncReplyComplete(IAsyncResult result, ContinuationState state)
        {
            try
            {
                state.Request.EndReply(result);
            }
            catch (Exception e)
            {
                DiagnosticUtility.TraceHandledException(e, System.Diagnostics.TraceEventType.Error);

                if (Fx.IsFatal(e))
                {
                    throw;
                }
                
                state.ChannelHandler.HandleError(e);
            }

            try
            {
                state.Reply.Close();
            }
            catch (Exception e)
            {
                DiagnosticUtility.TraceHandledException(e, System.Diagnostics.TraceEventType.Error);

                if (Fx.IsFatal(e))
                {
                    throw;
                }

                state.ChannelHandler.HandleError(e);
            }

            try
            {
                state.ChannelHandler.HandleErrorContinuation(state.Exception, state.Request, state.Channel, ref state.FaultInfo, true);
            }
            catch (Exception e)
            {
                DiagnosticUtility.TraceHandledException(e, System.Diagnostics.TraceEventType.Error);

                if (Fx.IsFatal(e))
                {
                    throw;
                }

                state.ChannelHandler.HandleError(e);
            }

            state.ChannelHandler.EnsurePump();
        }
Пример #19
0
        void ProvideFaultAndReplyFailure(RequestContext request, Exception exception, ref ErrorHandlerFaultInfo faultInfo, out bool replied, out bool replySentAsync)
        {
            replied = false;
            replySentAsync = false;
            bool requestMessageIsFault = false;
            try
            {
                requestMessageIsFault = request.RequestMessage.IsFault;
            }
#pragma warning suppress 56500 // covered by FxCOP
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }
                // ---- it
            }

            bool enableFaults = false;
            if (this.listener != null)
            {
                enableFaults = this.listener.ChannelDispatcher.EnableFaults;
            }
            else if (this.channel != null && this.channel.IsClient)
            {
                enableFaults = this.channel.ClientRuntime.EnableFaults;
            }

            if ((!requestMessageIsFault) && enableFaults)
            {
                this.ProvideFault(exception, ref faultInfo);
                if (faultInfo.Fault != null)
                {
                    Message reply = faultInfo.Fault;
                    try
                    {
                        try
                        {
                            if (this.PrepareReply(request, reply))
                            {
                                if (this.sendAsynchronously)
                                {
                                    var state = new ContinuationState { ChannelHandler = this, Channel = channel, Exception = exception, FaultInfo = faultInfo, Request = request, Reply = reply };
                                    var result = request.BeginReply(reply, ChannelHandler.onAsyncReplyComplete, state);
                                    if (result.CompletedSynchronously)
                                    {
                                        ChannelHandler.AsyncReplyComplete(result, state);
                                        replied = true;
                                    }
                                    else
                                    {
                                        replySentAsync = true;
                                    }
                                }
                                else
                                {
                                    request.Reply(reply);
                                    replied = true;
                                }
                            }
                        }
                        finally
                        {
                            if (!replySentAsync)
                            {
                                reply.Close();
                            }
                        }
                    }
#pragma warning suppress 56500 // covered by FxCOP
                    catch (Exception e)
                    {
                        if (Fx.IsFatal(e))
                        {
                            throw;
                        }
                        this.HandleError(e);
                    }
                }
            }
        }
Пример #20
0
        static IEnumerable <object> ProcessSocketInternal(this ISocket socket, IHttpSupport http, OwinApplication application)
        {
            var beginRequest = http.BeginRequest(socket);

            yield return(beginRequest);

            var request = beginRequest.Result;

            var invoke = new ContinuationState <Tuple <string, IDictionary <string, IList <string> >, IEnumerable <object> > >
                             ((r, e) =>
                             application(request,
                                         (s, h, b) =>
                                         r(new Tuple <string, IDictionary <string, IList <string> >, IEnumerable <object> >(s, h, b)),
                                         e));

            yield return(invoke);

            var response = invoke.Result;

            yield return(http.BeginResponse(socket, response.Item1, response.Item2));

            foreach (var obj in response.Item3)
            {
                var objectToWrite = obj;

                if (obj is Action <Action <object>, Action <Exception> > )
                {
                    var cs = new ContinuationState <object>(obj as Action <Action <object>, Action <Exception> >);

                    yield return(cs);

                    objectToWrite = cs.Result;
                }

                if (objectToWrite is FileInfo)
                {
                    yield return(new ContinuationState(socket.WriteFile((objectToWrite as FileInfo).Name)));

                    continue;
                }

                var chunk = default(ArraySegment <byte>);

                if (objectToWrite is ArraySegment <byte> )
                {
                    chunk = (ArraySegment <byte>)objectToWrite;
                }
                else if (objectToWrite is byte[])
                {
                    chunk = new ArraySegment <byte>(objectToWrite as byte[]);
                }
                else
                {
                    continue;
                }
                //throw new ArgumentException("Invalid object of type " + obj.GetType() + " '" + obj.ToString() + "'");

                var write = socket.WriteChunk(chunk);
                yield return(write);

                // TODO enumerate to completion
                if (write.Exception != null)
                {
                    throw write.Exception;
                }
            }

            socket.Dispose();
        }
Пример #21
0
 IEnumerable<object> Nest_ResultStateTrampoline(IDisposable disposable)
 {
     using (disposable)
     {
         var state = new ContinuationState<object>((r, e) => r("result"));
         yield return state;
         yield return state.Result;
     }
 }
 private void ThrowIllegalStateException(ContinuationState state, string realOperation)
 {
     throw new InvalidOperationException($"Cannot perform {realOperation} when encountered the {state} state");
 }
Пример #23
0
        // this is horribly inefficient right now.
        static IEnumerable<object> BufferHeadersInternal(ISocket socket)
        {
            LinkedList<ArraySegment<byte>> result = new LinkedList<ArraySegment<byte>>();

            int bufferPosition = 0, totalBytesRead = 0;
            byte[] buffer = null;

            while (true)
            {
                if (buffer == null || bufferPosition > BufferSize / 2)
                {
                    buffer = new byte[BufferSize];
                    bufferPosition = 0;
                }

                int bytesRead = 0;

                //Trace.Write("About to read header chunk.");
                var read = new ContinuationState<int>(socket.Read(buffer, bufferPosition, buffer.Length - bufferPosition));
                yield return read;

                bytesRead = read.Result;

                //Trace.Write("Read {0} bytes.", bytesRead);

                result.AddLast(new ArraySegment<byte>(buffer, bufferPosition, bytesRead));

                if (bytesRead == 0)
                    break;

                bufferPosition += bytesRead;
                totalBytesRead += bytesRead;

                // TODO: would be nice to have a state machine and only parse once. for now
                // let's just hope to catch it on the first go-round.
                var bodyDataPosition = IndexOfAfterCRLFCRLF(result);

                if (bodyDataPosition != -1)
                {
                    var last = result.Last.Value;
                    result.RemoveLast();
                    var overlapLength = totalBytesRead - bodyDataPosition;
                    result.AddLast(new ArraySegment<byte>(last.Array, last.Offset, last.Count - overlapLength));
                    result.AddLast(new ArraySegment<byte>(last.Array, last.Offset + last.Count - overlapLength, overlapLength));
                    break;
                }

                // TODO test this
                if (totalBytesRead > MaxHeaderLength)
                    throw new Exception("Request headers data exceeds max header length.");
            }

            yield return result;
        }
Пример #24
0
        private static void AsyncReplyComplete(IAsyncResult result, ContinuationState state)
        {
            try
            {
                state.Request.EndReply(result);
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                state.ChannelHandler.HandleError(e);
            }

            try
            {
                state.Reply.Close();
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                state.ChannelHandler.HandleError(e);
            }

            try
            {
                state.ChannelHandler.HandleErrorContinuation(state.Exception, state.Request, state.Channel, ref state.FaultInfo, true);
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                state.ChannelHandler.HandleError(e);
            }

            state.ChannelHandler.EnsurePump();
        }
Пример #25
0
 static ContinuationState <int> ReadAsync(this Stream stream, byte[] buffer, int offset, int count)
 {
     return(ContinuationState.FromAsync <int>(
                (cb, s) => stream.BeginRead(buffer, offset, count, cb, s),
                stream.EndRead));
 }