diff --git a/Hamakaze/HttpConnection.cs b/Hamakaze/HttpConnection.cs index 8bb90d0..d5b2c9e 100644 --- a/Hamakaze/HttpConnection.cs +++ b/Hamakaze/HttpConnection.cs @@ -4,7 +4,6 @@ using System.Net; using System.Net.Security; using System.Net.Sockets; using System.Security.Authentication; -using System.Threading; namespace Hamakaze { public class HttpConnection : IDisposable { @@ -18,9 +17,9 @@ namespace Hamakaze { public string Host { get; } public bool IsSecure { get; } - public bool HasTimedOut => MaxRequests == 0 || (DateTimeOffset.Now - LastOperation) > MaxIdle; + public bool HasTimedOut => MaxRequests < 1 || (DateTimeOffset.Now - LastOperation) > MaxIdle; - public int MaxRequests { get; set; } = -1; + public int? MaxRequests { get; set; } = null; public TimeSpan MaxIdle { get; set; } = TimeSpan.MaxValue; public DateTimeOffset LastOperation { get; private set; } = DateTimeOffset.Now; @@ -45,14 +44,19 @@ namespace Hamakaze { if(IsSecure) { SslStream = new SslStream(NetworkStream, false, (s, ce, ch, e) => e == SslPolicyErrors.None, null); Stream = SslStream; - SslStream.AuthenticateAsClient(Host, null, SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, true); + SslStream.AuthenticateAsClient( + Host, + null, + SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, + true + ); } else Stream = NetworkStream; } public void MarkUsed() { LastOperation = DateTimeOffset.Now; - if(MaxRequests > 0) + if(MaxRequests != null) --MaxRequests; } diff --git a/Hamakaze/HttpException.cs b/Hamakaze/HttpException.cs index d6e0bce..6219e57 100644 --- a/Hamakaze/HttpException.cs +++ b/Hamakaze/HttpException.cs @@ -12,6 +12,13 @@ namespace Hamakaze { public HttpConnectionManagerLockException() : base(@"Failed to lock the connection manager in time.") { } } + public class HttpRequestMessageException : HttpException { + public HttpRequestMessageException(string message) : base(message) { } + } + public class HttpRequestMessageStreamException : HttpRequestMessageException { + public HttpRequestMessageStreamException() : base(@"Provided Stream is not writable.") { } + } + public class HttpTaskException : HttpException { public HttpTaskException(string message) : base(message) { } } diff --git a/Hamakaze/HttpRequestMessage.cs b/Hamakaze/HttpRequestMessage.cs index 6ce3ce3..77a7907 100644 --- a/Hamakaze/HttpRequestMessage.cs +++ b/Hamakaze/HttpRequestMessage.cs @@ -157,6 +157,9 @@ namespace Hamakaze { } public void WriteTo(Stream stream, Action onProgress = null) { + if(!stream.CanWrite) + throw new HttpRequestMessageStreamException(); + using(StreamWriter sw = new(stream, new ASCIIEncoding(), leaveOpen: true)) { sw.NewLine = "\r\n"; sw.Write(Method); diff --git a/Hamakaze/HttpResponseMessage.cs b/Hamakaze/HttpResponseMessage.cs index c041e93..c401ed1 100644 --- a/Hamakaze/HttpResponseMessage.cs +++ b/Hamakaze/HttpResponseMessage.cs @@ -127,7 +127,7 @@ namespace Hamakaze { for(; ; ) { byt = stream.ReadByte(); if(byt == -1 && ms.Length == 0) - return null; + throw new IOException(@"readLine: There is no data."); ms.WriteByte((byte)byt); diff --git a/Hamakaze/HttpTask.cs b/Hamakaze/HttpTask.cs index ddcd212..e3ae06e 100644 --- a/Hamakaze/HttpTask.cs +++ b/Hamakaze/HttpTask.cs @@ -131,7 +131,7 @@ namespace Hamakaze { try { Request.WriteTo(Connection.Stream, (p, t) => OnUploadProgress?.Invoke(this, p, t)); break; - } catch(IOException ex) { + } catch(HttpRequestMessageStreamException ex) { Connection.Dispose(); Connection = Connections.GetConnection(Request.Host, endPoint, Request.IsSecure); @@ -162,7 +162,8 @@ namespace Hamakaze { return; } - if(Response.Connection == HttpConnectionHeader.CLOSE) + if(Response.Connection == HttpConnectionHeader.CLOSE + || Response.ProtocolVersion.CompareTo(@"1.1") < 0) Connection.Dispose(); if(Response == null) Error(new HttpTaskRequestFailedException());