* add support for per-request headers * remove unnecessary usings4.0
| @@ -30,9 +30,13 @@ namespace Discord.Net.Rest | |||
| /// <param name="cancelToken">The cancellation token used to cancel the task.</param> | |||
| /// <param name="headerOnly">Indicates whether to send the header only.</param> | |||
| /// <param name="reason">The audit log reason.</param> | |||
| /// <param name="requestHeaders">Additional headers to be sent with the request.</param> | |||
| /// <returns></returns> | |||
| Task<RestResponse> SendAsync(string method, string endpoint, CancellationToken cancelToken, bool headerOnly = false, string reason = null); | |||
| Task<RestResponse> SendAsync(string method, string endpoint, string json, CancellationToken cancelToken, bool headerOnly = false, string reason = null); | |||
| Task<RestResponse> SendAsync(string method, string endpoint, IReadOnlyDictionary<string, object> multipartParams, CancellationToken cancelToken, bool headerOnly = false, string reason = null); | |||
| Task<RestResponse> SendAsync(string method, string endpoint, CancellationToken cancelToken, bool headerOnly = false, string reason = null, | |||
| IEnumerable<KeyValuePair<string, IEnumerable<string>>> requestHeaders = null); | |||
| Task<RestResponse> SendAsync(string method, string endpoint, string json, CancellationToken cancelToken, bool headerOnly = false, string reason = null, | |||
| IEnumerable<KeyValuePair<string, IEnumerable<string>>> requestHeaders = null); | |||
| Task<RestResponse> SendAsync(string method, string endpoint, IReadOnlyDictionary<string, object> multipartParams, CancellationToken cancelToken, bool headerOnly = false, string reason = null, | |||
| IEnumerable<KeyValuePair<string, IEnumerable<string>>> requestHeaders = null); | |||
| } | |||
| } | |||
| @@ -1,5 +1,6 @@ | |||
| using Discord.Net; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Threading; | |||
| using System.Threading.Tasks; | |||
| @@ -19,7 +20,7 @@ namespace Discord | |||
| /// Gets or sets the maximum time to wait for this request to complete. | |||
| /// </summary> | |||
| /// <remarks> | |||
| /// Gets or set the max time, in milliseconds, to wait for this request to complete. If | |||
| /// Gets or set the max time, in milliseconds, to wait for this request to complete. If | |||
| /// <c>null</c>, a request will not time out. If a rate limit has been triggered for this request's bucket | |||
| /// and will not be unpaused in time, this request will fail immediately. | |||
| /// </remarks> | |||
| @@ -53,7 +54,7 @@ namespace Discord | |||
| /// </summary> | |||
| /// <remarks> | |||
| /// This property can also be set in <see cref="DiscordConfig"/>. | |||
| /// On a per-request basis, the system clock should only be disabled | |||
| /// On a per-request basis, the system clock should only be disabled | |||
| /// when millisecond precision is especially important, and the | |||
| /// hosting system is known to have a desynced clock. | |||
| /// </remarks> | |||
| @@ -69,9 +70,10 @@ namespace Discord | |||
| internal bool IsClientBucket { get; set; } | |||
| internal bool IsReactionBucket { get; set; } | |||
| internal bool IsGatewayBucket { get; set; } | |||
| internal IDictionary<string, IEnumerable<string?>> RequestHeaders { get; } | |||
| internal static RequestOptions CreateOrClone(RequestOptions options) | |||
| { | |||
| { | |||
| if (options == null) | |||
| return new RequestOptions(); | |||
| else | |||
| @@ -96,8 +98,9 @@ namespace Discord | |||
| public RequestOptions() | |||
| { | |||
| Timeout = DiscordConfig.DefaultRequestTimeout; | |||
| RequestHeaders = new Dictionary<string, IEnumerable<string?>>(); | |||
| } | |||
| public RequestOptions Clone() => MemberwiseClone() as RequestOptions; | |||
| } | |||
| } | |||
| @@ -66,33 +66,45 @@ namespace Discord.Net.Rest | |||
| _cancelToken = cancelToken; | |||
| } | |||
| public async Task<RestResponse> SendAsync(string method, string endpoint, CancellationToken cancelToken, bool headerOnly, string reason = null) | |||
| public async Task<RestResponse> SendAsync(string method, string endpoint, CancellationToken cancelToken, bool headerOnly, string reason = null, | |||
| IEnumerable<KeyValuePair<string, IEnumerable<string>>> requestHeaders = null) | |||
| { | |||
| string uri = Path.Combine(_baseUrl, endpoint); | |||
| using (var restRequest = new HttpRequestMessage(GetMethod(method), uri)) | |||
| { | |||
| if (reason != null) restRequest.Headers.Add("X-Audit-Log-Reason", Uri.EscapeDataString(reason)); | |||
| if (requestHeaders != null) | |||
| foreach (var header in requestHeaders) | |||
| restRequest.Headers.Add(header.Key, header.Value); | |||
| return await SendInternalAsync(restRequest, cancelToken, headerOnly).ConfigureAwait(false); | |||
| } | |||
| } | |||
| public async Task<RestResponse> SendAsync(string method, string endpoint, string json, CancellationToken cancelToken, bool headerOnly, string reason = null) | |||
| public async Task<RestResponse> SendAsync(string method, string endpoint, string json, CancellationToken cancelToken, bool headerOnly, string reason = null, | |||
| IEnumerable<KeyValuePair<string, IEnumerable<string>>> requestHeaders = null) | |||
| { | |||
| string uri = Path.Combine(_baseUrl, endpoint); | |||
| using (var restRequest = new HttpRequestMessage(GetMethod(method), uri)) | |||
| { | |||
| if (reason != null) restRequest.Headers.Add("X-Audit-Log-Reason", Uri.EscapeDataString(reason)); | |||
| if (requestHeaders != null) | |||
| foreach (var header in requestHeaders) | |||
| restRequest.Headers.Add(header.Key, header.Value); | |||
| restRequest.Content = new StringContent(json, Encoding.UTF8, "application/json"); | |||
| return await SendInternalAsync(restRequest, cancelToken, headerOnly).ConfigureAwait(false); | |||
| } | |||
| } | |||
| /// <exception cref="InvalidOperationException">Unsupported param type.</exception> | |||
| public async Task<RestResponse> SendAsync(string method, string endpoint, IReadOnlyDictionary<string, object> multipartParams, CancellationToken cancelToken, bool headerOnly, string reason = null) | |||
| public async Task<RestResponse> SendAsync(string method, string endpoint, IReadOnlyDictionary<string, object> multipartParams, CancellationToken cancelToken, bool headerOnly, string reason = null, | |||
| IEnumerable<KeyValuePair<string, IEnumerable<string>>> requestHeaders = null) | |||
| { | |||
| string uri = Path.Combine(_baseUrl, endpoint); | |||
| using (var restRequest = new HttpRequestMessage(GetMethod(method), uri)) | |||
| { | |||
| if (reason != null) restRequest.Headers.Add("X-Audit-Log-Reason", Uri.EscapeDataString(reason)); | |||
| if (requestHeaders != null) | |||
| foreach (var header in requestHeaders) | |||
| restRequest.Headers.Add(header.Key, header.Value); | |||
| var content = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture)); | |||
| MemoryStream memoryStream = null; | |||
| if (multipartParams != null) | |||
| @@ -126,7 +138,7 @@ namespace Discord.Net.Rest | |||
| content.Add(streamContent, p.Key, fileValue.Filename); | |||
| #pragma warning restore IDISP004 | |||
| continue; | |||
| } | |||
| default: | |||
| @@ -28,7 +28,7 @@ namespace Discord.Net.Queue | |||
| public virtual async Task<RestResponse> SendAsync() | |||
| { | |||
| return await Client.SendAsync(Method, Endpoint, Options.CancelToken, Options.HeaderOnly, Options.AuditLogReason).ConfigureAwait(false); | |||
| return await Client.SendAsync(Method, Endpoint, Options.CancelToken, Options.HeaderOnly, Options.AuditLogReason, Options.RequestHeaders).ConfigureAwait(false); | |||
| } | |||
| } | |||
| } | |||