protected virtual void ProcessRequest(TcpConnection socket) { Log.LogVerbose("Processing Request"); var requestBuffer = ArrayPool<byte>.Shared.Rent(RequestBufferSize); var requestByteCount = socket.Receive(requestBuffer); if(requestByteCount == 0) { socket.Close(); return; } var requestBytes = requestBuffer.Slice(0, requestByteCount); var request = HttpRequest.Parse(requestBytes); Log.LogRequest(request); var formatter = new BufferFormatter(1024, FormattingData.InvariantUtf8); WriteResponse(formatter, request); ArrayPool<byte>.Shared.Return(requestBuffer); var response = formatter.Buffer.Slice(0, formatter.CommitedByteCount); Console.WriteLine("Response:"); Console.WriteLine(new Utf8String(response)); socket.Send(response); socket.Close(); if (Log.IsVerbose) { Log.LogMessage(Log.Level.Verbose, "Request Processed and Response Sent", DateTime.UtcNow.Ticks); } }
protected virtual void ProcessRequest(TcpConnection socket) { Log.LogVerbose("Processing Request"); var requestBuffer = ManagedBufferPool<byte>.SharedByteBufferPool.RentBuffer(RequestBufferSize); var requestByteCount = socket.Receive(requestBuffer); if(requestByteCount == 0) { socket.Close(); return; } var requestBytes = requestBuffer.Slice(0, requestByteCount); var request = HttpRequest.Parse(requestBytes); Log.LogRequest(request); var formatter = new BufferFormatter(1024, FormattingData.InvariantUtf8); WriteResponse(formatter, request); ManagedBufferPool<byte>.SharedByteBufferPool.ReturnBuffer(ref requestBuffer); socket.Send(formatter.Buffer.Slice(formatter.CommitedByteCount)); socket.Close(); if (Log.IsVerbose) { Log.LogMessage(Log.Level.Verbose, "Request Processed", DateTime.UtcNow.Ticks); } }
static void WriteResponseForGetTime(BufferFormatter formatter, HttpRequestLine request) { // TODO: this needs to not allocate var body = string.Format(@"<html><head><title>Time</title></head><body>{0}</body></html>", DateTime.UtcNow.ToString("O")); WriteCommonHeaders(formatter, "1.1", "200", "Ok", keepAlive: false); // TOOD: this needs to not allocate formatter.WriteHttpHeader(new Utf8String("Content-Length"), new Utf8String(body.Length.ToString())); formatter.EndHttpHeaderSection(); formatter.WriteHttpBody(new Utf8String(body)); }
private static void WriteResponseForHelloWorld(BufferFormatter formatter) { formatter.WriteHttpStatusLine(new Utf8String("1.1"), new Utf8String("200"), new Utf8String("Ok")); formatter.WriteHttpHeader(new Utf8String("Content-Length"), new Utf8String("12")); formatter.WriteHttpHeader(new Utf8String("Content-Type"), new Utf8String("text/plain; charset=UTF-8")); formatter.WriteHttpHeader(new Utf8String("Server"), new Utf8String(".NET Core Sample Serve")); // TODO: this needs to not allocate formatter.WriteHttpHeader(new Utf8String("Date"), new Utf8String(DateTime.UtcNow.ToString("R"))); formatter.EndHttpHeaderSection(); formatter.WriteHttpBody(new Utf8String("Hello, World")); }
static HttpServerBuffer CreateResponseForGetTime(HttpRequestLine request) { var formatter = new BufferFormatter(1024, FormattingData.InvariantUtf8); WriteCommonHeaders(formatter, @"HTTP/1.1 200 OK", request.IsKeepAlive()); formatter.Append(HttpNewline); formatter.Append(@"<html><head><title>Time</title></head><body>"); formatter.Append(DateTime.UtcNow, 'O'); formatter.Append(@"</body></html>"); return new HttpServerBuffer(formatter.Buffer, formatter.CommitedByteCount, BufferPool.Shared); }
private static HttpServerBuffer CreateResponseForHelloWorld() { var formatter = new BufferFormatter(1024, FormattingData.InvariantUtf8); formatter.WriteHttpStatusLine(new Utf8String("1.1"), new Utf8String("200"), new Utf8String("Ok")); formatter.WriteHttpHeader(new Utf8String("Content-Length"), new Utf8String("12")); formatter.WriteHttpHeader(new Utf8String("Content-Type"), new Utf8String("text/plain; charset=UTF-8")); formatter.WriteHttpHeader(new Utf8String("Server"), new Utf8String(".NET Core Sample Serve")); formatter.WriteHttpHeader(new Utf8String("Date"), new Utf8String(DateTime.UtcNow.ToString("R"))); formatter.EndHttpHeaderSection(); formatter.WriteHttpBody(new Utf8String("Hello, World")); return new HttpServerBuffer(formatter.Buffer, formatter.CommitedByteCount, BufferPool.Shared); }
static HttpServerBuffer CreateResponseForGetTime(HttpRequestLine request) { var body = string.Format(@"<html><head><title>Time</title></head><body>{0}</body></html>", DateTime.UtcNow.ToString("O")); var formatter = new BufferFormatter(1024, FormattingData.InvariantUtf8); WriteCommonHeaders(formatter, "1.1", "200", "Ok", request.IsKeepAlive()); formatter.WriteHttpHeader(new Utf8String("Content-Length"), new Utf8String(body.Length.ToString())); formatter.EndHttpHeaderSection(); formatter.WriteHttpBody(new Utf8String(body)); return new HttpServerBuffer(formatter.Buffer, formatter.CommitedByteCount, BufferPool.Shared); }
static void ProcessRequest(TcpClient socket) { HttpServer.Listen(socket, (request) => { if (request.RequestUri.Equals(new Utf8String("/plaintext"))) { var formatter = new BufferFormatter(1024, FormattingData.InvariantUtf8); HttpWriter.WriteCommonHeaders(formatter, "HTTP/1.1 200 OK"); formatter.Append("Hello, World!"); socket.Write(formatter); socket.Dispose(); } }); }
static void RunLoop(bool log) { var loop = new UVLoop(); var listener = new TcpListener(s_ipAddress, s_port, loop); var formatter = new BufferFormatter(512, FormattingData.InvariantUtf8); listener.ConnectionAccepted += (Tcp connection) => { if (log) { Console.WriteLine("connection accepted"); } connection.ReadCompleted += (ByteSpan data) => { if (log) { unsafe { var requestString = new Utf8String(data.UnsafeBuffer, data.Length); Console.WriteLine("*REQUEST:\n {0}", requestString.ToString()); } } formatter.Clear(); formatter.Append("HTTP/1.1 200 OK"); formatter.Append("\r\n\r\n"); formatter.Append("Hello World!"); if (log) { formatter.Format(" @ {0:O}", DateTime.UtcNow); } var response = formatter.Buffer.Slice(0, formatter.CommitedByteCount); // formatter should have a property for written bytes GCHandle gcHandle; var byteSpan = response.Pin(out gcHandle); connection.TryWrite(byteSpan); connection.Dispose(); gcHandle.Free(); // TODO: formatter should format to ByteSpan, to avoid pinning }; connection.ReadStart(); }; listener.Listen(); loop.Run(); }
protected override void WriteResponse(BufferFormatter formatter, HttpRequest request) { var api = Apis.Map(request.RequestLine); switch (api) { case Api.HelloWorld: WriteResponseForHelloWorld(formatter); break; case Api.GetTime: WriteResponseForGetTime(formatter, request.RequestLine); break; default: // TODO: this should be built into the base class WriteResponseFor404(formatter, request.RequestLine); break; } }
private HttpServerBuffer CreateResponseForHelloWorld() { var formatter = new BufferFormatter(1024, FormattingData.InvariantUtf8); formatter.Append(@"HTTP/1.1 200 OK"); formatter.Append(HttpNewline); formatter.Append("Content-Length: 12"); formatter.Append(HttpNewline); formatter.Append("Content-Type: text/plain; charset=UTF-8"); formatter.Append(HttpNewline); formatter.Append("Server: .NET Core Sample Server"); formatter.Append(HttpNewline); formatter.Append("Date: "); formatter.Append(DateTime.UtcNow, 'R'); formatter.Append(HttpNewline); formatter.Append(HttpNewline); formatter.Append("Hello, World"); return new HttpServerBuffer(formatter.Buffer, formatter.CommitedByteCount, BufferPool.Shared); }
public static void WriteCommonHeaders(BufferFormatter formatter, string responseLine) { var currentTime = DateTime.UtcNow; formatter.Append(responseLine); formatter.Append(HttpNewline); formatter.Append("Date: "); formatter.Append(currentTime, 'R'); formatter.Append(HttpNewline); formatter.Append("Server: .NET Core Sample Server"); formatter.Append(HttpNewline); formatter.Append("Last-Modified: "); formatter.Append(currentTime, 'R'); formatter.Append(HttpNewline); formatter.Append("Content-Type: text/html; charset=UTF-8"); formatter.Append(HttpNewline); formatter.Append("Connection: close"); formatter.Append(HttpNewline); formatter.Append(HttpNewline); }
// This method is a bit of a mess. We need to fix many Http and Json APIs void WriteResponseForPostJson(BufferFormatter formatter, HttpRequestLine requestLine, ReadOnlySpan<byte> body) { Console.WriteLine(new Utf8String(body)); uint requestedCount = ReadCountUsingReader(body).GetValueOrDefault(1); //uint requestedCount = ReadCountUsingNonAllocatingDom(body).GetValueOrDefault(1); // TODO: this needs to be written directly to the buffer after content length reservation is implemented. var buffer = ArrayPool<byte>.Shared.Rent(2048); var spanFormatter = new SpanFormatter(buffer.Slice(), FormattingData.InvariantUtf8); var json = new JsonWriter<SpanFormatter>(spanFormatter, prettyPrint: true); json.WriteObjectStart(); json.WriteArrayStart(); for (int i = 0; i < requestedCount; i++) { json.WriteString(DateTime.UtcNow.ToString()); // TODO: this needs to not allocate. } json.WriteArrayEnd(); ; json.WriteObjectEnd(); var responseBodyText = new Utf8String(buffer, 0, spanFormatter.CommitedByteCount); formatter.AppendHttpStatusLine(HttpVersion.V1_1, 200, new Utf8String("OK")); formatter.Append(new Utf8String("Content-Length : ")); formatter.Append(responseBodyText.Length); formatter.AppendHttpNewLine(); formatter.Append("Content-Type : text/plain; charset=UTF-8"); formatter.AppendHttpNewLine(); formatter.Append("Server : .NET Core Sample Serve"); formatter.AppendHttpNewLine(); formatter.Append(new Utf8String("Date : ")); formatter.Append(DateTime.UtcNow.ToString("R")); formatter.AppendHttpNewLine(); formatter.AppendHttpNewLine(); formatter.Append(responseBodyText); ArrayPool<byte>.Shared.Return(buffer); }
public void WriteHttpHeader_resizes_the_buffer_taking_into_consideration_the_reserver() { _formatter = new BufferFormatter(32, FormattingData.InvariantUtf8, ArrayPool<byte>.Shared); var httpHeaderBuffer = _formatter.WriteHttpHeader(GetUtf8EncodedString("Connection"), GetUtf8EncodedString("close")); httpHeaderBuffer.UpdateValue("18446744073709551615"); var result = _formatter.Buffer; result.Should().ContainInOrder(Utf8Encoding.GetBytes("Connection : 18446744073709551615\r\n")); }
// TODO: this should not be here. Also, this should not allocate protected static void WriteCommonHeaders( BufferFormatter formatter, HttpVersion version, int statuCode, string reasonCode, bool keepAlive) { var currentTime = DateTime.UtcNow; formatter.AppendHttpStatusLine(version, statuCode, new Utf8String(reasonCode)); formatter.Append(new Utf8String("Date : ")); formatter.Append(currentTime, 'R'); formatter.AppendHttpNewLine(); formatter.Append("Server : .NET Core Sample Serve"); formatter.AppendHttpNewLine(); formatter.Append("Content-Type : text/html; charset=UTF-8"); formatter.AppendHttpNewLine(); if (!keepAlive) { formatter.Append("Connection : close"); } }
// Not Found protected virtual HttpServerBuffer CreateResponseFor404(HttpRequestLine requestLine, ByteSpan headersAndBody) { Log.LogMessage(Log.Level.Warning, "Request {0}, Response: 404 Not Found", requestLine); BufferFormatter formatter = new BufferFormatter(1024, FormattingData.InvariantUtf8); WriteCommonHeaders(formatter, @"HTTP/1.1 404 Not Found"); formatter.Append(HttpNewline); return new HttpServerBuffer(formatter.Buffer, formatter.CommitedByteCount, BufferPool.Shared); }
// Bad Request protected virtual HttpServerBuffer CreateResponseFor400(ByteSpan receivedBytes) { BufferFormatter formatter = new BufferFormatter(1024, FormattingData.InvariantUtf8); WriteCommonHeaders(formatter, @"HTTP/1.1 400 Bad Request"); formatter.Append(HttpNewline); return new HttpServerBuffer(formatter.Buffer, formatter.CommitedByteCount, BufferPool.Shared); }
private void EncodeStringToUtf8() { string text = "Hello World!"; int stringsToWrite = 2000; int size = stringsToWrite * text.Length + stringsToWrite; BufferFormatter formatter = new BufferFormatter(size, FormattingData.InvariantUtf8); timer.Restart(); for (int itteration = 0; itteration < itterationsInvariant; itteration++) { formatter.Clear(); for (int i = 0; i < stringsToWrite; i++) { formatter.Append(text); formatter.Append(1); } Assert.Equal(size, formatter.CommitedByteCount); } PrintTime(); }
// TODO: this should not be here. Also, this should not allocate protected static void WriteCommonHeaders( BufferFormatter formatter, string version, string statuCode, string reasonCode, bool keepAlive) { var currentTime = DateTime.UtcNow; formatter.WriteHttpStatusLine( new Utf8String(version), new Utf8String(statuCode), new Utf8String(reasonCode)); formatter.WriteHttpHeader(new Utf8String("Date"), new Utf8String(currentTime.ToString("R"))); formatter.WriteHttpHeader(new Utf8String("Server"), new Utf8String(".NET Core Sample Serve")); formatter.WriteHttpHeader(new Utf8String("Last-Modified"), new Utf8String(currentTime.ToString("R"))); formatter.WriteHttpHeader(new Utf8String("Content-Type"), new Utf8String("text/html; charset=UTF-8")); if (!keepAlive) { formatter.WriteHttpHeader(new Utf8String("Connection"), new Utf8String("close")); } }
protected abstract void WriteResponse(BufferFormatter formatter, HttpRequest request);
protected virtual void WriteResponseFor400(BufferFormatter formatter, Span<byte> receivedBytes) // Bad Request { Log.LogMessage(Log.Level.Warning, "Request {0}, Response: 400 Bad Request", receivedBytes.Length); WriteCommonHeaders(formatter, "1.1", "400", "Bad Request", false); formatter.Append(HttpNewline); }
static void WriteResponseForHelloWorld(BufferFormatter formatter) { var responseBodyText = new Utf8String("Hello, World"); formatter.AppendHttpStatusLine(HttpVersion.V1_1, 200, new Utf8String("OK")); formatter.Append(new Utf8String("Content-Length : ")); formatter.Append(responseBodyText.Length); formatter.AppendHttpNewLine(); formatter.Append("Content-Type : text/plain; charset=UTF-8"); formatter.AppendHttpNewLine(); formatter.Append("Server : .NET Core Sample Serve"); formatter.AppendHttpNewLine(); formatter.Append(new Utf8String("Date : ")); formatter.Append(DateTime.UtcNow.ToString("R")); formatter.AppendHttpNewLine(); formatter.AppendHttpNewLine(); formatter.Append(responseBodyText); }
// this will be removed once we implement socket APIs that use pooled memory buffers public static void Write(this TcpClient socket, BufferFormatter formatter) { Console.WriteLine("writing"); NetworkStream stream = socket.GetStream(); var buffer = formatter.Buffer; stream.Write(buffer, 0, formatter.CommitedByteCount); stream.Flush(); //var text = Encoding.UTF8.GetString(buffer, 0, formatter.CommitedByteCount); //Console.WriteLine("response {0} bytes", formatter.CommitedByteCount); //Console.WriteLine(text); BufferPool.Shared.ReturnBuffer(ref buffer); }
protected virtual void WriteResponseFor404(BufferFormatter formatter, HttpRequestLine requestLine) // Not Found { Log.LogMessage(Log.Level.Warning, "Request {0}, Response: 404 Not Found", requestLine); WriteCommonHeaders(formatter, "1.1", "404", "Not Found", false); formatter.Append(HttpNewline); }
public GivenIFormatterExtensionsForHttp() { _formatter = new BufferFormatter(124, FormattingData.InvariantUtf8, ArrayPool<byte>.Shared); }
static void WriteResponseForGetTime(BufferFormatter formatter, HttpRequestLine request) { // TODO: this needs to not allocate. var body = string.Format(@"<html><head><title>Time</title></head><body>{0}</body></html>", DateTime.UtcNow.ToString("O")); WriteCommonHeaders(formatter, HttpVersion.V1_1, 200, "OK", keepAlive: false); formatter.Append(new Utf8String("Content-Length : ")); formatter.Append(body.Length); formatter.AppendHttpNewLine(); formatter.AppendHttpNewLine(); formatter.Append(body); }
public GivenIFormatterExtensionsForHttp() { _formatter = new BufferFormatter(124, FormattingData.InvariantUtf8, ManagedBufferPool<byte>.SharedByteBufferPool); }