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