// Copyright (c) Richasy. All rights reserved. using System; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json; using Richasy.Bili.Lib.Interfaces; using Richasy.Bili.Models.App.Constants; using Richasy.Bili.Models.App.Other; using Richasy.Bili.Models.BiliBili; namespace Richasy.Bili.Lib.Uwp { /// /// 用于网络请求模块的内部方法. /// public partial class HttpProvider { private readonly IAuthorizeProvider _authenticationProvider; private HttpClient _httpClient; private bool _disposedValue; private CookieContainer _cookieContainer; /// public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } internal async Task SendRequestAsync( HttpRequestMessage request, CancellationToken cancellationToken) { HttpResponseMessage response = null; try { response = await this._httpClient.SendAsync(request, cancellationToken); await ThrowIfHasExceptionAsync(response); } catch (TaskCanceledException exception) { throw new ServiceException( new ServerResponse { Code = 408, Message = ServiceConstants.Messages.RequestTimedOut, }, exception); } catch (ServiceException exception) { throw exception; } catch (Exception exception) { throw new ServiceException( new ServerResponse { Message = ServiceConstants.Messages.UnexpectedExceptionOnSend, }, exception); } return response; } /// /// Dispose object. /// /// Is it disposing. protected virtual void Dispose(bool disposing) { if (!_disposedValue) { if (disposing) { if (this._httpClient != null) { this._httpClient.Dispose(); } } this._httpClient = null; _disposedValue = true; } } private void InitHttpClient() { _cookieContainer = new CookieContainer(); var handler = new HttpClientHandler { AllowAutoRedirect = false, AutomaticDecompression = DecompressionMethods.None, UseCookies = true, CookieContainer = _cookieContainer, }; var client = new HttpClient(handler); client.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue { NoCache = false, NoStore = false }; client.DefaultRequestHeaders.Add("accept", ServiceConstants.DefaultAcceptString); this._httpClient = client; } private async Task ThrowIfHasExceptionAsync(HttpResponseMessage response) { ServerResponse errorResponse = null; try { var errorResponseStr = await response.Content.ReadAsStringAsync(); if (response.Content.Headers.ContentType?.MediaType.Contains("image") ?? false) { if (response.IsSuccessStatusCode) { return; } } errorResponse = JsonConvert.DeserializeObject(errorResponseStr); if (errorResponse?.Code == 0 || string.IsNullOrEmpty(errorResponseStr)) { return; } } catch (Exception) { } if (errorResponse == null || !response.IsSuccessStatusCode) { if (response != null && response.StatusCode == HttpStatusCode.NotFound) { errorResponse = new ServerResponse { Message = ServiceConstants.Messages.NotFound }; } else { errorResponse = new ServerResponse { Message = ServiceConstants.Messages.UnexpectedExceptionResponse, }; } } if (response.Content?.Headers.ContentType?.MediaType == ServiceConstants.Headers.JsonContentType) { var rawResponseBody = await response.Content.ReadAsStringAsync(); throw new ServiceException( errorResponse, response.Headers, response.StatusCode, rawResponseBody, null); } else { // 将响应头和状态代码传递给ServiceException。 // System.Net.HttpStatusCode不支持RFC 6585,附加HTTP状态代码。 // 节流状态代码429是在RFC 6586中。状态码429将被传递过去。 throw new ServiceException(errorResponse, response.Headers, response.StatusCode); } } } }