diff --git a/Content.cs b/Content.cs index 69b1c26..dd497ae 100644 --- a/Content.cs +++ b/Content.cs @@ -4,6 +4,9 @@ using Fody; +using Microsoft.IO; + +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Yove.Http.Exceptions; @@ -27,7 +30,9 @@ public class Content : IDisposable #region Internal - internal MemoryStream Stream { get; } = new(); + private readonly RecyclableMemoryStreamManager _streamManager = new(); + + internal RecyclableMemoryStream Stream { get; set; } #endregion @@ -40,10 +45,21 @@ public async Task ReadAsString() { if (_response.IsEmpytyBody) throw new HttpResponseException("Content not found."); + else if (_response.ContentLength.HasValue && _response.ContentLength > int.MaxValue) + throw new HttpResponseException("The data array is too large (Use ToFile)."); + + RecyclableMemoryStream outputStream = await ReadAsStream() as RecyclableMemoryStream; - MemoryStream outputStream = await _response.GetBodyContent(); + if (outputStream.Length > int.MaxValue) + { + outputStream.Dispose(); - return _response.CharacterSet.GetString(outputStream.ToArray(), 0, (int)outputStream.Length); + throw new HttpResponseException("The data array is too large (Use ToFile)."); + } + + byte[] buffer = outputStream.GetBuffer(); + + return _response.CharacterSet.GetString(buffer, 0, buffer.Length); } public async Task ReadAsJson() @@ -56,19 +72,106 @@ public async Task ReadAsJson() return JToken.Parse(body); } - public async Task ReadAsStream() + public async Task ReadAsJson() { - if (_response.IsEmpytyBody) + string body = await ReadAsString(); + + if (string.IsNullOrEmpty(body)) throw new HttpResponseException("Content not found."); - return await _response.GetBodyContent(); + return JsonConvert.DeserializeObject(body); } public async Task ReadAsBytes() { - MemoryStream outputStream = await ReadAsStream(); + if (_response.IsEmpytyBody) + throw new HttpResponseException("Content not found."); + if (_response.ContentLength.HasValue && _response.ContentLength > int.MaxValue) + throw new HttpResponseException("The data array is too large (Use ToFile)."); + + RecyclableMemoryStream outputStream = await ReadAsStream() as RecyclableMemoryStream; + + if (outputStream.Length > int.MaxValue) + { + outputStream.Dispose(); + + throw new HttpResponseException("The data array is too large (Use ToFile)."); + } + + return outputStream.GetBuffer(); + } + + public async Task ReadAsStream() + { + if (_response.IsEmpytyBody) + throw new HttpResponseException("Content not found."); + + Stream ??= _streamManager.GetStream(); + + if (Stream.Length == 0) + { + await foreach (Memory source in _response.GetBodyContent()) + Stream.Write(source.ToArray(), 0, source.Length); + } + + Stream.Seek(0, SeekOrigin.Begin); + + return Stream; + } + + public async Task ToFile(string filepath) + { + if (string.IsNullOrEmpty(filepath)) + throw new NullReferenceException("filepath is null or empty."); + + string path = Path.GetDirectoryName(filepath); + string filename = Path.GetFileName(filepath); + + return await ToFile(path, filename); + } + + public async Task ToFile(string localPath, string filename = null) + { + if (_response.IsEmpytyBody) + throw new NullReferenceException("Content not found."); + + if (string.IsNullOrEmpty(localPath)) + throw new NullReferenceException("Path is null or empty."); + + if (filename == null) + { + if (_response.Headers["Content-Disposition"] != null) + { + filename = $"{localPath.TrimEnd('/')}/{HttpUtils.Parser("filename=\"", _response.Headers["Content-Disposition"], "\"")}"; + } + else + { + filename = Path.GetFileName(new Uri(_response.Address.AbsoluteUri).LocalPath); + + if (string.IsNullOrEmpty(filename)) + throw new NullReferenceException("Could not find filename."); + } + } + + string outputPath = Path.Join(localPath.TrimEnd('/'), filename); + + Stream ??= _streamManager.GetStream(); + + using FileStream fileStream = new(outputPath, FileMode.OpenOrCreate); + + if (Stream.Length == 0) + { + await foreach (Memory source in _response.GetBodyContent()) + await fileStream.WriteAsync(source); + } + else + { + Stream.Seek(0, SeekOrigin.Begin); + + await Stream.CopyToAsync(fileStream); + } - return outputStream?.ToArray(); + return outputPath; } protected virtual void Dispose(bool disposing) diff --git a/Content/MultipartContent.cs b/Content/MultipartContent.cs index 33414c5..dede338 100644 --- a/Content/MultipartContent.cs +++ b/Content/MultipartContent.cs @@ -32,32 +32,34 @@ public override long ContentLength { get { - if (_elements.Count == 0) - throw new ObjectDisposedException("Content disposed or empty."); - - long length = 0; - - foreach (Element item in _elements) + if (_elements.Count != 0) { - length += item.Content.ContentLength; + long length = 0; - if (item.IsFieldFile) - { - length += 72; - length += item.Name.Length; - length += item.Filename.Length; - length += item.Content.ContentType.Length; - } - else + foreach (Element item in _elements) { - length += 43; - length += item.Name.Length; + length += item.Content.ContentLength; + + if (item.IsFieldFile) + { + length += 72; + length += item.Name.Length; + length += item.Filename.Length; + length += item.Content.ContentType.Length; + } + else + { + length += 43; + length += item.Name.Length; + } + + length += _boundary.Length + 6; } - length += _boundary.Length + 6; + return length += _boundary.Length + 6; } - return length += _boundary.Length + 6; + throw new ObjectDisposedException("Content disposed or empty."); } } @@ -187,36 +189,40 @@ public void Add(string name, string contentType, FileContent content, string fil public override void Write(Stream commonStream) { - if (_elements.Count == 0) - throw new ObjectDisposedException("Content disposed or empty."); - - if (commonStream == null) - throw new NullReferenceException("CommonStream is null."); + if (_elements.Count != 0) + { + if (commonStream == null) + throw new NullReferenceException("CommonStream is null."); - byte[] lineBytes = Encoding.ASCII.GetBytes("\r\n"); - byte[] boundaryBytes = Encoding.ASCII.GetBytes($"--{_boundary}\r\n"); + byte[] lineBytes = Encoding.ASCII.GetBytes("\r\n"); + byte[] boundaryBytes = Encoding.ASCII.GetBytes($"--{_boundary}\r\n"); - foreach (Element item in _elements) - { - commonStream.Write(boundaryBytes, 0, boundaryBytes.Length); + foreach (Element item in _elements) + { + commonStream.Write(boundaryBytes, 0, boundaryBytes.Length); - string field; + string field; - if (item.IsFieldFile) - field = $"Content-Disposition: form-data; name=\"{item.Name}\"; filename=\"{item.Filename}\"\r\nContent-Type: {item.Content.ContentType}\r\n\r\n"; - else - field = $"Content-Disposition: form-data; name=\"{item.Name}\"\r\n\r\n"; + if (item.IsFieldFile) + field = $"Content-Disposition: form-data; name=\"{item.Name}\"; filename=\"{item.Filename}\"\r\nContent-Type: {item.Content.ContentType}\r\n\r\n"; + else + field = $"Content-Disposition: form-data; name=\"{item.Name}\"\r\n\r\n"; - byte[] fieldBytes = Encoding.ASCII.GetBytes(field); + byte[] fieldBytes = Encoding.ASCII.GetBytes(field); - commonStream.Write(fieldBytes, 0, fieldBytes.Length); - item.Content.Write(commonStream); - commonStream.Write(lineBytes, 0, lineBytes.Length); - } + commonStream.Write(fieldBytes, 0, fieldBytes.Length); + item.Content.Write(commonStream); + commonStream.Write(lineBytes, 0, lineBytes.Length); + } - boundaryBytes = Encoding.ASCII.GetBytes($"--{_boundary}--\r\n"); + boundaryBytes = Encoding.ASCII.GetBytes($"--{_boundary}--\r\n"); - commonStream.Write(boundaryBytes, 0, boundaryBytes.Length); + commonStream.Write(boundaryBytes, 0, boundaryBytes.Length); + } + else + { + throw new ObjectDisposedException("Content disposed or empty."); + } } ~MultipartContent() diff --git a/Content/StreamContent.cs b/Content/StreamContent.cs index 851e551..381e795 100644 --- a/Content/StreamContent.cs +++ b/Content/StreamContent.cs @@ -13,10 +13,7 @@ public override long ContentLength { get { - if (Content == null) - throw new ObjectDisposedException("Content disposed or empty."); - - return Content.Length; + return Content == null ? throw new ObjectDisposedException("Content disposed or empty.") : Content.Length; } } @@ -33,24 +30,28 @@ public StreamContent(Stream content, int bufferSize = 32768) public override void Write(Stream commonStream) { - if (Content == null) - throw new ObjectDisposedException("Content disposed or empty."); - - if (commonStream == null) - throw new NullReferenceException("Stream is empty."); + if (Content != null) + { + if (commonStream == null) + throw new NullReferenceException("Stream is empty."); - Content.Position = 0; + Content.Position = 0; - byte[] buffer = new byte[BufferSize]; + byte[] buffer = new byte[BufferSize]; - while (true) - { - int readBytes = Content.Read(buffer, 0, buffer.Length); + while (true) + { + int readBytes = Content.Read(buffer, 0, buffer.Length); - if (readBytes == 0) - break; + if (readBytes == 0) + break; - commonStream.Write(buffer, 0, readBytes); + commonStream.Write(buffer, 0, readBytes); + } + } + else + { + throw new ObjectDisposedException("Content disposed or empty."); } } diff --git a/Events/DownloadEvent.cs b/Events/DownloadEvent.cs index c3f54a2..4f7e7d6 100644 --- a/Events/DownloadEvent.cs +++ b/Events/DownloadEvent.cs @@ -2,10 +2,10 @@ namespace Yove.Http.Events; -public class DownloadEvent : EventArgs +public class DownloadEvent(long received, long? total) : EventArgs { - public long Received { get; } - public long? Total { get; } + public long Received { get; } = received; + public long? Total { get; } = total; public int ProgressPercentage { @@ -14,10 +14,4 @@ public int ProgressPercentage return (int)(Received / (double)Total * 100.0); } } - - public DownloadEvent(long received, long? total) - { - Received = received; - Total = total; - } } diff --git a/Events/UploadEvent.cs b/Events/UploadEvent.cs index 9c75419..e54ca7c 100644 --- a/Events/UploadEvent.cs +++ b/Events/UploadEvent.cs @@ -2,10 +2,10 @@ namespace Yove.Http.Events; -public class UploadEvent : EventArgs +public class UploadEvent(long sent, long total) : EventArgs { - public long Sent { get; } - public long Total { get; } + public long Sent { get; } = sent; + public long Total { get; } = total; public int ProgressPercentage { @@ -14,10 +14,4 @@ public int ProgressPercentage return (int)(Sent / (double)Total * 100.0); } } - - public UploadEvent(long sent, long total) - { - Sent = sent; - Total = total; - } } diff --git a/Exceptions/ProxyException.cs b/Exceptions/ProxyException.cs index 2af9523..8013827 100644 --- a/Exceptions/ProxyException.cs +++ b/Exceptions/ProxyException.cs @@ -10,6 +10,4 @@ public HttpProxyException() { } public HttpProxyException(string message) : base(message) { } public HttpProxyException(string message, Exception inner) : base(message, inner) { } - - protected HttpProxyException(SerializationInfo info, StreamingContext context) : base(info, context) { } } diff --git a/HttpClient.cs b/HttpClient.cs index 25fd163..b36917c 100644 --- a/HttpClient.cs +++ b/HttpClient.cs @@ -215,35 +215,35 @@ public async Task GetString(string url) { HttpResponse response = await Raw(HttpMethod.GET, url); - return await response.Content.ReadAsString(); + return await response?.Content?.ReadAsString(); } public async Task GetJson(string url) { HttpResponse response = await Raw(HttpMethod.GET, url); - return await response.Content.ReadAsJson(); + return await response?.Content?.ReadAsJson(); } - public async Task GetBytes(string url) + public async Task GetJson(string url) { HttpResponse response = await Raw(HttpMethod.GET, url); - return await response.Content.ReadAsBytes(); + return await response?.Content?.ReadAsJson(); } - public async Task GetStream(string url) + public async Task GetBytes(string url) { HttpResponse response = await Raw(HttpMethod.GET, url); - return await response.Content.ReadAsStream(); + return await response?.Content?.ReadAsBytes(); } - public async Task GetToFile(string url, string path, string filename = null) + public async Task GetStream(string url) { HttpResponse response = await Raw(HttpMethod.GET, url); - return await response.ToFile(path, filename); + return await response?.Content?.ReadAsStream(); } public async Task Raw(HttpMethod method, string url, HttpContent body = null) diff --git a/HttpResponse.cs b/HttpResponse.cs index 6f994f9..48ba152 100644 --- a/HttpResponse.cs +++ b/HttpResponse.cs @@ -215,49 +215,90 @@ internal HttpResponse(HttpClient httpClient) Content = new Content(this); } - internal async Task GetBodyContent() + internal async IAsyncEnumerable> GetBodyContent() { _request.CancellationToken.ThrowIfCancellationRequested(); if (ContentLength.HasValue && ContentLength > _request.MaxReciveBufferSize) - throw new InternalBufferOverflowException($"Cannot write more bytes to the buffer than the configured maximum buffer size: {_request.MaxReciveBufferSize}"); - - if (Content.Stream.Length > 0) { - Content.Stream.Position = 0; - - return Content.Stream; + throw new InternalBufferOverflowException($"Cannot write more bytes to the buffer than the configured maximum buffer size: {_request.MaxReciveBufferSize}"); } - MemoryStream outputStream = null; - if (Headers["Content-Encoding"] != null && Headers["Content-Encoding"] != "none") { if (Headers["Transfer-Encoding"] != null) - outputStream = await ReceiveZipBody(true); + { + await foreach (Memory stream in ReceiveZipBody(true)) + { + _request.CancellationToken.ThrowIfCancellationRequested(); - if (outputStream == null && ContentLength.HasValue) - outputStream = await ReceiveZipBody(false); + yield return stream; + } - if (outputStream == null) + if (Content.Stream.Length > 0) + yield break; + } + else if (!ContentLength.HasValue) { - using StreamWrapper streamWrapper = new(_request.CommonStream, _content); - using Stream decopressionStream = GetZipStream(streamWrapper); + await foreach (Memory stream in ReceiveZipBody(false)) + { + _request.CancellationToken.ThrowIfCancellationRequested(); + + yield return stream; + } - outputStream = await ReceiveUnsizeBody(decopressionStream); + if (Content.Stream.Length > 0) + yield break; } + + using StreamWrapper streamWrapper = new(_request.CommonStream, _content); + using Stream decopressionStream = GetZipStream(streamWrapper); + + await foreach (Memory stream in ReceiveUnsizeBody(decopressionStream)) + { + _request.CancellationToken.ThrowIfCancellationRequested(); + + yield return stream; + } + + if (Content.Stream.Length > 0) + yield break; } - if (outputStream == null && Headers["Transfer-Encoding"] != null) - outputStream = await ReceiveStandartBody(true); + if (Headers["Transfer-Encoding"] != null) + { + await foreach (Memory stream in ReceiveStandartBody(true)) + { + _request.CancellationToken.ThrowIfCancellationRequested(); + + yield return stream; + } + + if (Content.Stream.Length > 0) + yield break; + } + else if (ContentLength.HasValue) + { + await foreach (Memory stream in ReceiveStandartBody(false)) + { + _request.CancellationToken.ThrowIfCancellationRequested(); + + yield return stream; + } + + if (Content.Stream.Length > 0) + yield break; + } - if (outputStream == null && ContentLength.HasValue) - outputStream = await ReceiveStandartBody(false); + await foreach (Memory stream in ReceiveUnsizeBody(_request.CommonStream)) + { + _request.CancellationToken.ThrowIfCancellationRequested(); - outputStream ??= await ReceiveUnsizeBody(_request.CommonStream); + yield return stream; + } - if (outputStream != null && Content.Stream.Length > 0) - Content.Stream.Position = 0; + if (Content.Stream.Length > 0) + yield break; if (!ContentLength.HasValue || ContentLength == 0 || Method == HttpMethod.HEAD || StatusCode == HttpStatusCode.Continue || StatusCode == HttpStatusCode.NoContent || @@ -265,8 +306,6 @@ internal async Task GetBodyContent() { IsEmpytyBody = true; } - - return outputStream; } private Stream GetZipStream(Stream inputStream) @@ -280,88 +319,92 @@ private Stream GetZipStream(Stream inputStream) }; } - private async Task ReceiveZipBody(bool chunked) + private async IAsyncEnumerable> ReceiveZipBody(bool chunked) { - using (StreamWrapper streamWrapper = new(_request.CommonStream, _content)) - { - using Stream decopressionStream = GetZipStream(streamWrapper); - - byte[] buffer = new byte[_request.Connection.ReceiveBufferSize]; + using StreamWrapper streamWrapper = new(_request.CommonStream, _content); + using Stream decopressionStream = GetZipStream(streamWrapper); - if (chunked) - { - while (true) - { - string getLine = _content.Get(true); - - if (getLine == "\r\n") - continue; - - getLine = getLine.Trim(' ', '\r', '\n'); - - if (getLine?.Length == 0) - break; + byte[] buffer = new byte[_request.Connection.ReceiveBufferSize]; - int blockLength = Convert.ToInt32(getLine, 16); + if (chunked) + { + long totalLength = 0; - if (blockLength == 0) - break; + while (true) + { + string getLine = _content.Get(true); - streamWrapper.TotalBytesRead = 0; - streamWrapper.LimitBytesRead = blockLength; + if (getLine == "\r\n") + continue; - while (true) - { - int readBytes = decopressionStream.Read(buffer, 0, buffer.Length); + getLine = getLine.Trim(' ', '\r', '\n'); - if (readBytes == 0) - { - if (streamWrapper.TotalBytesRead == blockLength) - break; + if (getLine?.Length == 0) + break; - await WaitStream(); - continue; - } + int blockLength = Convert.ToInt32(getLine, 16); - await Content.Stream.WriteAsync(buffer.AsMemory(0, readBytes)); + if (blockLength == 0) + break; - if (Content.Stream.Length > _request.MaxReciveBufferSize) - throw new InternalBufferOverflowException($"Cannot write more bytes to the buffer than the configured maximum buffer size: {_request.MaxReciveBufferSize}"); - } - } + streamWrapper.TotalBytesRead = 0; + streamWrapper.LimitBytesRead = blockLength; - if (ContentLength == null || ContentLength.Value == 0) - ContentLength = Content.Stream.Length; - } - else - { while (true) { - int readBytes = await decopressionStream.ReadAsync(buffer); + int readBytes = decopressionStream.Read(buffer, 0, buffer.Length); if (readBytes == 0) { - if (streamWrapper.TotalBytesRead == ContentLength) + if (streamWrapper.TotalBytesRead == blockLength) break; await WaitStream(); continue; } - await Content.Stream.WriteAsync(buffer.AsMemory(0, readBytes)); + totalLength += readBytes; + + if (totalLength > _request.MaxReciveBufferSize) + { + throw new InternalBufferOverflowException($"Cannot write more bytes to the buffer than the configured maximum buffer size: {_request.MaxReciveBufferSize}"); + } + + yield return buffer.AsMemory(0, readBytes); } } + + if (ContentLength == null || ContentLength.Value == 0) + ContentLength = totalLength; } + else + { + while (true) + { + int readBytes = await decopressionStream.ReadAsync(buffer); + + if (readBytes == 0) + { + if (streamWrapper.TotalBytesRead == ContentLength) + break; - return Content.Stream; + await WaitStream(); + continue; + } + + yield return buffer.AsMemory(0, readBytes); + } + } } - private async Task ReceiveStandartBody(bool chunked) + private async IAsyncEnumerable> ReceiveStandartBody(bool chunked) { byte[] buffer = new byte[_request.Connection.ReceiveBufferSize]; if (chunked) { + long totalLength = 0; + while (true) { string getLine = _content.Get(true); @@ -402,16 +445,19 @@ private async Task ReceiveStandartBody(bool chunked) } totalBytesRead += readBytes; + totalLength += readBytes; - await Content.Stream.WriteAsync(buffer.AsMemory(0, readBytes)); - - if (Content.Stream.Length > _request.MaxReciveBufferSize) + if (totalLength > _request.MaxReciveBufferSize) + { throw new InternalBufferOverflowException($"Cannot write more bytes to the buffer than the configured maximum buffer size: {_request.MaxReciveBufferSize}"); + } + + yield return buffer.AsMemory(0, readBytes); } } if (ContentLength == null || ContentLength.Value == 0) - ContentLength = Content.Stream.Length; + ContentLength = totalLength; } else { @@ -432,16 +478,14 @@ private async Task ReceiveStandartBody(bool chunked) continue; } - await Content.Stream.WriteAsync(buffer.AsMemory(0, readBytes)); - totalBytesRead += readBytes; + + yield return buffer.AsMemory(0, readBytes); } } - - return Content.Stream; } - private async Task ReceiveUnsizeBody(Stream inputStream) + private async IAsyncEnumerable> ReceiveUnsizeBody(Stream inputStream) { int beginBytesRead = 0; @@ -460,12 +504,12 @@ private async Task ReceiveUnsizeBody(Stream inputStream) beginBytesRead += await inputStream.ReadAsync(buffer.AsMemory(beginBytesRead, buffer.Length - beginBytesRead)); } - await Content.Stream.WriteAsync(buffer.AsMemory(0, beginBytesRead)); - string html = Encoding.ASCII.GetString(buffer); if (html.Contains("", StringComparison.OrdinalIgnoreCase)) - return Content.Stream; + yield return buffer.AsMemory(0, beginBytesRead); + + long totalLength = 0; while (true) { @@ -483,7 +527,8 @@ private async Task ReceiveUnsizeBody(Stream inputStream) if (html.Contains("", StringComparison.OrdinalIgnoreCase)) { - await Content.Stream.WriteAsync(buffer.AsMemory(0, beginBytesRead)); + yield return buffer.AsMemory(0, beginBytesRead); + break; } } @@ -492,16 +537,18 @@ private async Task ReceiveUnsizeBody(Stream inputStream) break; } - await Content.Stream.WriteAsync(buffer.AsMemory(0, readBytes)); + totalLength += readBytes; - if (Content.Stream.Length > _request.MaxReciveBufferSize) + if (totalLength > _request.MaxReciveBufferSize) + { throw new InternalBufferOverflowException($"Cannot write more bytes to the buffer than the configured maximum buffer size: {_request.MaxReciveBufferSize}"); + } + + yield return buffer.AsMemory(0, readBytes); } if (ContentLength == null || ContentLength.Value == 0) - ContentLength = Content.Stream.Length; - - return Content.Stream; + ContentLength = totalLength; } private async Task WaitStream() @@ -522,42 +569,4 @@ private async Task WaitStream() throw new HttpResponseException($"Timeout waiting for data from Address: {_request.Address.AbsoluteUri}"); } } - - public async Task ToFile(string filename) - { - if (string.IsNullOrEmpty(filename)) - throw new NullReferenceException("Filename is null or empty."); - - return await ToFile(AppDomain.CurrentDomain.BaseDirectory, filename); - } - - public async Task ToFile(string localPath, string filename = null) - { - if (IsEmpytyBody) - throw new NullReferenceException("Content not found."); - - if (string.IsNullOrEmpty(localPath)) - throw new NullReferenceException("Path is null or empty."); - - if (filename == null) - { - if (Headers["Content-Disposition"] != null) - { - filename = $"{localPath.TrimEnd('/')}/{HttpUtils.Parser("filename=\"", Headers["Content-Disposition"], "\"")}"; - } - else - { - filename = Path.GetFileName(new Uri(Address.AbsoluteUri).LocalPath); - - if (string.IsNullOrEmpty(filename)) - throw new NullReferenceException("Could not find filename."); - } - } - - string outputPath = $"{localPath.TrimEnd('/')}/{filename}"; - - await File.WriteAllBytesAsync(outputPath, await Content.ReadAsBytes()); - - return outputPath; - } } diff --git a/README.md b/README.md index 232d34e..aba0e05 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ [![NuGet version](https://badge.fury.io/nu/Yove.Http.svg)](https://badge.fury.io/nu/Yove.Http) [![Downloads](https://img.shields.io/nuget/dt/Yove.Http.svg)](https://www.nuget.org/packages/Yove.Http) -[![Target](https://img.shields.io/badge/.NET%20Standard-2.0-green.svg)](https://docs.microsoft.com/ru-ru/dotnet/standard/net-standard) Nuget: https://www.nuget.org/packages/Yove.Http @@ -28,7 +27,8 @@ using(HttpClient client = new HttpClient EnableReconnect = false, // Disable reconnection in case of connection errors or data reading ReconnectDelay = 1000, // Delay in attempting a new connection ReconnectLimit = 3, // Maximum number of reconnection attempts - UserAgent = HttpUtils.GenerateUserAgent() // Set Random User-Agent + UserAgent = HttpUtils.GenerateUserAgent() // Set Random User-Agent, + MaxReciveBufferSize = 3147483647 // Maximum size of the response body. }) { HttpResponse postResponse = await client.Post("https://example.com/", "name=value"); @@ -36,6 +36,7 @@ using(HttpClient client = new HttpClient string getResponse = await client.GetString("https://example.com/"); JToken getJsonResponse = await client.GetJson("https://example.com/list.json"); + Modal getJsonResponse = await client.GetJson("https://example.com/list.json"); } ``` @@ -71,7 +72,7 @@ HttpClient client = new HttpClient("Base URL") | `await client.GetStream("http://example.com/");` | Makes a GET request and returns a response MemoryStream | | `await client.GetString("http://example.com/");` | Makes a GET request and returns a response ToString | | `await client.GetJson("http://example.com/");` | Makes a GET request and returns a response JToken [JSON] | -| `await client.GetToFile("http://example.com/", "Save path");` | Makes a GET request and save file | +| `await client.GetJson("http://example.com/");` | Makes a GET request and returns a response T [Object] | | `await client.Post("http://example.com/", "id=0&message=test");` | Simple POST request, supports up to 5 reload | | `await client.Raw(HttpMethod.DELETE, "http://example.com/");` | Raw method, can accept any parameters included in HttpContent | @@ -125,8 +126,10 @@ string body = await response.Content.ReadAsString(); MemoryStream stream = await response.Content.ReadAsStream(); byte[] bytes = await response.Content.ReadAsBytes(); JToken json = await response.Content.ReadAsJson(); +Modal json = await response.Content.ReadAsJson(); -string path = await response.ToFile("Path to save", "Filename"); // If you do not specify a Filename, the client will try to find the file name, and save it, otherwise you will get an error +string path = await response.Content.ToFile("/etc/filename.pack"); +string path = await response.Content.ToFile("Path to save", "Filename"); // If you do not specify a Filename, the client will try to find the file name, and save it, otherwise you will get an error ``` --- @@ -152,8 +155,6 @@ Supports both default requests and WebDAV | LOCK | Put a lock on the object | | UNLOCK | Unlock a resource | ---- - ### TODO -- [x] Proxy Authorization \ No newline at end of file +- [] HtmlParser to Regex \ No newline at end of file diff --git a/Yove.Http.csproj b/Yove.Http.csproj index 55fcb74..0befee0 100644 --- a/Yove.Http.csproj +++ b/Yove.Http.csproj @@ -6,7 +6,8 @@ true snupkg Yove.Http - 1.6.8 + 1.7.0 + beta Sunny en-US, ru-RU Http Client for .Net | Http, Socks4, Socks5 client @@ -15,13 +16,15 @@ https://github.com/TheSuunny/Yove.Http false git + MIT - - - - - + + + + + + \ No newline at end of file