diff --git a/ln.http.sln b/ln.http.sln index 11e6cd5..340fa86 100644 --- a/ln.http.sln +++ b/ln.http.sln @@ -9,12 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.http.tests", "ln.http.te EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.http.service", "ln.http.service\ln.http.service.csproj", "{FE139A5A-A388-4656-AD15-149012EDB9D0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.protocols.helper", "..\ln.protocols.helper\ln.protocols.helper.csproj", "{1C1D3A17-A615-4686-90BD-F0E221EAC89C}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.http.templates", "..\ln.templates\ln.http.templates\ln.http.templates.csproj", "{45709176-EA57-4BB3-815B-91D161CEB7A6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.templates", "..\ln.templates\ln.templates\ln.templates.csproj", "{D6BA640C-352F-41BF-85EF-4B76FD928BEC}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.http.helpers", "ln.http.helpers\ln.http.helpers.csproj", "{FAC3F9BE-6C09-4523-8584-2BD5B08BB70D}" EndProject Global @@ -63,26 +59,10 @@ Global {FE139A5A-A388-4656-AD15-149012EDB9D0}.Release|x86.ActiveCfg = Release|Any CPU {FE139A5A-A388-4656-AD15-149012EDB9D0}.Release|x86.Build.0 = Release|Any CPU {FE139A5A-A388-4656-AD15-149012EDB9D0}.Release|Any CPU.Deploy.0 = Release|Any CPU - {1C1D3A17-A615-4686-90BD-F0E221EAC89C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1C1D3A17-A615-4686-90BD-F0E221EAC89C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1C1D3A17-A615-4686-90BD-F0E221EAC89C}.Debug|x64.ActiveCfg = Debug|Any CPU - {1C1D3A17-A615-4686-90BD-F0E221EAC89C}.Debug|x64.Build.0 = Debug|Any CPU - {1C1D3A17-A615-4686-90BD-F0E221EAC89C}.Debug|x86.ActiveCfg = Debug|Any CPU - {1C1D3A17-A615-4686-90BD-F0E221EAC89C}.Debug|x86.Build.0 = Debug|Any CPU - {1C1D3A17-A615-4686-90BD-F0E221EAC89C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1C1D3A17-A615-4686-90BD-F0E221EAC89C}.Release|Any CPU.Build.0 = Release|Any CPU - {1C1D3A17-A615-4686-90BD-F0E221EAC89C}.Release|x64.ActiveCfg = Release|Any CPU - {1C1D3A17-A615-4686-90BD-F0E221EAC89C}.Release|x64.Build.0 = Release|Any CPU - {1C1D3A17-A615-4686-90BD-F0E221EAC89C}.Release|x86.ActiveCfg = Release|Any CPU - {1C1D3A17-A615-4686-90BD-F0E221EAC89C}.Release|x86.Build.0 = Release|Any CPU {45709176-EA57-4BB3-815B-91D161CEB7A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {45709176-EA57-4BB3-815B-91D161CEB7A6}.Debug|Any CPU.Build.0 = Debug|Any CPU {45709176-EA57-4BB3-815B-91D161CEB7A6}.Release|Any CPU.ActiveCfg = Release|Any CPU {45709176-EA57-4BB3-815B-91D161CEB7A6}.Release|Any CPU.Build.0 = Release|Any CPU - {D6BA640C-352F-41BF-85EF-4B76FD928BEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D6BA640C-352F-41BF-85EF-4B76FD928BEC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D6BA640C-352F-41BF-85EF-4B76FD928BEC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D6BA640C-352F-41BF-85EF-4B76FD928BEC}.Release|Any CPU.Build.0 = Release|Any CPU {FAC3F9BE-6C09-4523-8584-2BD5B08BB70D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FAC3F9BE-6C09-4523-8584-2BD5B08BB70D}.Debug|Any CPU.Build.0 = Debug|Any CPU {FAC3F9BE-6C09-4523-8584-2BD5B08BB70D}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/ln.http/Http1XConnection.cs b/ln.http/Http1XConnection.cs index 63b2ea3..b8f5f8e 100644 --- a/ln.http/Http1XConnection.cs +++ b/ln.http/Http1XConnection.cs @@ -9,8 +9,8 @@ public class Http1XConnection : HttpConnection { bool _keepAlive; - public Http1XConnection(Listener listener, IPEndPoint remoteEndpoint, Stream connectionStream, string method, Uri uri, HttpVersion httpVersion) - : base(listener, remoteEndpoint, connectionStream, method, uri, httpVersion) + public Http1XConnection(Listener listener, IPEndPoint remoteEndpoint, Stream connectionStream, string method, string requestUriLine, HttpVersion httpVersion) + : base(listener, remoteEndpoint, connectionStream, method, requestUriLine, httpVersion) { if (httpVersion == HttpVersion.HTTP11) _keepAlive = true; @@ -19,15 +19,18 @@ public class Http1XConnection : HttpConnection public override void Run() { string _method = Method; - Uri _requestUri = RequestUri; HttpVersion _httpVersion = HttpVersion; HeaderContainer headerContainer = new HeaderContainer(); + string _requestUriLine = RequestUriLine; while (ConnectionStream.CanRead && ConnectionStream.CanWrite) { headerContainer.Clear(); headerContainer.Read(ConnectionStream); - + + Uri BaseURI = new Uri($"{(Listener is TlsListener ? "https" : "http")}://{headerContainer.Get("host")}"); + Uri RequestUri = new Uri(BaseURI, _requestUriLine); + if ( headerContainer.TryGetHeader("connection", out Header connectionHeader) ) @@ -45,9 +48,18 @@ public class Http1XConnection : HttpConnection HttpRequestStream requestStream = null; if (headerContainer.TryGetInteger("content-length", out int contentLength)) + { + if (headerContainer.TryGetValue("Expect", out string expectValue) && expectValue.Equals("100-continue")) + { + string statusLine = $"{HttpVersionSupport.ToString(_httpVersion)} 417 expectation failed\r\n"; + byte[] statusLineBytes = Encoding.ASCII.GetBytes(statusLine); + ConnectionStream.Write(statusLineBytes); + break; + } requestStream = new HttpRequestStream(ConnectionStream, contentLength); + } - HttpRequestContext requestContext = new HttpRequestContext(Listener, this, ConnectionStream, new HttpRequest(_method, _requestUri, _httpVersion, false, headerContainer, requestStream)); + HttpRequestContext requestContext = new HttpRequestContext(Listener, this, ConnectionStream, new HttpRequest(_method, RequestUri, _httpVersion, false, headerContainer, requestStream)); Listener.Dispatch(requestContext); if (!ConnectionStream.CanWrite && !ConnectionStream.CanRead) @@ -69,7 +81,7 @@ public class Http1XConnection : HttpConnection if (!_keepAlive) break; - if (!HttpConnection.ReadRequestLine(ConnectionStream, out _method, out _requestUri, out _httpVersion)) + if (!HttpConnection.ReadRequestLine(ConnectionStream, out _method, out _requestUriLine, out _httpVersion)) break; } } diff --git a/ln.http/Http2Connection.cs b/ln.http/Http2Connection.cs index a68811b..5d8250e 100644 --- a/ln.http/Http2Connection.cs +++ b/ln.http/Http2Connection.cs @@ -6,8 +6,8 @@ namespace ln.http; public class Http2Connection : HttpConnection { - public Http2Connection(Listener listener, IPEndPoint remoteEndpoint, Stream connectionStream, string method, Uri uri, HttpVersion httpVersion) - : base(listener, remoteEndpoint, connectionStream, method, uri, httpVersion) + public Http2Connection(Listener listener, IPEndPoint remoteEndpoint, Stream connectionStream, string method, string requestUriLine, HttpVersion httpVersion) + : base(listener, remoteEndpoint, connectionStream, method, requestUriLine, httpVersion) { throw new NotImplementedException(); } diff --git a/ln.http/HttpConnection.cs b/ln.http/HttpConnection.cs index e0e7156..10ed1a8 100644 --- a/ln.http/HttpConnection.cs +++ b/ln.http/HttpConnection.cs @@ -13,18 +13,20 @@ namespace ln.http public IPEndPoint RemoteEndpoint { get; } public Stream ConnectionStream { get; } public string Method { get; } - public Uri RequestUri { get; } + //public Uri RequestUri { get; } public HttpVersion HttpVersion { get; } + public string RequestUriLine { get; set; } + public HttpConnection(Listener listener, IPEndPoint remoteEndpoint, Stream connectionStream, string method, - Uri uri, HttpVersion httpVersion) + String requestUriLine, HttpVersion httpVersion) { Listener = listener; RemoteEndpoint = remoteEndpoint; ConnectionStream = connectionStream; Method = method; - RequestUri = uri; + RequestUriLine = requestUriLine; HttpVersion = httpVersion; } @@ -60,7 +62,7 @@ namespace ln.http return null; } - public static bool ReadRequestLine(Stream stream, out string method, out Uri requestUri, + public static bool ReadRequestLine(Stream stream, out string method, out string requestUri, out HttpVersion httpVersion) { string requestLine = ReadLine(stream); @@ -78,7 +80,7 @@ namespace ln.http if ((idxSpace1 > 0) && (idxSpace2 > 0)) { method = requestLine.Substring(0, idxSpace1); - requestUri = new Uri(requestLine.Substring(idxSpace1 + 1, (idxSpace2 - idxSpace1 - 1))); + requestUri = requestLine.Substring(idxSpace1 + 1, (idxSpace2 - idxSpace1 - 1)); string protocol = requestLine.Substring(idxSpace2 + 1); httpVersion = HttpVersion.None; @@ -98,8 +100,8 @@ namespace ln.http return false; } - public abstract void SendResponse(HttpRequestContext requestContext); - - static Uri Http2PrefaceUri = new Uri("*"); + public abstract void SendResponse(HttpRequestContext requestContext); + + private static string Http2PrefaceUri = "*"; } } diff --git a/ln.http/HttpEndpointController.cs b/ln.http/HttpEndpointController.cs index f217689..1177e6e 100644 --- a/ln.http/HttpEndpointController.cs +++ b/ln.http/HttpEndpointController.cs @@ -103,7 +103,7 @@ namespace ln.http .ConvertFromInvariantString(parameterValue); } } - else if (_argumentSourceAttributes[n].ArgumentSource == HttpArgumentSource.CONTENT) + else if ((_argumentSourceAttributes[n].ArgumentSource == HttpArgumentSource.CONTENT) && (requestContext.Request.Headers.Contains("content-length"))) { if (_parameterInfos[n].ParameterType.Equals(typeof(Stream))) { diff --git a/ln.http/HttpRequestStream.cs b/ln.http/HttpRequestStream.cs index 4dc903e..8985523 100644 --- a/ln.http/HttpRequestStream.cs +++ b/ln.http/HttpRequestStream.cs @@ -13,16 +13,16 @@ public class HttpRequestStream : Stream public HttpRequestStream(Stream connectionStream, int length) { byte[] transferBuffer; - if (length <= MemoryLimit) - { - transferBuffer = new byte[length]; - if (connectionStream.Read(transferBuffer, 0, transferBuffer.Length) != length) - throw new IOException(); - - _stream = new MemoryStream(transferBuffer); - } - else - { + // if (length <= MemoryLimit) + // { + // transferBuffer = new byte[length]; + // if (connectionStream.ReadExactly(transferBuffer, 0, transferBuffer.Length) != length) + // throw new IOException(); + // + // _stream = new MemoryStream(transferBuffer); + // } + // else + // { _tempFileName = Path.GetTempFileName(); _stream = new FileStream(_tempFileName, FileMode.Open, FileAccess.ReadWrite); @@ -36,7 +36,7 @@ public class HttpRequestStream : Stream } _stream.Position = 0; - } + // } } public override int Read(byte[] buffer, int offset, int count) => _stream.Read(buffer, offset, count); diff --git a/ln.http/Listener.cs b/ln.http/Listener.cs index e091991..0bd214a 100644 --- a/ln.http/Listener.cs +++ b/ln.http/Listener.cs @@ -72,7 +72,7 @@ public class Listener : IDisposable protected virtual void Accepted(Socket connectedSocket, Stream connectionStream) { - if (HttpConnection.ReadRequestLine(connectionStream, out string method, out Uri requestUri, out HttpVersion httpVersion)) + if (HttpConnection.ReadRequestLine(connectionStream, out string method, out string requestUri, out HttpVersion httpVersion)) { if ((AcceptedHttpVersion & httpVersion) == HttpVersion.None) return; diff --git a/ln.http/ln.http.csproj b/ln.http/ln.http.csproj index 7dd5243..c8cbd82 100644 --- a/ln.http/ln.http.csproj +++ b/ln.http/ln.http.csproj @@ -9,9 +9,9 @@ (c) 2020 Harald Wolff-Thobaben http server default - 0.9.5 + 0.9.8-preview4 0.6.2.0 - net5.0;net6.0 + net7.0