예제 #1
0
        public Task WriteAsync(Span <byte> data)
        {
            if (!HasStarted)
            {
                WriteBeginResponseHeaders();
            }

            if (_autoChunk)
            {
                _outputFormatter.Append(data.Length, Format.Parsed.HexLowercase);
                _outputFormatter.Write(data);
                _outputFormatter.Write(_endChunkBytes);
            }
            else
            {
                _outputFormatter.Write(data);
            }

            return(_outputFormatter.FlushAsync());
        }
예제 #2
0
        public void CopyTo(bool chunk, WritableChannelFormatter outputFormatter)
        {
            foreach (var header in _headers)
            {
                outputFormatter.Write(_headersStartBytes);
                outputFormatter.Append(header.Key);
                outputFormatter.Write(_headersSeperatorBytes);
                outputFormatter.Append(header.Value.ToString());
            }

            if (chunk)
            {
                outputFormatter.Write(_chunkedHeaderBytes);
            }

            outputFormatter.Write(_serverHeaderBytes);
            var date = _dateHeaderValueManager.GetDateHeaderValues().Bytes;

            outputFormatter.Write(date);

            outputFormatter.Write(_headersEndBytes);
        }
예제 #3
0
        public async Task ProcessAllRequests()
        {
            Reset();

            while (true)
            {
                var buffer = await _input.ReadAsync();

                try
                {
                    if (buffer.IsEmpty && _input.Reading.IsCompleted)
                    {
                        // We're done with this connection
                        return;
                    }
                    Console.WriteLine($"Read: {buffer.Length} bytes");
                    Console.WriteLine(BitConverter.ToString(buffer.ToArray()));
                    Console.WriteLine(buffer.GetAsciiString());
                    var result = _parser.ParseRequest(ref buffer);
                    Console.WriteLine($"Result: {result}");
                    switch (result)
                    {
                        case HttpRequestParser.ParseResult.Incomplete:
                            if (_input.Reading.IsCompleted)
                            {
                                // Didn't get the whole request and the connection ended
                                throw new EndOfStreamException();
                            }
                            // Need more data
                            continue;
                        case HttpRequestParser.ParseResult.Complete:
                            // Done
                            break;
                        case HttpRequestParser.ParseResult.BadRequest:
                            // TODO: Don't throw here;
                            throw new Exception();
                        default:
                            break;
                    }

                }
                catch (Exception)
                {
                    StatusCode = 400;

                    await EndResponse();

                    return;
                }
                finally
                {
                    _input.Advance(buffer.Start, buffer.End);
                }

                var context = _application.CreateContext(this);

                try
                {
                    if (!_isHttp2 && RequestHeaders.ContainsKey("Upgrade") && TryUpgradeToHttp2())
                    {
                        _outputFormatter.Write(_http2SwitchBytes);
                        _isHttp2 = true;

                        /*
                         The first HTTP/2 frame sent by the server MUST be a server connection
                         preface (Section 3.5) consisting of a SETTINGS frame (Section 6.5).
                        */
                        _outputFormatter.Write(_emptySettingsFrame);


                        await _outputFormatter.FlushAsync();
                    }

                    await _application.ProcessRequestAsync(context);
                }
                catch (Exception ex)
                {
                    StatusCode = 500;

                    _application.DisposeContext(context, ex);
                }
                finally
                {
                    await EndResponse();
                }

                if (!KeepAlive)
                {
                    break;
                }

                Reset();
            }
        }