123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459 |
- using System;
- using System.Net;
- using System.Threading;
- using System.Threading.Tasks;
- namespace NetCoreServer
- {
-
-
-
-
- public class HttpsClient : SslClient
- {
-
-
-
-
-
-
- public HttpsClient(SslContext context, IPAddress address, int port) : base(context, address, port) { Request = new HttpRequest(); Response = new HttpResponse(); }
-
-
-
-
-
-
- public HttpsClient(SslContext context, string address, int port) : base(context, address, port) { Request = new HttpRequest(); Response = new HttpResponse(); }
-
-
-
-
-
- public HttpsClient(SslContext context, DnsEndPoint endpoint) : base(context, endpoint) { Request = new HttpRequest(); Response = new HttpResponse(); }
-
-
-
-
-
- public HttpsClient(SslContext context, IPEndPoint endpoint) : base(context, endpoint) { Request = new HttpRequest(); Response = new HttpResponse(); }
-
-
-
- public HttpRequest Request { get; protected set; }
-
-
-
- protected HttpResponse Response { get; set; }
- #region Send request / Send request body
-
-
-
-
- public long SendRequest() => SendRequest(Request);
-
-
-
-
-
- public long SendRequest(HttpRequest request) => Send(request.Cache.Data, request.Cache.Offset, request.Cache.Size);
-
-
-
-
-
- public long SendRequestBody(string body) => Send(body);
-
-
-
-
-
- public long SendRequestBody(ReadOnlySpan<char> body) => Send(body);
-
-
-
-
-
- public long SendRequestBody(byte[] buffer) => Send(buffer);
-
-
-
-
-
-
-
- public long SendRequestBody(byte[] buffer, long offset, long size) => Send(buffer, offset, size);
-
-
-
-
-
- public long SendRequestBody(ReadOnlySpan<byte> buffer) => Send(buffer);
-
-
-
-
- public bool SendRequestAsync() => SendRequestAsync(Request);
-
-
-
-
-
- public bool SendRequestAsync(HttpRequest request) => SendAsync(request.Cache.Data, request.Cache.Offset, request.Cache.Size);
-
-
-
-
-
- public bool SendRequestBodyAsync(string body) => SendAsync(body);
-
-
-
-
-
- public bool SendRequestBodyAsync(ReadOnlySpan<char> body) => SendAsync(body);
-
-
-
-
-
- public bool SendRequestBodyAsync(byte[] buffer) => SendAsync(buffer);
-
-
-
-
-
-
-
- public bool SendRequestBodyAsync(byte[] buffer, long offset, long size) => SendAsync(buffer, offset, size);
-
-
-
-
-
- public bool SendRequestBodyAsync(ReadOnlySpan<byte> buffer) => SendAsync(buffer);
- #endregion
- #region Session handlers
- protected override void OnReceived(byte[] buffer, long offset, long size)
- {
-
- if (Response.IsPendingHeader())
- {
- if (Response.ReceiveHeader(buffer, (int)offset, (int)size))
- OnReceivedResponseHeader(Response);
- size = 0;
- }
-
- if (Response.IsErrorSet)
- {
- OnReceivedResponseError(Response, "Invalid HTTP response!");
- Response.Clear();
- Disconnect();
- return;
- }
-
- if (Response.ReceiveBody(buffer, (int)offset, (int)size))
- {
- OnReceivedResponse(Response);
- Response.Clear();
- return;
- }
-
- if (Response.IsErrorSet)
- {
- OnReceivedResponseError(Response, "Invalid HTTP response!");
- Response.Clear();
- Disconnect();
- return;
- }
- }
- protected override void OnDisconnected()
- {
-
- if (Response.IsPendingBody())
- {
- OnReceivedResponse(Response);
- Response.Clear();
- return;
- }
- }
-
-
-
-
-
- protected virtual void OnReceivedResponseHeader(HttpResponse response) {}
-
-
-
-
-
- protected virtual void OnReceivedResponse(HttpResponse response) {}
-
-
-
-
-
-
- protected virtual void OnReceivedResponseError(HttpResponse response, string error) {}
- #endregion
- }
-
-
-
-
- public class HttpsClientEx : HttpsClient
- {
-
-
-
-
-
-
- public HttpsClientEx(SslContext context, IPAddress address, int port) : base(context, address, port) {}
-
-
-
-
-
-
- public HttpsClientEx(SslContext context, string address, int port) : base(context, address, port) {}
-
-
-
-
-
- public HttpsClientEx(SslContext context, DnsEndPoint endpoint) : base(context, endpoint) {}
-
-
-
-
-
- public HttpsClientEx(SslContext context, IPEndPoint endpoint) : base(context, endpoint) {}
- #region Send request
-
-
-
-
-
- public Task<HttpResponse> SendRequest(TimeSpan? timeout = null) => SendRequest(Request, timeout);
-
-
-
-
-
-
- public Task<HttpResponse> SendRequest(HttpRequest request, TimeSpan? timeout = null)
- {
- timeout ??= TimeSpan.FromMinutes(1);
- _tcs = new TaskCompletionSource<HttpResponse>();
- Request = request;
-
- if (Request.IsEmpty || Request.IsErrorSet)
- {
- SetResultError("Invalid HTTP request!");
- return _tcs.Task;
- }
- if (!IsHandshaked)
- {
-
- if (!ConnectAsync())
- {
- SetResultError("Connection failed!");
- return _tcs.Task;
- }
- }
- else
- {
-
- if (!SendRequestAsync())
- {
- SetResultError("Failed to send HTTP request!");
- return _tcs.Task;
- }
- }
- void TimeoutHandler(object state)
- {
-
- OnReceivedResponseError(Response, "Timeout!");
- Response.Clear();
- DisconnectAsync();
- }
-
- if (_timer == null)
- _timer = new Timer(TimeoutHandler, null, Timeout.Infinite, Timeout.Infinite);
-
- _timer.Change((int)timeout.Value.TotalMilliseconds, Timeout.Infinite);
- return _tcs.Task;
- }
-
-
-
-
-
-
- public Task<HttpResponse> SendHeadRequest(string url, TimeSpan? timeout = null) => SendRequest(Request.MakeHeadRequest(url), timeout);
-
-
-
-
-
-
- public Task<HttpResponse> SendGetRequest(string url, TimeSpan? timeout = null) => SendRequest(Request.MakeGetRequest(url), timeout);
-
-
-
-
-
-
-
- public Task<HttpResponse> SendPostRequest(string url, string content, TimeSpan? timeout = null) => SendRequest(Request.MakePostRequest(url, content), timeout);
-
-
-
-
-
-
-
- public Task<HttpResponse> SendPutRequest(string url, string content, TimeSpan? timeout = null) => SendRequest(Request.MakePutRequest(url, content), timeout);
-
-
-
-
-
-
- public Task<HttpResponse> SendDeleteRequest(string url, TimeSpan? timeout = null) => SendRequest(Request.MakeDeleteRequest(url), timeout);
-
-
-
-
-
-
- public Task<HttpResponse> SendOptionsRequest(string url, TimeSpan? timeout = null) => SendRequest(Request.MakeOptionsRequest(url), timeout);
-
-
-
-
-
-
- public Task<HttpResponse> SendTraceRequest(string url, TimeSpan? timeout = null) => SendRequest(Request.MakeTraceRequest(url), timeout);
- #endregion
- #region Session handlers
- protected override void OnHandshaked()
- {
-
- if (!Request.IsEmpty && !Request.IsErrorSet)
- if (!SendRequestAsync())
- SetResultError("Failed to send HTTP request!");
- }
- protected override void OnDisconnected()
- {
-
- _timer?.Change(Timeout.Infinite, Timeout.Infinite);
- base.OnDisconnected();
- }
- protected override void OnReceivedResponse(HttpResponse response)
- {
-
- _timer?.Change(Timeout.Infinite, Timeout.Infinite);
- SetResultValue(response);
- }
- protected override void OnReceivedResponseError(HttpResponse response, string error)
- {
-
- _timer?.Change(Timeout.Infinite, Timeout.Infinite);
- SetResultError(error);
- }
- #endregion
- private TaskCompletionSource<HttpResponse> _tcs = new TaskCompletionSource<HttpResponse>();
- private Timer _timer;
- private void SetResultValue(HttpResponse response)
- {
- Response = new HttpResponse();
- _tcs.SetResult(response);
- Request.Clear();
- }
- private void SetResultError(string error)
- {
- _tcs.SetException(new Exception(error));
- Request.Clear();
- }
- #region IDisposable implementation
-
- private bool _disposed;
- protected override void Dispose(bool disposingManagedResources)
- {
- if (!_disposed)
- {
- if (disposingManagedResources)
- {
-
- _timer?.Dispose();
- }
-
-
-
- _disposed = true;
- }
-
- base.Dispose(disposingManagedResources);
- }
-
-
-
- #endregion
- }
- }
|