public void ParseRequestStream_AllHeaderTypes_AllHeadersParsed() { var streamedRequest = new[] { "GET /api/data HTTP/1.1", "Content-Length: 4", "Accept: application/json,text/xml", "Accept-Charset: utf-7;q=0.2, utf-8;q=0.1,*;q=0", "Content-Type: text/xml;charset=utf-8", "UnknownHeader: some:value", "", "data" }; var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes(string.Join("\r\n", streamedRequest))); var request = MutableHttpServerRequest.Parse(new TestStream(byteStreamParts)).Result; Assert.AreEqual(true, request.IsComplete); Assert.IsTrue(request.Headers.Any(h => h.Name == "UnknownHeader" && h.Value == "some:value")); Assert.AreEqual(4, request.ContentLength); Assert.AreEqual("utf-8", request.ContentTypeCharset); Assert.AreEqual("text/xml", request.ContentType); Assert.AreEqual("utf-7", request.AcceptCharsets.First()); Assert.AreEqual("application/json", request.AcceptMediaTypes.First()); Assert.AreEqual("text/xml", request.AcceptMediaTypes.Skip(1).First()); }
private async void ProcessRequestAsync(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args) { await Task.Run(async() => { try { using (var inputStream = args.Socket.InputStream) using (var outputStream = args.Socket.OutputStream) { var request = await MutableHttpServerRequest.Parse(inputStream); var result = await HandleRequestExAsync(request); var httpResponse = result.Item1; var routeRegistration = result.Item2; await WriteResponseAsync(httpResponse, outputStream); if (routeRegistration != null) { await routeRegistration.Stream(args.Socket); } } } catch (Exception ex) { _log.Error($"Exception while handling process: {ex.Message}"); } finally { try { args.Socket.Dispose(); } catch { } } }); }
private async void ProcessRequestAsync(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args) { await Task.Run(async() => { try { using (var inputStream = args.Socket.InputStream) { var request = await MutableHttpServerRequest.Parse(inputStream); var httpResponse = await HandleRequestAsync(request); await WriteResponseAsync(httpResponse, args.Socket); } } catch (Exception ex) { Debug.WriteLine($"Exception while handling process: {ex.Message}"); } finally { try { args.Socket.Dispose(); } catch { } } }); }
public void ParseRequestStream_AcceptEncodingWithQuality_DefaultQuality1AsAccept() { var streamedRequest = "GET /api/data HTTP/1.1\r\nAccept-Encoding: gzip,deflate;q=0.7\r\n\r\n"; var byteStreamParts = Encoding.UTF8.GetBytes(streamedRequest); var request = MutableHttpServerRequest.Parse(new TestStream(new[] { byteStreamParts })).Result; Assert.AreEqual(true, request.IsComplete); Assert.AreEqual("gzip", request.AcceptEncodings.First()); }
public void ParseRequestStream_AcceptWithQuality_DefaultQuality1AsAccept() { var streamedRequest = "GET /api/data HTTP/1.1\r\nAccept: application/json,text/xml;q=0.7\r\n\r\n"; var byteStreamParts = Encoding.UTF8.GetBytes(streamedRequest); var request = MutableHttpServerRequest.Parse(new TestStream(new[] { byteStreamParts })).Result; Assert.AreEqual(true, request.IsComplete); Assert.AreEqual("application/json", request.AcceptMediaTypes.First()); }
public void ParseRequestStream_AcceptCharsetWithQuality_QualityHighestAsAccept() { var streamedRequest = "GET /api/data HTTP/1.1\r\nAccept-Charset: iso-8859-1;q=0.5,utf-8;q=0.7\r\n\r\n"; var byteStreamParts = Encoding.UTF8.GetBytes(streamedRequest); var request = MutableHttpServerRequest.Parse(new TestStream(new[] { byteStreamParts })).Result; Assert.AreEqual(true, request.IsComplete); Assert.AreEqual("utf-8", request.AcceptCharsets.First()); }
internal async Task <MutableHttpServerRequest> ParseRequestStream(IInputStream requestStream) { var httpStream = new HttpRequestStream(requestStream); var request = new MutableHttpServerRequest(); try { var stream = await httpStream.ReadAsync(BUFFER_SIZE, InputStreamOptions.Partial); byte[] streamData = stream.Data; var requestPipeline = GetPipeline(); using (var pipeLineEnumerator = requestPipeline.GetEnumerator()) { pipeLineEnumerator.MoveNext(); bool requestComplete = false; while (!requestComplete) { pipeLineEnumerator.Current.HandleRequestPart(streamData, request); streamData = pipeLineEnumerator.Current.UnparsedData; if (pipeLineEnumerator.Current.IsFinished) { if (!pipeLineEnumerator.Current.IsSucceeded || !pipeLineEnumerator.MoveNext()) { break; } } else { var newStreamdata = await httpStream.ReadAsync(BUFFER_SIZE, InputStreamOptions.Partial); if (!newStreamdata.ReadSuccessful) { break; } streamData = streamData.ConcatArray(newStreamdata.Data); } } } request.IsComplete = requestPipeline.All(p => p.IsSucceeded); } catch (Exception ex) { Debug.WriteLine(ex.Message); } return(request); }
public override void HandleRequestPart(byte[] stream, MutableHttpServerRequest resultThisFar) { var word = stream.ReadNextWord(); if (word.WordFound) { resultThisFar.Uri = new Uri(word.Word, UriKind.RelativeOrAbsolute); UnparsedData = word.RemainingBytes; IsFinished = true; IsSucceeded = true; } }
public override void HandleRequestPart(byte[] stream, MutableHttpServerRequest resultThisFar) { var word = stream.ReadNextWord(); if (word.WordFound) { resultThisFar.HttpVersion = word.Word; UnparsedData = word.RemainingBytes; IsFinished = true; IsSucceeded = true; } }
internal async Task<MutableHttpServerRequest> ParseRequestStream(IInputStream requestStream) { var httpStream = new HttpRequestStream(requestStream); var request = new MutableHttpServerRequest(); try { var stream = await httpStream.ReadAsync(BUFFER_SIZE, InputStreamOptions.Partial); byte[] streamData = stream.Data; var requestPipeline = GetPipeline(); using (var pipeLineEnumerator = requestPipeline.GetEnumerator()) { pipeLineEnumerator.MoveNext(); bool requestComplete = false; while (!requestComplete) { pipeLineEnumerator.Current.HandleRequestPart(streamData, request); streamData = pipeLineEnumerator.Current.UnparsedData; if (pipeLineEnumerator.Current.IsFinished) { if (!pipeLineEnumerator.Current.IsSucceeded || !pipeLineEnumerator.MoveNext()) { break; } } else { var newStreamdata = await httpStream.ReadAsync(BUFFER_SIZE, InputStreamOptions.Partial); if (!newStreamdata.ReadSuccessful) { break; } streamData = streamData.ConcatArray(newStreamdata.Data); } } } request.IsComplete = requestPipeline.All(p => p.IsSucceeded); } catch (Exception ex) { Debug.WriteLine(ex.Message); } return request; }
public void ParseRequestStream_AllAcceptEncodingsAreReturned() { var streamedRequest = "GET /api/data HTTP/1.1\r\nAccept-Encoding: gzip,deflate;q=0.7\r\n\r\n"; var byteStreamParts = Encoding.UTF8.GetBytes(streamedRequest); var request = MutableHttpServerRequest.Parse(new TestStream(new[] { byteStreamParts })).Result; Assert.AreEqual(true, request.IsComplete); Assert.AreEqual(2, request.AcceptEncodings.Count()); Assert.AreEqual("gzip", request.AcceptEncodings.ElementAt(0)); Assert.AreEqual("deflate", request.AcceptEncodings.ElementAt(1)); }
public void ParseRequestStream_WithoutDataAndHeaders_CompleteRequest() { var streamedRequest = new[] { "GET /api/data HTTP/1.1\r\n", //to force double /r/n on string.Join "" }; var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes(string.Join("\r\n", streamedRequest))); var request = MutableHttpServerRequest.Parse(new TestStream(byteStreamParts)).Result; Assert.AreEqual(true, request.IsComplete); }
public void ParseRequestStream_AllDataAtOnce_CompleteRequest() { var streamedRequest = "GET /api/data HTTP/1.1\r\nContent-Length: 4\r\n\r\ndata"; var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes(streamedRequest)); var request = MutableHttpServerRequest.Parse(new TestStream(byteStreamParts)).Result; Assert.AreEqual(HttpMethod.GET, request.Method); Assert.AreEqual(new Uri("/api/data", UriKind.Relative), request.Uri); CollectionAssert.AreEqual(Encoding.UTF8.GetBytes("data"), request.Content); Assert.AreEqual(4, request.ContentLength); Assert.AreEqual("HTTP/1.1", request.HttpVersion); Assert.AreEqual(true, request.IsComplete); }
public void ParseRequestStream_FragmentedData_ValidRequest() { var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes("GET /api/data HTTP/1.1\r\n")); byteStreamParts.Add(Encoding.UTF8.GetBytes("Content-Leng")); byteStreamParts.Add(Encoding.UTF8.GetBytes("th: 4\r\n")); byteStreamParts.Add(Encoding.UTF8.GetBytes("\r\nd")); byteStreamParts.Add(Encoding.UTF8.GetBytes("a")); byteStreamParts.Add(Encoding.UTF8.GetBytes("t")); byteStreamParts.Add(Encoding.UTF8.GetBytes("a")); var request = MutableHttpServerRequest.Parse(new TestStream(byteStreamParts)).Result; Assert.AreEqual(true, request.IsComplete); CollectionAssert.AreEqual(Encoding.UTF8.GetBytes("data"), request.Content); }
public void ParseRequestStream_DataLengthInSecondPart_ValidRequest() { var httpHeadersPart1 = "GET /api/data HTTP/1.1\r\n"; var httpHeadersPart2 = "Content-Length: 4\r\n\r\n"; var content = Encoding.UTF8.GetBytes("data"); var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes(httpHeadersPart1)); byteStreamParts.Add(Encoding.UTF8.GetBytes(httpHeadersPart2)); byteStreamParts.Add(new byte[] { }); byteStreamParts.Add(content); var request = MutableHttpServerRequest.Parse(new TestStream(byteStreamParts)).Result; Assert.AreEqual(true, request.IsComplete); CollectionAssert.AreEqual(content, request.Content); }
public void ParseRequestStream_ContentLengthNumberMissing_RequestIncomplete() { var streamedRequest = new[] { "GET /api/data HTTP/1.1", "Content-Length: four", "", "data" }; var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes(string.Join("\r\n", streamedRequest))); var request = MutableHttpServerRequest.Parse(new TestStream(byteStreamParts)).Result; Assert.AreEqual(false, request.IsComplete); }
public void ParseRequestStream_TooMuchData_RequestIncomplete() { var streamedRequest = new[] { "GET /api/data HTTP/1.1", "Content-Length: 4", "", "data" }; var extraData = "plusanotherextrafewbytes"; var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes(string.Join("\r\n", streamedRequest) + extraData)); var request = MutableHttpServerRequest.Parse(new TestStream(byteStreamParts)).Result; Assert.AreEqual(false, request.IsComplete); }
public override void HandleRequestPart(byte[] stream, MutableHttpServerRequest resultThisFar) { if (resultThisFar.ContentLength == 0) { IsFinished = true; IsSucceeded = stream.Length == 0; } else { _content.AddRange(stream); if (_content.Count == resultThisFar.ContentLength) { resultThisFar.Content = _content.ToArray(); IsFinished = true; IsSucceeded = true; } // else if content is bigger, finished will never be set, badrequest will happen } }
public void ParseRequestStream_PartedData_ValidRequest() { var streamedRequest = new[] { "GET /api/data HTTP/1.1", "Content-Length: 4\r\n", //to force double /r/n on string.Join "" }; var content = Encoding.UTF8.GetBytes("data"); var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes(string.Join("\r\n", streamedRequest))); byteStreamParts.Add(content); var request = MutableHttpServerRequest.Parse(new TestStream(byteStreamParts)).Result; Assert.AreEqual(true, request.IsComplete); CollectionAssert.AreEqual(content, request.Content); }
public void ParseRequestStream_ThreeEmptyResponses_EmptyRequestString() { var streamedRequest = new[] { "GET /api/data HTTP/1.1", "Content-Length: 4\r\n", //to force double /r/n on string.Join "" }; var content = "data"; var byteStreamParts = new List <byte[]>(); byteStreamParts.Add(Encoding.UTF8.GetBytes(string.Join("\r\n", streamedRequest))); byteStreamParts.Add(new byte[] { }); byteStreamParts.Add(new byte[] { }); byteStreamParts.Add(new byte[] { }); byteStreamParts.Add(new byte[] { }); byteStreamParts.Add(Encoding.UTF8.GetBytes(content)); var request = MutableHttpServerRequest.Parse(new TestStream(byteStreamParts)).Result; Assert.AreEqual(false, request.IsComplete); }
public abstract void HandleRequestPart(byte[] stream, MutableHttpServerRequest resultThisFar);
/// <summary> /// A regex would be nice :) /// </summary> /// <param name="stream"></param> /// <param name="resultThisFar"></param> public override void HandleRequestPart(byte[] stream, MutableHttpServerRequest resultThisFar) { UnparsedData = stream; string headerName = null; var bytesLeft = stream.Length; int headerValueStartIndex = 0; int headerValueEndIndex = 0; for (var i = 0; i < stream.Length; i++, bytesLeft--) { byte currentByte = stream[i]; if (headerName == null && currentByte == Constants.ColonByte) { headerName = GetHeaderString(stream, headerValueEndIndex, i); headerValueStartIndex = i + 1; } else if (stream[i] == Constants.CRByte) { // Special case when /r/n is received or /r/ncontentdata if (i == 0 && bytesLeft >= 2 && stream[1] == Constants.LFByte) { IsFinished = true; IsSucceeded = true; headerValueEndIndex = 2; break; } if (headerName != null && bytesLeft >= 2 && stream[i + 1] == Constants.LFByte) { // Handle end of one header scenario var headerValue = GetHeaderString(stream, headerValueStartIndex, i); headerValue = headerValue.TrimWhitespaces(); try { resultThisFar.AddHeader(_headerFactory.Create(headerName, headerValue)); } catch (Exception) { IsFinished = true; IsSucceeded = false; break; } finally { headerName = null; headerValueStartIndex = 0; headerValueEndIndex = i + 2; } } if (bytesLeft >= 4 && stream[i + 1] == Constants.LFByte && stream[i + 2] == Constants.CRByte && stream[i + 3] == Constants.LFByte) { // Handle end of headers scenario headerValueEndIndex = i + 4; IsFinished = true; IsSucceeded = true; break; } } } UnparsedData = stream.Skip(headerValueEndIndex).ToArray(); }