using Maki.Structures.Rest;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
namespace Maki.Rest
{
///
/// Handles requests to Discord's REST API
///
internal class RestClient
{
///
/// User agent that is send alongside requests
///
private const string USER_AGENT = @"DiscordBot (https://github.com/flashwave/nicobot)";
///
/// Container for parent DiscordClient instance
///
private readonly Discord client;
///
/// Request types that should be handled as data requests
///
private readonly RestRequestMethod[] dataRequestTypes = new RestRequestMethod[] {
RestRequestMethod.POST,
RestRequestMethod.PUT,
RestRequestMethod.PATCH,
};
///
/// Constructor
///
/// Parent DiscordClient instance
public RestClient(Discord c)
{
client = c;
}
///
/// Creates a base HttpWebRequest
///
/// Request method
/// Endpoint url
/// Prepared HttpWebRequest
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;
}
///
/// Gets a response string from HttpWebRequest
///
/// HttpWebRequest instance
/// string output
private RestResponse HandleResponse(HttpWebRequest request)
{
HttpWebResponse webResponse;
RestResponse response = new RestResponse();
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(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;
}
Console.WriteLine(response.RawResponse);
if (response.Status == 200)
response.Response = JsonConvert.DeserializeObject(response.RawResponse);
return response;
}
///
/// Make a json request
///
/// Type to use when deserialising the JSON object
/// Request method
/// Endpoint url
/// Request data
/// Deserialised JSON object
public RestResponse Request(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(request);
}
}
}