Archived
1
0
Fork 0
This repository has been archived on 2024-05-21. You can view files and clone it, but cannot push or open issues or pull requests.
maki/Maki/Rest/RestClient.cs
2017-05-19 01:04:45 +02:00

150 lines
4.9 KiB
C#

using Maki.Structures.Rest;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
namespace Maki.Rest
{
/// <summary>
/// Handles requests to Discord's REST API
/// </summary>
internal class RestClient
{
/// <summary>
/// User agent that is send alongside requests
/// </summary>
private const string USER_AGENT = @"DiscordBot (https://github.com/flashwave/maki, 1.0.0.0)";
/// <summary>
/// Container for parent DiscordClient instance
/// </summary>
private readonly Discord client;
/// <summary>
/// Request types that should be handled as data requests
/// </summary>
private readonly RestRequestMethod[] dataRequestTypes = new RestRequestMethod[] {
RestRequestMethod.POST,
RestRequestMethod.PUT,
RestRequestMethod.PATCH,
};
/// <summary>
/// Constructor
/// </summary>
/// <param name="c">Parent DiscordClient instance</param>
public RestClient(Discord c)
{
client = c;
}
/// <summary>
/// Creates a base HttpWebRequest
/// </summary>
/// <param name="method">Request method</param>
/// <param name="url">Endpoint url</param>
/// <returns>Prepared HttpWebRequest</returns>
private HttpWebRequest BaseRequest(RestRequestMethod method, string url)
{
Uri uri = new Uri(RestEndpoints.BASE_URL + RestEndpoints.BASE_PATH + url);
HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
request.Method = method.ToString();
request.UserAgent = USER_AGENT;
if (!string.IsNullOrEmpty(client.Token))
request.Headers[HttpRequestHeader.Authorization] = (client.IsBot ? "Bot " : string.Empty) + client.Token;
return request;
}
/// <summary>
/// Gets a response string from HttpWebRequest
/// </summary>
/// <param name="request">HttpWebRequest instance</param>
/// <returns>string output</returns>
private RestResponse<T> HandleResponse<T>(HttpWebRequest request)
{
HttpWebResponse webResponse;
RestResponse<T> response = new RestResponse<T>();
try
{
webResponse = request.GetResponse() as HttpWebResponse;
}
catch (WebException ex)
{
webResponse = ex.Response as HttpWebResponse;
}
Enum.TryParse(webResponse.Method, out response.Method);
response.Uri = webResponse.ResponseUri;
response.Status = (ushort)webResponse.StatusCode;
using (Stream httpResponseStream = webResponse.GetResponseStream())
using (StreamReader streamReader = new StreamReader(httpResponseStream))
response.RawResponse = streamReader.ReadToEnd();
webResponse.Close();
Error error = default(Error);
try
{
error = JsonConvert.DeserializeObject<Error>(response.RawResponse);
}
catch
{
}
if (error.Equals(default(Error)))
{
response.ErrorCode = RestErrorCode.Ok;
response.ErrorMessage = string.Empty;
}
else
{
response.ErrorCode = (RestErrorCode)error.Code;
response.ErrorMessage = error.Message;
}
if (client.LogRest)
Console.WriteLine(response.RawResponse);
if (response.Status == 200)
response.Response = JsonConvert.DeserializeObject<T>(response.RawResponse);
return response;
}
/// <summary>
/// Make a json request
/// </summary>
/// <typeparam name="T">Type to use when deserialising the JSON object</typeparam>
/// <param name="method">Request method</param>
/// <param name="url">Endpoint url</param>
/// <param name="data">Request data</param>
/// <returns>Deserialised JSON object</returns>
public RestResponse<T> Request<T>(RestRequestMethod method, string url, object data = null)
{
HttpWebRequest request = BaseRequest(method, url);
request.ContentType = "application/json;charset=utf-8";
request.ContentLength = 0;
if (dataRequestTypes.Contains(method) && data != null)
{
byte[] bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data));
request.ContentLength = bytes.LongLength;
using (Stream requestStream = request.GetRequestStream())
requestStream.Write(bytes, 0, bytes.Length);
}
return HandleResponse<T>(request);
}
}
}