* 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); | |||||
} | } | ||||
} | } | ||||
} | } |