Exemplo n.º 1
0
        private static void FormatRequestAndValidate(HttpRequestMessage request, string expected)
        {
            var buffer        = new byte[8192];
            var result        = HttpFormatter.FormatRequest(request, buffer);
            var decodedString = Encoding.UTF8.GetString(buffer, 0, result);

            Assert.Equal(expected, decodedString);
        }
Exemplo n.º 2
0
        private void ProcessRequest(BufferSegment buffer, bool isCompleted)
        {
            Logger.Debug("Request received (isCompleted = {isCompleted}), length = {length}",
                         isCompleted, buffer.Length);

            var headerLength = HttpFormatter.ParseRequest(buffer, out var request);

            Logger.Trace("Request: {@request}", request);

            var stream = new BufferQueueStream(_socket.BufferPool);

            request.Body = stream;

            stream.PushBuffer(new ArraySegment <byte>(buffer.Buffer, buffer.Offset + headerLength,
                                                      buffer.Length - headerLength));

            var requestId = int.Parse(request.Headers[MazeHeaders.MazeSocketRequestIdHeader]);
            var cancellationTokenSource = _cancellableRequests.GetOrAdd(requestId, i => new CancellationTokenSource());
            var token = cancellationTokenSource.Token;

            if (token.IsCancellationRequested)
            {
                cancellationTokenSource.Dispose();
                _cancellableRequests.TryRemove(requestId, out _);
                return;
            }

            if (isCompleted)
            {
                stream.IsCompleted = true;
            }
            else
            {
                if (_activeRequests.TryAdd(requestId, stream))
                {
                    Logger.Debug("Added request {requestId} to active requests", requestId);
                }
                else
                {
                    Logger.Error(
                        "Adding the request {requestId} to the active requests failed because it already exists.",
                        requestId);
                    throw new InvalidOperationException("The request already exists, duplicate request id deteceted.");
                }
            }

            var response = new DefaultMazeResponse(requestId);

            response.Headers.Add(MazeHeaders.MazeSocketRequestIdHeader, requestId.ToString());

            var rawStream = new HttpResponseStream(response, request, _socket, _packageBufferSize, _maxHeaderSize,
                                                   _bufferPool, token);

            response.HttpResponseStream = rawStream;
            response.Body = new BufferingWriteStream(rawStream, _packageBufferSize, _bufferPool);

            LogTaskError(Task.Run(() => RequestReceived?.Invoke(this, new MazeRequestReceivedEventArgs(request, response, token))));
        }
Exemplo n.º 3
0
        public static HttpResponseMessage DecodeResponse(string commandResultBase64)
        {
            var binary = Convert.FromBase64String(commandResultBase64);

            var length = HttpFormatter.ParseResponse(new ArraySegment <byte>(binary), out var response, out var contentHeaders);

            if (binary.Length > length)
            {
                response.Content = new ByteArrayContent(binary, length, binary.Length - length);
                foreach (var contentHeader in contentHeaders)
                {
                    response.Content.Headers.Add(contentHeader.Key, (IEnumerable <string>)contentHeader.Value);
                }
            }

            return(response);
        }
Exemplo n.º 4
0
        private void ProcessResponse(BufferSegment buffer, bool isCompleted)
        {
            Logger.LogDataPackage("Received Response", buffer.Buffer, buffer.Offset, buffer.Length);

            var headerLength  = HttpFormatter.ParseResponse(buffer, out var response, out var contentHeaders);
            var requestId     = int.Parse(response.Headers.GetValues(MazeHeaders.MazeSocketRequestIdHeader).Single());
            var bufferSegment =
                new ArraySegment <byte>(buffer.Buffer, buffer.Offset + headerLength, buffer.Length - headerLength);

            if (isCompleted)
            {
                response.Content = new RawStreamContent(new ArrayPoolMemoryStream(bufferSegment, _socket.BufferPool));
            }
            else
            {
                var stream = new BufferQueueStream(_socket.BufferPool);
                stream.PushBuffer(bufferSegment);
                if (_activeResponses.TryAdd(requestId, stream))
                {
                    Logger.Debug("Added response {requestId} to active responses", requestId);
                }
                else
                {
                    Logger.Error(
                        "Adding the response {requestId} to the active response failed because it already exists.",
                        requestId);
                    throw new InvalidOperationException("The response already exists, duplicate response id deteceted.");
                }

                response.Content = new RawStreamContent(stream);
            }

            foreach (var contentHeader in contentHeaders)
            {
                response.Content.Headers.Add(contentHeader.Key, (IEnumerable <string>)contentHeader.Value);
            }

            if (!_waitingRequests.TryRemove(requestId, out var taskCompletionSource))
            {
                Logger.Error("No TaskCompletionSource for request {requestId} found.", requestId);
                response.Dispose();
                return;
            }

            taskCompletionSource.SetResult(response);
        }
Exemplo n.º 5
0
        static async Task MainAsync(CancellationToken cancellationToken)
        {
            var function = new Function();

            function.PrepareFunctionContext();

            System.Diagnostics.Debug.WriteLine("C# AfterBurn running.");

            var httpFormatter = new HttpFormatter();
            var stdin         = Console.OpenStandardInput();

            using (TextReader reader = new StreamReader(stdin))
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    HeaderParser parser = new HeaderParser();
                    var          header = parser.Parse(reader);

                    foreach (string v in header.HttpHeaders)
                    {
                        System.Diagnostics.Debug.WriteLine(v + "=" + header.HttpHeaders[v]);
                    }

                    System.Diagnostics.Debug.WriteLine("Content-Length: " + header.ContentLength);

                    BodyParser bodyParser = new BodyParser();
                    string     body       = String.Empty;
                    if (header.ContentLength > 0)
                    {
                        body = bodyParser.Parse(reader, header.ContentLength);

                        System.Diagnostics.Debug.WriteLine(body);
                    }

                    await function.Invoke(body, cancellationToken);

                    var httpAdded = httpFormatter.Format("");
                    Console.WriteLine(httpAdded);
                }
            }
        }
        static void Main(string[] args)
        {
            var function = new Function.Handler();

            System.Diagnostics.Debug.WriteLine("C# AfterBurn running.");

            var httpFormatter = new HttpFormatter();
            var stdin         = Console.OpenStandardInput();

            using (TextReader reader = new StreamReader(stdin)) {
                while (true)
                {
                    HeaderParser parser = new HeaderParser();
                    var          header = parser.Parse(reader);

                    foreach (string v in header.HttpHeaders)
                    {
                        System.Diagnostics.Debug.WriteLine(v + "=" + header.HttpHeaders[v]);
                    }

                    System.Diagnostics.Debug.WriteLine("Content-Length: " + header.ContentLength);

                    BodyParser bodyParser = new BodyParser();
                    char[]     body       = new char[0] {
                    };
                    if (header.ContentLength > 0)
                    {
                        body = bodyParser.Parse(reader, header.ContentLength);

                        System.Diagnostics.Debug.WriteLine(body);
                    }

                    var httpAdded = httpFormatter.Format(function.Invoke(body));
                    Console.WriteLine(httpAdded);
                }
            }
        }
Exemplo n.º 7
0
        public async Task <HttpResponseMessage> SendRequest(HttpRequestMessage requestMessage,
                                                            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (requestMessage.Headers.Contains(MazeHeaders.MazeSocketRequestIdHeader))
            {
                throw new ArgumentException(
                          $"The maze request must not have a {MazeHeaders.MazeSocketRequestIdHeader} header.",
                          nameof(requestMessage));
            }

            var requestId = Interlocked.Increment(ref _requestCounter);

            requestMessage.Headers.Add(MazeHeaders.MazeSocketRequestIdHeader, requestId.ToString());

            var requestWaiter = new TaskCompletionSource <HttpResponseMessage>();

            _waitingRequests.TryAdd(requestId, requestWaiter);

            using (var sendBuffer = AllocateBuffer(_packageBufferSize))
            {
                var headerLength  = HttpFormatter.FormatRequest(requestMessage, sendBuffer);
                var maxReadLength = sendBuffer.Length - headerLength;
                var opCode        = MazeSocket.MessageOpcode.Request;

                Stream bodyStream;
                if (requestMessage.Content != null)
                {
                    bodyStream = await requestMessage.Content.ReadAsStreamAsync();
                }
                else
                {
                    bodyStream = null;
                }

                using (bodyStream)
                {
                    int read;

                    if (bodyStream == null) //no body, single package, easy
                    {
                        opCode = MazeSocket.MessageOpcode.RequestSinglePackage;
                        read   = 0;
                    }
                    else
                    {
                        //read something
                        var readOffset = sendBuffer.Offset + headerLength;
                        read = await bodyStream.ReadAsync(sendBuffer.Buffer, readOffset, maxReadLength,
                                                          cancellationToken);

                        if (read < maxReadLength)
                        {
                            if (read == 0)
                            {
                                //no data in the stream
                                opCode = MazeSocket.MessageOpcode.RequestSinglePackage;
                            }
                            else
                            {
                                //we read less than requested. check if we already reached the end
                                readOffset += read;
                                var read2 = await bodyStream.ReadAsync(sendBuffer.Buffer, readOffset,
                                                                       maxReadLength - read, cancellationToken);

                                if (read2 == 0)
                                {
                                    opCode = MazeSocket.MessageOpcode.RequestSinglePackage;
                                }
                                else
                                {
                                    read += read2;
                                }
                            }
                        }
                    }

                    cancellationToken
                    .ThrowIfCancellationRequested();     //last chance without having to send a cancel package

                    try
                    {
                        await _socket.SendFrameAsync(opCode,
                                                     new ArraySegment <byte>(sendBuffer.Buffer, sendBuffer.Offset, read + headerLength),
                                                     bufferHasRequiredLength : true, cancellationToken);

                        if (opCode == MazeSocket.MessageOpcode.Request)
                        {
                            BinaryUtils.WriteInt32(sendBuffer.Buffer, sendBuffer.Offset, requestId);
                            opCode        = MazeSocket.MessageOpcode.RequestContinuation;
                            maxReadLength = sendBuffer.Length - 4;

                            while (true)
                            {
                                var readOffset = sendBuffer.Offset + 4; //4 for the request id
                                read = await bodyStream.ReadAsync(sendBuffer.Buffer, readOffset, maxReadLength,
                                                                  cancellationToken);

                                if (read == 0)
                                {
                                    opCode = MazeSocket.MessageOpcode.RequestContinuationFinished;
                                }
                                else if (read < maxReadLength)
                                {
                                    var read2 = await bodyStream.ReadAsync(sendBuffer.Buffer, readOffset + read,
                                                                           maxReadLength - read, cancellationToken);

                                    if (read2 == 0)
                                    {
                                        opCode = MazeSocket.MessageOpcode.RequestContinuationFinished;
                                    }
                                    else
                                    {
                                        read += read2;
                                    }
                                }

                                await _socket.SendFrameAsync(opCode,
                                                             new ArraySegment <byte>(sendBuffer.Buffer, sendBuffer.Offset, 4 + read),
                                                             bufferHasRequiredLength : true, cancellationToken);

                                if (opCode == MazeSocket.MessageOpcode.RequestContinuationFinished)
                                {
                                    break;
                                }
                            }
                        }
                    }
                    catch (Exception)
                    {
                        BinaryUtils.WriteInt32(sendBuffer.Buffer, sendBuffer.Offset, requestId);
                        await _socket.SendFrameAsync(MazeSocket.MessageOpcode.CancelRequest,
                                                     new ArraySegment <byte>(sendBuffer.Buffer, sendBuffer.Offset, 4),
                                                     bufferHasRequiredLength : true, CancellationToken.None); //DO NOT USE THE CANCELLATION TOKEN HERE

                        throw;
                    }
                }

                cancellationToken.Register(() =>
                {
                    using (var buffer = AllocateBuffer(4))
                    {
                        BinaryUtils.WriteInt32(buffer.Buffer, buffer.Offset, requestId);
                        _socket.SendFrameAsync(MazeSocket.MessageOpcode.CancelRequest,
                                               new ArraySegment <byte>(buffer.Buffer, buffer.Offset, 4), bufferHasRequiredLength: true,
                                               CancellationToken.None).Wait();
                    }

                    requestWaiter.TrySetCanceled();
                });

                return(await requestWaiter.Task);
            }
        }