Improved all things HTTP related
This commit is contained in:
@@ -37,6 +37,7 @@
|
|||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
|||||||
@@ -9,109 +9,108 @@ namespace Discord.API
|
|||||||
public const int MaxMessageSize = 2000;
|
public const int MaxMessageSize = 2000;
|
||||||
|
|
||||||
//Auth
|
//Auth
|
||||||
public static async Task<APIResponses.AuthRegister> LoginAnonymous(string username, HttpOptions options)
|
public static async Task<APIResponses.AuthRegister> LoginAnonymous(string username)
|
||||||
{
|
{
|
||||||
var fingerprintResponse = await Http.Post<APIResponses.AuthFingerprint>(Endpoints.AuthFingerprint, options);
|
var fingerprintResponse = await Http.Post<APIResponses.AuthFingerprint>(Endpoints.AuthFingerprint);
|
||||||
var registerRequest = new APIRequests.AuthRegisterRequest { Fingerprint = fingerprintResponse.Fingerprint, Username = username };
|
var registerRequest = new APIRequests.AuthRegisterRequest { Fingerprint = fingerprintResponse.Fingerprint, Username = username };
|
||||||
var registerResponse = await Http.Post<APIResponses.AuthRegister>(Endpoints.AuthRegister, registerRequest, options);
|
var registerResponse = await Http.Post<APIResponses.AuthRegister>(Endpoints.AuthRegister, registerRequest);
|
||||||
return registerResponse;
|
return registerResponse;
|
||||||
}
|
}
|
||||||
public static async Task<APIResponses.AuthLogin> Login(string email, string password, HttpOptions options)
|
public static async Task<APIResponses.AuthLogin> Login(string email, string password)
|
||||||
{
|
{
|
||||||
var request = new APIRequests.AuthLogin { Email = email, Password = password };
|
var request = new APIRequests.AuthLogin { Email = email, Password = password };
|
||||||
var response = await Http.Post<APIResponses.AuthLogin>(Endpoints.AuthLogin, request, options);
|
var response = await Http.Post<APIResponses.AuthLogin>(Endpoints.AuthLogin, request);
|
||||||
options.Token = response.Token;
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
public static Task Logout(HttpOptions options)
|
public static Task Logout()
|
||||||
=> Http.Post(Endpoints.AuthLogout, options);
|
=> Http.Post(Endpoints.AuthLogout);
|
||||||
|
|
||||||
//Servers
|
//Servers
|
||||||
public static Task<APIResponses.CreateServer> CreateServer(string name, string region, HttpOptions options)
|
public static Task<APIResponses.CreateServer> CreateServer(string name, string region)
|
||||||
{
|
{
|
||||||
var request = new APIRequests.CreateServer { Name = name, Region = region };
|
var request = new APIRequests.CreateServer { Name = name, Region = region };
|
||||||
return Http.Post<APIResponses.CreateServer>(Endpoints.Servers, request, options);
|
return Http.Post<APIResponses.CreateServer>(Endpoints.Servers, request);
|
||||||
}
|
}
|
||||||
public static Task LeaveServer(string id, HttpOptions options)
|
public static Task LeaveServer(string id)
|
||||||
=> Http.Delete<APIResponses.DeleteServer>(Endpoints.Server(id), options);
|
=> Http.Delete<APIResponses.DeleteServer>(Endpoints.Server(id));
|
||||||
|
|
||||||
//Channels
|
//Channels
|
||||||
public static Task<APIResponses.CreateChannel> CreateChannel(string serverId, string name, string channelType, HttpOptions options)
|
public static Task<APIResponses.CreateChannel> CreateChannel(string serverId, string name, string channelType)
|
||||||
{
|
{
|
||||||
var request = new APIRequests.CreateChannel { Name = name, Type = channelType };
|
var request = new APIRequests.CreateChannel { Name = name, Type = channelType };
|
||||||
return Http.Post<APIResponses.CreateChannel>(Endpoints.ServerChannels(serverId), request, options);
|
return Http.Post<APIResponses.CreateChannel>(Endpoints.ServerChannels(serverId), request);
|
||||||
}
|
}
|
||||||
public static Task<APIResponses.CreateChannel> CreatePMChannel(string myId, string recipientId, HttpOptions options)
|
public static Task<APIResponses.CreateChannel> CreatePMChannel(string myId, string recipientId)
|
||||||
{
|
{
|
||||||
var request = new APIRequests.CreatePMChannel { RecipientId = recipientId };
|
var request = new APIRequests.CreatePMChannel { RecipientId = recipientId };
|
||||||
return Http.Post<APIResponses.CreateChannel>(Endpoints.UserChannels(myId), request, options);
|
return Http.Post<APIResponses.CreateChannel>(Endpoints.UserChannels(myId), request);
|
||||||
}
|
}
|
||||||
public static Task<APIResponses.DestroyChannel> DestroyChannel(string channelId, HttpOptions options)
|
public static Task<APIResponses.DestroyChannel> DestroyChannel(string channelId)
|
||||||
=> Http.Delete<APIResponses.DestroyChannel>(Endpoints.Channel(channelId), options);
|
=> Http.Delete<APIResponses.DestroyChannel>(Endpoints.Channel(channelId));
|
||||||
public static Task<APIResponses.GetMessages[]> GetMessages(string channelId, int count, HttpOptions options)
|
public static Task<APIResponses.GetMessages[]> GetMessages(string channelId, int count)
|
||||||
=> Http.Get<APIResponses.GetMessages[]>(Endpoints.ChannelMessages(channelId, count), options);
|
=> Http.Get<APIResponses.GetMessages[]>(Endpoints.ChannelMessages(channelId, count));
|
||||||
|
|
||||||
//Members
|
//Members
|
||||||
public static Task Kick(string serverId, string memberId, HttpOptions options)
|
public static Task Kick(string serverId, string memberId)
|
||||||
=> Http.Delete(Endpoints.ServerMember(serverId, memberId), options);
|
=> Http.Delete(Endpoints.ServerMember(serverId, memberId));
|
||||||
public static Task Ban(string serverId, string memberId, HttpOptions options)
|
public static Task Ban(string serverId, string memberId)
|
||||||
=> Http.Put(Endpoints.ServerBan(serverId, memberId), options);
|
=> Http.Put(Endpoints.ServerBan(serverId, memberId));
|
||||||
public static Task Unban(string serverId, string memberId, HttpOptions options)
|
public static Task Unban(string serverId, string memberId)
|
||||||
=> Http.Delete(Endpoints.ServerBan(serverId, memberId), options);
|
=> Http.Delete(Endpoints.ServerBan(serverId, memberId));
|
||||||
|
|
||||||
//Invites
|
//Invites
|
||||||
public static Task<APIResponses.CreateInvite> CreateInvite(string channelId, int maxAge, int maxUses, bool isTemporary, bool hasXkcdPass, HttpOptions options)
|
public static Task<APIResponses.CreateInvite> CreateInvite(string channelId, int maxAge, int maxUses, bool isTemporary, bool hasXkcdPass)
|
||||||
{
|
{
|
||||||
var request = new APIRequests.CreateInvite { MaxAge = maxAge, MaxUses = maxUses, IsTemporary = isTemporary, HasXkcdPass = hasXkcdPass };
|
var request = new APIRequests.CreateInvite { MaxAge = maxAge, MaxUses = maxUses, IsTemporary = isTemporary, HasXkcdPass = hasXkcdPass };
|
||||||
return Http.Post<APIResponses.CreateInvite>(Endpoints.ChannelInvites(channelId), request, options);
|
return Http.Post<APIResponses.CreateInvite>(Endpoints.ChannelInvites(channelId), request);
|
||||||
}
|
}
|
||||||
public static Task<APIResponses.GetInvite> GetInvite(string id, HttpOptions options)
|
public static Task<APIResponses.GetInvite> GetInvite(string id)
|
||||||
=> Http.Get<APIResponses.GetInvite>(Endpoints.Invite(id), options);
|
=> Http.Get<APIResponses.GetInvite>(Endpoints.Invite(id));
|
||||||
public static Task AcceptInvite(string id, HttpOptions options)
|
public static Task AcceptInvite(string id)
|
||||||
=> Http.Post<APIResponses.AcceptInvite>(Endpoints.Invite(id), options);
|
=> Http.Post<APIResponses.AcceptInvite>(Endpoints.Invite(id));
|
||||||
public static Task DeleteInvite(string id, HttpOptions options)
|
public static Task DeleteInvite(string id)
|
||||||
=> Http.Delete(Endpoints.Invite(id), options);
|
=> Http.Delete(Endpoints.Invite(id));
|
||||||
|
|
||||||
//Chat
|
//Chat
|
||||||
public static Task<APIResponses.SendMessage> SendMessage(string channelId, string message, string[] mentions, HttpOptions options)
|
public static Task<APIResponses.SendMessage> SendMessage(string channelId, string message, string[] mentions)
|
||||||
{
|
{
|
||||||
var request = new APIRequests.SendMessage { Content = message, Mentions = mentions };
|
var request = new APIRequests.SendMessage { Content = message, Mentions = mentions };
|
||||||
return Http.Post<APIResponses.SendMessage>(Endpoints.ChannelMessages(channelId), request, options);
|
return Http.Post<APIResponses.SendMessage>(Endpoints.ChannelMessages(channelId), request);
|
||||||
}
|
}
|
||||||
public static Task<APIResponses.EditMessage> EditMessage(string channelId, string messageId, string message, string[] mentions, HttpOptions options)
|
public static Task<APIResponses.EditMessage> EditMessage(string channelId, string messageId, string message, string[] mentions)
|
||||||
{
|
{
|
||||||
var request = new APIRequests.EditMessage { Content = message, Mentions = mentions };
|
var request = new APIRequests.EditMessage { Content = message, Mentions = mentions };
|
||||||
return Http.Patch<APIResponses.EditMessage>(Endpoints.ChannelMessage(channelId, messageId), request, options);
|
return Http.Patch<APIResponses.EditMessage>(Endpoints.ChannelMessage(channelId, messageId), request);
|
||||||
}
|
}
|
||||||
public static Task SendIsTyping(string channelId, HttpOptions options)
|
public static Task SendIsTyping(string channelId)
|
||||||
=> Http.Post(Endpoints.ChannelTyping(channelId), options);
|
=> Http.Post(Endpoints.ChannelTyping(channelId));
|
||||||
public static Task DeleteMessage(string channelId, string msgId, HttpOptions options)
|
public static Task DeleteMessage(string channelId, string msgId)
|
||||||
=> Http.Delete(Endpoints.ChannelMessage(channelId, msgId), options);
|
=> Http.Delete(Endpoints.ChannelMessage(channelId, msgId));
|
||||||
|
|
||||||
//Voice
|
//Voice
|
||||||
public static Task<APIResponses.GetRegions[]> GetVoiceRegions(HttpOptions options)
|
public static Task<APIResponses.GetRegions[]> GetVoiceRegions()
|
||||||
=> Http.Get<APIResponses.GetRegions[]>(Endpoints.VoiceRegions, options);
|
=> Http.Get<APIResponses.GetRegions[]>(Endpoints.VoiceRegions);
|
||||||
public static Task<APIResponses.GetIce> GetVoiceIce(HttpOptions options)
|
public static Task<APIResponses.GetIce> GetVoiceIce()
|
||||||
=> Http.Get<APIResponses.GetIce>(Endpoints.VoiceIce, options);
|
=> Http.Get<APIResponses.GetIce>(Endpoints.VoiceIce);
|
||||||
public static Task Mute(string serverId, string memberId, HttpOptions options)
|
public static Task Mute(string serverId, string memberId)
|
||||||
{
|
{
|
||||||
var request = new APIRequests.SetMemberMute { Mute = true };
|
var request = new APIRequests.SetMemberMute { Mute = true };
|
||||||
return Http.Patch(Endpoints.ServerMember(serverId, memberId), options);
|
return Http.Patch(Endpoints.ServerMember(serverId, memberId));
|
||||||
}
|
}
|
||||||
public static Task Unmute(string serverId, string memberId, HttpOptions options)
|
public static Task Unmute(string serverId, string memberId)
|
||||||
{
|
{
|
||||||
var request = new APIRequests.SetMemberMute { Mute = false };
|
var request = new APIRequests.SetMemberMute { Mute = false };
|
||||||
return Http.Patch(Endpoints.ServerMember(serverId, memberId), options);
|
return Http.Patch(Endpoints.ServerMember(serverId, memberId));
|
||||||
}
|
}
|
||||||
public static Task Deafen(string serverId, string memberId, HttpOptions options)
|
public static Task Deafen(string serverId, string memberId)
|
||||||
{
|
{
|
||||||
var request = new APIRequests.SetMemberDeaf { Deaf = true };
|
var request = new APIRequests.SetMemberDeaf { Deaf = true };
|
||||||
return Http.Patch(Endpoints.ServerMember(serverId, memberId), options);
|
return Http.Patch(Endpoints.ServerMember(serverId, memberId));
|
||||||
}
|
}
|
||||||
public static Task Undeafen(string serverId, string memberId, HttpOptions options)
|
public static Task Undeafen(string serverId, string memberId)
|
||||||
{
|
{
|
||||||
var request = new APIRequests.SetMemberDeaf { Deaf = false };
|
var request = new APIRequests.SetMemberDeaf { Deaf = false };
|
||||||
return Http.Patch(Endpoints.ServerMember(serverId, memberId), options);
|
return Http.Patch(Endpoints.ServerMember(serverId, memberId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ namespace Discord
|
|||||||
public const int FailedReconnectDelay = 10000; //Time in milliseconds to wait after a failed reconnect attempt
|
public const int FailedReconnectDelay = 10000; //Time in milliseconds to wait after a failed reconnect attempt
|
||||||
|
|
||||||
private DiscordWebSocket _webSocket;
|
private DiscordWebSocket _webSocket;
|
||||||
private HttpOptions _httpOptions;
|
|
||||||
private bool _isReady;
|
private bool _isReady;
|
||||||
|
|
||||||
public string UserId { get; private set; }
|
public string UserId { get; private set; }
|
||||||
@@ -45,8 +44,6 @@ namespace Discord
|
|||||||
public DiscordClient()
|
public DiscordClient()
|
||||||
{
|
{
|
||||||
_isStopping = new ManualResetEventSlim(false);
|
_isStopping = new ManualResetEventSlim(false);
|
||||||
string version = typeof(DiscordClient).GetTypeInfo().Assembly.GetName().Version.ToString(2);
|
|
||||||
_httpOptions = new HttpOptions($"Discord.Net/{version} (https://github.com/RogueException/Discord.Net)");
|
|
||||||
|
|
||||||
_servers = new AsyncCache<Server, API.Models.ServerReference>(
|
_servers = new AsyncCache<Server, API.Models.ServerReference>(
|
||||||
(key, parentKey) => new Server(key, this),
|
(key, parentKey) => new Server(key, this),
|
||||||
@@ -160,7 +157,7 @@ namespace Discord
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Task.Delay(ReconnectDelay);
|
await Task.Delay(ReconnectDelay);
|
||||||
await _webSocket.ConnectAsync(Endpoints.WebSocket_Hub, true, _httpOptions);
|
await _webSocket.ConnectAsync(Endpoints.WebSocket_Hub, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
@@ -413,15 +410,26 @@ namespace Discord
|
|||||||
)
|
)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
}
|
}
|
||||||
public User FindChannelUser(Channel channel, string name)
|
public Membership FindMember(string serverId, string name)
|
||||||
=> FindChannelUser(channel.Id, name);
|
=> FindMember(GetServer(serverId), name);
|
||||||
public User FindChannelUser(string channelId, string name)
|
public Membership FindMember(Server server, string name)
|
||||||
{
|
{
|
||||||
|
if (server == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (name.StartsWith("<@") && name.EndsWith(">"))
|
||||||
|
{
|
||||||
|
var user = GetUser(name.Substring(2, name.Length - 3));
|
||||||
|
if (user == null)
|
||||||
|
return null;
|
||||||
|
return server.GetMembership(user.Id);
|
||||||
|
}
|
||||||
|
|
||||||
if (name.StartsWith("@"))
|
if (name.StartsWith("@"))
|
||||||
name = name.Substring(1);
|
name = name.Substring(1);
|
||||||
|
|
||||||
return _users
|
return server.Members
|
||||||
.Where(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase))
|
.Where(x => string.Equals(x.User.Name, name, StringComparison.OrdinalIgnoreCase))
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,9 +444,11 @@ namespace Discord
|
|||||||
public Channel GetChannel(string id) => _channels[id];
|
public Channel GetChannel(string id) => _channels[id];
|
||||||
public Channel FindChannel(string name)
|
public Channel FindChannel(string name)
|
||||||
{
|
{
|
||||||
|
if (name.StartsWith("<#") && name.EndsWith(">"))
|
||||||
|
return GetChannel(name.Substring(2, name.Length - 3));
|
||||||
|
|
||||||
if (name.StartsWith("#"))
|
if (name.StartsWith("#"))
|
||||||
name = name.Substring(1);
|
name = name.Substring(1);
|
||||||
|
|
||||||
return _channels
|
return _channels
|
||||||
.Where(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase))
|
.Where(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase))
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
@@ -447,9 +457,11 @@ namespace Discord
|
|||||||
=> FindChannel(server.Id, name);
|
=> FindChannel(server.Id, name);
|
||||||
public Channel FindChannel(string serverId, string name)
|
public Channel FindChannel(string serverId, string name)
|
||||||
{
|
{
|
||||||
|
if (name.StartsWith("<#") && name.EndsWith(">"))
|
||||||
|
return GetChannel(name.Substring(2, name.Length - 3));
|
||||||
|
|
||||||
if (name.StartsWith("#"))
|
if (name.StartsWith("#"))
|
||||||
name = name.Substring(1);
|
name = name.Substring(1);
|
||||||
|
|
||||||
return _channels
|
return _channels
|
||||||
.Where(x =>
|
.Where(x =>
|
||||||
string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase) &&
|
string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase) &&
|
||||||
@@ -478,7 +490,7 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var msgs = await DiscordAPI.GetMessages(channel.Id, count, _httpOptions);
|
var msgs = await DiscordAPI.GetMessages(channel.Id, count);
|
||||||
return msgs.OrderBy(x => x.Timestamp)
|
return msgs.OrderBy(x => x.Timestamp)
|
||||||
.Select(x =>
|
.Select(x =>
|
||||||
{
|
{
|
||||||
@@ -501,13 +513,13 @@ namespace Discord
|
|||||||
_isStopping.Reset();
|
_isStopping.Reset();
|
||||||
|
|
||||||
//Open websocket while we wait for login response
|
//Open websocket while we wait for login response
|
||||||
Task socketTask = _webSocket.ConnectAsync(Endpoints.WebSocket_Hub, false, _httpOptions);
|
Task socketTask = _webSocket.ConnectAsync(Endpoints.WebSocket_Hub, false);
|
||||||
var response = await DiscordAPI.Login(email, password, _httpOptions);
|
var response = await DiscordAPI.Login(email, password);
|
||||||
_httpOptions.Token = response.Token;
|
Http.Token = response.Token;
|
||||||
|
|
||||||
//Wait for websocket to finish connecting, then send token
|
//Wait for websocket to finish connecting, then send token
|
||||||
await socketTask;
|
await socketTask;
|
||||||
_webSocket.Login(_httpOptions);
|
_webSocket.Login();
|
||||||
|
|
||||||
_isReady = true;
|
_isReady = true;
|
||||||
}
|
}
|
||||||
@@ -516,13 +528,13 @@ namespace Discord
|
|||||||
_isStopping.Reset();
|
_isStopping.Reset();
|
||||||
|
|
||||||
//Open websocket while we wait for login response
|
//Open websocket while we wait for login response
|
||||||
Task socketTask = _webSocket.ConnectAsync(Endpoints.WebSocket_Hub, false, _httpOptions);
|
Task socketTask = _webSocket.ConnectAsync(Endpoints.WebSocket_Hub, false);
|
||||||
var response = await DiscordAPI.LoginAnonymous(username, _httpOptions);
|
var response = await DiscordAPI.LoginAnonymous(username);
|
||||||
_httpOptions.Token = response.Token;
|
Http.Token = response.Token;
|
||||||
|
|
||||||
//Wait for websocket to finish connecting, then send token
|
//Wait for websocket to finish connecting, then send token
|
||||||
await socketTask;
|
await socketTask;
|
||||||
_webSocket.Login(_httpOptions);
|
_webSocket.Login();
|
||||||
|
|
||||||
_isReady = true;
|
_isReady = true;
|
||||||
}
|
}
|
||||||
@@ -543,7 +555,7 @@ namespace Discord
|
|||||||
public async Task<Server> CreateServer(string name, string region)
|
public async Task<Server> CreateServer(string name, string region)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
var response = await DiscordAPI.CreateServer(name, region, _httpOptions);
|
var response = await DiscordAPI.CreateServer(name, region);
|
||||||
return _servers.Update(response.Id, response);
|
return _servers.Update(response.Id, response);
|
||||||
}
|
}
|
||||||
public Task<Server> LeaveServer(Server server)
|
public Task<Server> LeaveServer(Server server)
|
||||||
@@ -553,7 +565,7 @@ namespace Discord
|
|||||||
CheckReady();
|
CheckReady();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await DiscordAPI.LeaveServer(serverId, _httpOptions);
|
await DiscordAPI.LeaveServer(serverId);
|
||||||
}
|
}
|
||||||
catch (WebException ex) when ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound) {}
|
catch (WebException ex) when ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound) {}
|
||||||
return _servers.Remove(serverId);
|
return _servers.Remove(serverId);
|
||||||
@@ -565,7 +577,7 @@ namespace Discord
|
|||||||
public async Task<Channel> CreateChannel(string serverId, string name, string type)
|
public async Task<Channel> CreateChannel(string serverId, string name, string type)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
var response = await DiscordAPI.CreateChannel(serverId, name, type, _httpOptions);
|
var response = await DiscordAPI.CreateChannel(serverId, name, type);
|
||||||
return _channels.Update(response.Id, serverId, response);
|
return _channels.Update(response.Id, serverId, response);
|
||||||
}
|
}
|
||||||
public Task<Channel> CreatePMChannel(User user)
|
public Task<Channel> CreatePMChannel(User user)
|
||||||
@@ -573,7 +585,7 @@ namespace Discord
|
|||||||
public async Task<Channel> CreatePMChannel(string recipientId)
|
public async Task<Channel> CreatePMChannel(string recipientId)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
var response = await DiscordAPI.CreatePMChannel(UserId, recipientId, _httpOptions);
|
var response = await DiscordAPI.CreatePMChannel(UserId, recipientId);
|
||||||
return _channels.Update(response.Id, response);
|
return _channels.Update(response.Id, response);
|
||||||
}
|
}
|
||||||
public Task<Channel> DestroyChannel(Channel channel)
|
public Task<Channel> DestroyChannel(Channel channel)
|
||||||
@@ -583,7 +595,7 @@ namespace Discord
|
|||||||
CheckReady();
|
CheckReady();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var response = await DiscordAPI.DestroyChannel(channelId, _httpOptions);
|
var response = await DiscordAPI.DestroyChannel(channelId);
|
||||||
}
|
}
|
||||||
catch (WebException ex) when ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound) { }
|
catch (WebException ex) when ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound) { }
|
||||||
return _channels.Remove(channelId);
|
return _channels.Remove(channelId);
|
||||||
@@ -599,7 +611,7 @@ namespace Discord
|
|||||||
public Task Ban(string serverId, string userId)
|
public Task Ban(string serverId, string userId)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
return DiscordAPI.Ban(serverId, userId, _httpOptions);
|
return DiscordAPI.Ban(serverId, userId);
|
||||||
}
|
}
|
||||||
public Task Unban(Server server, User user)
|
public Task Unban(Server server, User user)
|
||||||
=> Unban(server.Id, user.Id);
|
=> Unban(server.Id, user.Id);
|
||||||
@@ -612,7 +624,7 @@ namespace Discord
|
|||||||
CheckReady();
|
CheckReady();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await DiscordAPI.Unban(serverId, userId, _httpOptions);
|
await DiscordAPI.Unban(serverId, userId);
|
||||||
}
|
}
|
||||||
catch (WebException ex) when ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound) { }
|
catch (WebException ex) when ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound) { }
|
||||||
}
|
}
|
||||||
@@ -629,7 +641,7 @@ namespace Discord
|
|||||||
public async Task<Invite> CreateInvite(string channelId, int maxAge, int maxUses, bool isTemporary, bool hasXkcdPass)
|
public async Task<Invite> CreateInvite(string channelId, int maxAge, int maxUses, bool isTemporary, bool hasXkcdPass)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
var response = await DiscordAPI.CreateInvite(channelId, maxAge, maxUses, isTemporary, hasXkcdPass, _httpOptions);
|
var response = await DiscordAPI.CreateInvite(channelId, maxAge, maxUses, isTemporary, hasXkcdPass);
|
||||||
_channels.Update(response.Channel.Id, response.Server.Id, response.Channel);
|
_channels.Update(response.Channel.Id, response.Server.Id, response.Channel);
|
||||||
_servers.Update(response.Server.Id, response.Server);
|
_servers.Update(response.Server.Id, response.Server);
|
||||||
_users.Update(response.Inviter.Id, response.Inviter);
|
_users.Update(response.Inviter.Id, response.Inviter);
|
||||||
@@ -648,7 +660,7 @@ namespace Discord
|
|||||||
public async Task<Invite> GetInvite(string id)
|
public async Task<Invite> GetInvite(string id)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
var response = await DiscordAPI.GetInvite(id, _httpOptions);
|
var response = await DiscordAPI.GetInvite(id);
|
||||||
return new Invite(response.Code, response.XkcdPass, this)
|
return new Invite(response.Code, response.XkcdPass, this)
|
||||||
{
|
{
|
||||||
ChannelId = response.Channel.Id,
|
ChannelId = response.Channel.Id,
|
||||||
@@ -659,14 +671,14 @@ namespace Discord
|
|||||||
public Task AcceptInvite(Invite invite)
|
public Task AcceptInvite(Invite invite)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
return DiscordAPI.AcceptInvite(invite.Code, _httpOptions);
|
return DiscordAPI.AcceptInvite(invite.Code);
|
||||||
}
|
}
|
||||||
public async Task AcceptInvite(string id)
|
public async Task AcceptInvite(string id)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
//Check if this is a human-readable link and get its ID
|
//Check if this is a human-readable link and get its ID
|
||||||
var response = await DiscordAPI.GetInvite(id, _httpOptions);
|
var response = await DiscordAPI.GetInvite(id);
|
||||||
await DiscordAPI.AcceptInvite(response.Code, _httpOptions);
|
await DiscordAPI.AcceptInvite(response.Code);
|
||||||
}
|
}
|
||||||
public async Task DeleteInvite(string id)
|
public async Task DeleteInvite(string id)
|
||||||
{
|
{
|
||||||
@@ -674,8 +686,8 @@ namespace Discord
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
//Check if this is a human-readable link and get its ID
|
//Check if this is a human-readable link and get its ID
|
||||||
var response = await DiscordAPI.GetInvite(id, _httpOptions);
|
var response = await DiscordAPI.GetInvite(id);
|
||||||
await DiscordAPI.DeleteInvite(response.Code, _httpOptions);
|
await DiscordAPI.DeleteInvite(response.Code);
|
||||||
}
|
}
|
||||||
catch (WebException ex) when ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound) { }
|
catch (WebException ex) when ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound) { }
|
||||||
}
|
}
|
||||||
@@ -693,7 +705,7 @@ namespace Discord
|
|||||||
|
|
||||||
if (text.Length <= 2000)
|
if (text.Length <= 2000)
|
||||||
{
|
{
|
||||||
var msg = await DiscordAPI.SendMessage(channelId, text, mentions, _httpOptions);
|
var msg = await DiscordAPI.SendMessage(channelId, text, mentions);
|
||||||
return new Message[] { _messages.Update(msg.Id, channelId, msg) };
|
return new Message[] { _messages.Update(msg.Id, channelId, msg) };
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -703,7 +715,7 @@ namespace Discord
|
|||||||
for (int i = 0; i < blockCount; i++)
|
for (int i = 0; i < blockCount; i++)
|
||||||
{
|
{
|
||||||
int index = i * DiscordAPI.MaxMessageSize;
|
int index = i * DiscordAPI.MaxMessageSize;
|
||||||
var msg = await DiscordAPI.SendMessage(channelId, text.Substring(index, Math.Min(2000, text.Length - index)), mentions, _httpOptions);
|
var msg = await DiscordAPI.SendMessage(channelId, text.Substring(index, Math.Min(2000, text.Length - index)), mentions);
|
||||||
result[i] = _messages.Update(msg.Id, channelId, msg);
|
result[i] = _messages.Update(msg.Id, channelId, msg);
|
||||||
await Task.Delay(1000);
|
await Task.Delay(1000);
|
||||||
}
|
}
|
||||||
@@ -727,7 +739,7 @@ namespace Discord
|
|||||||
if (text.Length > DiscordAPI.MaxMessageSize)
|
if (text.Length > DiscordAPI.MaxMessageSize)
|
||||||
text = text.Substring(0, DiscordAPI.MaxMessageSize);
|
text = text.Substring(0, DiscordAPI.MaxMessageSize);
|
||||||
|
|
||||||
var msg = await DiscordAPI.EditMessage(channelId, messageId, text, mentions, _httpOptions);
|
var msg = await DiscordAPI.EditMessage(channelId, messageId, text, mentions);
|
||||||
_messages.Update(msg.Id, channelId, msg);
|
_messages.Update(msg.Id, channelId, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -737,7 +749,7 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await DiscordAPI.DeleteMessage(channelId, msgId, _httpOptions);
|
await DiscordAPI.DeleteMessage(channelId, msgId);
|
||||||
return _messages.Remove(msgId);
|
return _messages.Remove(msgId);
|
||||||
}
|
}
|
||||||
catch (WebException ex) when ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound) { }
|
catch (WebException ex) when ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound) { }
|
||||||
@@ -755,7 +767,7 @@ namespace Discord
|
|||||||
public Task Mute(string serverId, string userId)
|
public Task Mute(string serverId, string userId)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
return DiscordAPI.Mute(serverId, userId, _httpOptions);
|
return DiscordAPI.Mute(serverId, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task Unmute(Server server, User user)
|
public Task Unmute(Server server, User user)
|
||||||
@@ -767,7 +779,7 @@ namespace Discord
|
|||||||
public Task Unmute(string serverId, string userId)
|
public Task Unmute(string serverId, string userId)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
return DiscordAPI.Unmute(serverId, userId, _httpOptions);
|
return DiscordAPI.Unmute(serverId, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task Deafen(Server server, User user)
|
public Task Deafen(Server server, User user)
|
||||||
@@ -779,7 +791,7 @@ namespace Discord
|
|||||||
public Task Deafen(string serverId, string userId)
|
public Task Deafen(string serverId, string userId)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
return DiscordAPI.Deafen(serverId, userId, _httpOptions);
|
return DiscordAPI.Deafen(serverId, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task Undeafen(Server server, User user)
|
public Task Undeafen(Server server, User user)
|
||||||
@@ -791,7 +803,7 @@ namespace Discord
|
|||||||
public Task Undeafen(string serverId, string userId)
|
public Task Undeafen(string serverId, string userId)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
return DiscordAPI.Undeafen(serverId, userId, _httpOptions);
|
return DiscordAPI.Undeafen(serverId, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckReady()
|
private void CheckReady()
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace Discord
|
|||||||
private DateTime _lastHeartbeat;
|
private DateTime _lastHeartbeat;
|
||||||
private AutoResetEvent _connectWaitOnLogin, _connectWaitOnLogin2;
|
private AutoResetEvent _connectWaitOnLogin, _connectWaitOnLogin2;
|
||||||
|
|
||||||
public async Task ConnectAsync(string url, bool autoLogin, HttpOptions options)
|
public async Task ConnectAsync(string url, bool autoLogin)
|
||||||
{
|
{
|
||||||
await DisconnectAsync();
|
await DisconnectAsync();
|
||||||
|
|
||||||
@@ -58,12 +58,12 @@ namespace Discord
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (autoLogin)
|
if (autoLogin)
|
||||||
Login(options);
|
Login();
|
||||||
}
|
}
|
||||||
public void Login(HttpOptions options)
|
public void Login()
|
||||||
{
|
{
|
||||||
WebSocketCommands.Login msg = new WebSocketCommands.Login();
|
WebSocketCommands.Login msg = new WebSocketCommands.Login();
|
||||||
msg.Payload.Token = options.Token;
|
msg.Payload.Token = Http.Token;
|
||||||
msg.Payload.Properties["$os"] = "";
|
msg.Payload.Properties["$os"] = "";
|
||||||
msg.Payload.Properties["$browser"] = "";
|
msg.Payload.Properties["$browser"] = "";
|
||||||
msg.Payload.Properties["$device"] = "Discord.Net";
|
msg.Payload.Properties["$device"] = "Discord.Net";
|
||||||
|
|||||||
@@ -2,23 +2,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Net;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace Discord.Helpers
|
namespace Discord.Helpers
|
||||||
{
|
{
|
||||||
internal class HttpOptions
|
|
||||||
{
|
|
||||||
public readonly string UserAgent;
|
|
||||||
public string Token;
|
|
||||||
|
|
||||||
public HttpOptions(string userAgent)
|
|
||||||
{
|
|
||||||
UserAgent = userAgent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static class Http
|
internal static class Http
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@@ -26,151 +16,120 @@ namespace Discord.Helpers
|
|||||||
#else
|
#else
|
||||||
private const bool _isDebug = false;
|
private const bool _isDebug = false;
|
||||||
#endif
|
#endif
|
||||||
|
private static readonly HttpClient _client;
|
||||||
|
private static readonly HttpMethod _patch = new HttpMethod("PATCH"); //Not sure why this isn't a default...
|
||||||
|
|
||||||
internal static Task<ResponseT> Get<ResponseT>(string path, HttpOptions options)
|
static Http()
|
||||||
where ResponseT : class
|
{
|
||||||
=> Send<ResponseT>("GET", path, null, options);
|
_client = new HttpClient();
|
||||||
internal static Task<string> Get(string path, HttpOptions options)
|
_client.DefaultRequestHeaders.Add("Accept", "*/*");
|
||||||
=> Send("GET", path, null, options);
|
_client.DefaultRequestHeaders.Add("Accept-language", "en-US;q=0.8");
|
||||||
|
|
||||||
internal static Task<ResponseT> Post<ResponseT>(string path, object data, HttpOptions options)
|
string version = typeof(Http).GetTypeInfo().Assembly.GetName().Version.ToString(2);
|
||||||
where ResponseT : class
|
_client.DefaultRequestHeaders.Add("User-agent", $"Discord.Net/{version} (https://github.com/RogueException/Discord.Net)");
|
||||||
=> Send<ResponseT>("POST", path, data, options);
|
}
|
||||||
internal static Task<string> Post(string path, object data, HttpOptions options)
|
|
||||||
=> Send("POST", path, data, options);
|
|
||||||
internal static Task<ResponseT> Post<ResponseT>(string path, HttpOptions options)
|
|
||||||
where ResponseT : class
|
|
||||||
=> Send<ResponseT>("POST", path, null, options);
|
|
||||||
internal static Task<string> Post(string path, HttpOptions options)
|
|
||||||
=> Send("POST", path, null, options);
|
|
||||||
|
|
||||||
internal static Task<ResponseT> Put<ResponseT>(string path, object data, HttpOptions options)
|
private static string _token;
|
||||||
where ResponseT : class
|
public static string Token
|
||||||
=> Send<ResponseT>("PUT", path, data, options);
|
{
|
||||||
internal static Task<string> Put(string path, object data, HttpOptions options)
|
get { return _token; }
|
||||||
=> Send("PUT", path, data, options);
|
set
|
||||||
internal static Task<ResponseT> Put<ResponseT>(string path, HttpOptions options)
|
{
|
||||||
where ResponseT : class
|
_token = value;
|
||||||
=> Send<ResponseT>("PUT", path, null, options);
|
_client.DefaultRequestHeaders.Add("Authorization", _token);
|
||||||
internal static Task<string> Put(string path, HttpOptions options)
|
}
|
||||||
=> Send("PUT", path, null, options);
|
}
|
||||||
|
|
||||||
internal static Task<ResponseT> Patch<ResponseT>(string path, object data, HttpOptions options)
|
internal static Task<ResponseT> Get<ResponseT>(string path)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
=> Send<ResponseT>("PATCH", path, data, options);
|
=> Send<ResponseT>(HttpMethod.Get, path, null);
|
||||||
internal static Task<string> Patch(string path, object data, HttpOptions options)
|
internal static Task<string> Get(string path)
|
||||||
=> Send("PATCH", path, data, options);
|
=> Send(HttpMethod.Get, path, null);
|
||||||
internal static Task<ResponseT> Patch<ResponseT>(string path, HttpOptions options)
|
|
||||||
where ResponseT : class
|
|
||||||
=> Send<ResponseT>("PATCH", path, null, options);
|
|
||||||
internal static Task<string> Patch(string path, HttpOptions options)
|
|
||||||
=> Send("PATCH", path, null, options);
|
|
||||||
|
|
||||||
internal static Task<ResponseT> Delete<ResponseT>(string path, object data, HttpOptions options)
|
internal static Task<ResponseT> Post<ResponseT>(string path, object data)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
=> Send<ResponseT>("DELETE", path, data, options);
|
=> Send<ResponseT>(HttpMethod.Post, path, data);
|
||||||
internal static Task<string> Delete(string path, object data, HttpOptions options)
|
internal static Task<string> Post(string path, object data)
|
||||||
=> Send("DELETE", path, data, options);
|
=> Send(HttpMethod.Post, path, data);
|
||||||
internal static Task<ResponseT> Delete<ResponseT>(string path, HttpOptions options)
|
internal static Task<ResponseT> Post<ResponseT>(string path)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
=> Send<ResponseT>("DELETE", path, null, options);
|
=> Send<ResponseT>(HttpMethod.Post, path, null);
|
||||||
internal static Task<string> Delete(string path, HttpOptions options)
|
internal static Task<string> Post(string path)
|
||||||
=> Send("DELETE", path, null, options);
|
=> Send(HttpMethod.Post, path, null);
|
||||||
|
|
||||||
internal static async Task<ResponseT> Send<ResponseT>(string method, string path, object data, HttpOptions options)
|
internal static Task<ResponseT> Put<ResponseT>(string path, object data)
|
||||||
|
where ResponseT : class
|
||||||
|
=> Send<ResponseT>(HttpMethod.Put, path, data);
|
||||||
|
internal static Task<string> Put(string path, object data)
|
||||||
|
=> Send(HttpMethod.Put, path, data);
|
||||||
|
internal static Task<ResponseT> Put<ResponseT>(string path)
|
||||||
|
where ResponseT : class
|
||||||
|
=> Send<ResponseT>(HttpMethod.Put, path, null);
|
||||||
|
internal static Task<string> Put(string path)
|
||||||
|
=> Send(HttpMethod.Put, path, null);
|
||||||
|
|
||||||
|
internal static Task<ResponseT> Patch<ResponseT>(string path, object data)
|
||||||
|
where ResponseT : class
|
||||||
|
=> Send<ResponseT>(_patch, path, data);
|
||||||
|
internal static Task<string> Patch(string path, object data)
|
||||||
|
=> Send(_patch, path, data);
|
||||||
|
internal static Task<ResponseT> Patch<ResponseT>(string path)
|
||||||
|
where ResponseT : class
|
||||||
|
=> Send<ResponseT>(_patch, path, null);
|
||||||
|
internal static Task<string> Patch(string path)
|
||||||
|
=> Send(_patch, path, null);
|
||||||
|
|
||||||
|
internal static Task<ResponseT> Delete<ResponseT>(string path, object data)
|
||||||
|
where ResponseT : class
|
||||||
|
=> Send<ResponseT>(HttpMethod.Delete, path, data);
|
||||||
|
internal static Task<string> Delete(string path, object data)
|
||||||
|
=> Send(HttpMethod.Delete, path, data);
|
||||||
|
internal static Task<ResponseT> Delete<ResponseT>(string path)
|
||||||
|
where ResponseT : class
|
||||||
|
=> Send<ResponseT>(HttpMethod.Delete, path, null);
|
||||||
|
internal static Task<string> Delete(string path)
|
||||||
|
=> Send(HttpMethod.Delete, path, null);
|
||||||
|
|
||||||
|
internal static async Task<ResponseT> Send<ResponseT>(HttpMethod method, string path, object data)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
{
|
{
|
||||||
string requestJson = data != null ? JsonConvert.SerializeObject(data) : null;
|
string requestJson = data != null ? JsonConvert.SerializeObject(data) : null;
|
||||||
string responseJson = await SendRequest(method, path, requestJson, options, true);
|
string responseJson = await SendRequest(method, path, requestJson, true);
|
||||||
var response = JsonConvert.DeserializeObject<ResponseT>(responseJson);
|
var response = JsonConvert.DeserializeObject<ResponseT>(responseJson);
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
CheckResponse(responseJson, response);
|
CheckResponse(responseJson, response);
|
||||||
#endif
|
#endif
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
internal static async Task<string> Send(string method, string path, object data, HttpOptions options)
|
internal static async Task<string> Send(HttpMethod method, string path, object data)
|
||||||
{
|
{
|
||||||
string requestJson = data != null ? JsonConvert.SerializeObject(data) : null;
|
string requestJson = data != null ? JsonConvert.SerializeObject(data) : null;
|
||||||
string responseJson = await SendRequest(method, path, requestJson, options, _isDebug);
|
string responseJson = await SendRequest(method, path, requestJson, _isDebug);
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
CheckEmptyResponse(responseJson);
|
CheckEmptyResponse(responseJson);
|
||||||
#endif
|
#endif
|
||||||
return responseJson;
|
return responseJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<string> SendRequest(string method, string path, string data, HttpOptions options, bool hasResponse)
|
private static async Task<string> SendRequest(HttpMethod method, string path, string data, bool hasResponse)
|
||||||
{
|
{
|
||||||
//Create Request
|
//Create Request
|
||||||
HttpWebRequest request = WebRequest.CreateHttp(path);
|
HttpRequestMessage msg = new HttpRequestMessage(method, path);
|
||||||
request.Accept = "*/*";
|
|
||||||
request.Method = method;
|
|
||||||
request.Proxy = null;
|
|
||||||
request.Headers[HttpRequestHeader.AcceptLanguage] = "en-US;q=0.8";
|
|
||||||
request.Headers[HttpRequestHeader.AcceptEncoding] = "gzip, deflate";
|
|
||||||
request.Headers[HttpRequestHeader.UserAgent] = options.UserAgent;
|
|
||||||
request.Headers[HttpRequestHeader.Authorization] = options.Token;
|
|
||||||
//request.UserAgent = options.UserAgent;
|
|
||||||
|
|
||||||
//Add Payload
|
//Add Payload
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
msg.Content = new StringContent(data, Encoding.UTF8, "application/json");
|
||||||
byte[] buffer = Encoding.UTF8.GetBytes(data);
|
|
||||||
using (var payload = await request.GetRequestStreamAsync())
|
|
||||||
payload.Write(buffer, 0, buffer.Length);
|
|
||||||
request.ContentType = "application/json";
|
|
||||||
}
|
|
||||||
|
|
||||||
//Get Response
|
if (!hasResponse)
|
||||||
using (var response = (HttpWebResponse)(await request.GetResponseAsync()))
|
|
||||||
{
|
{
|
||||||
if (hasResponse)
|
await _client.SendAsync(msg, HttpCompletionOption.ResponseHeadersRead);
|
||||||
{
|
return null;
|
||||||
using (var stream = response.GetResponseStream())
|
|
||||||
using (var reader = new BinaryReader(stream))
|
|
||||||
using (var largeBuffer = new MemoryStream())
|
|
||||||
{
|
|
||||||
//Read the response in small chunks and add them to a larger buffer.
|
|
||||||
//ContentLength isn't always provided, so this is safer.
|
|
||||||
int bytesRead = 0;
|
|
||||||
byte[] smallBuffer = new byte[4096];
|
|
||||||
while ((bytesRead = reader.Read(smallBuffer, 0, smallBuffer.Length)) > 0)
|
|
||||||
largeBuffer.Write(smallBuffer, 0, bytesRead);
|
|
||||||
|
|
||||||
//Do we need to decompress?
|
|
||||||
string encoding = response.Headers[HttpResponseHeader.ContentEncoding];
|
|
||||||
if (!string.IsNullOrEmpty(encoding))
|
|
||||||
{
|
|
||||||
largeBuffer.Position = 0;
|
|
||||||
using (var decoder = GetDecoder(encoding, largeBuffer))
|
|
||||||
using (var decodedStream = new MemoryStream())
|
|
||||||
{
|
|
||||||
decoder.CopyTo(decodedStream);
|
|
||||||
#if !DOTNET
|
|
||||||
return Encoding.UTF8.GetString(decodedStream.GetBuffer(), 0, (int)decodedStream.Length);
|
|
||||||
#else
|
|
||||||
ArraySegment<byte> buffer;
|
|
||||||
if (!decodedStream.TryGetBuffer(out buffer))
|
|
||||||
throw new InvalidOperationException("Failed to get response buffer.");
|
|
||||||
return Encoding.UTF8.GetString(buffer.Array, buffer.Offset, (int)decodedStream.Length);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if !DOTNET
|
|
||||||
return Encoding.UTF8.GetString(largeBuffer.GetBuffer(), 0, (int)largeBuffer.Length);
|
|
||||||
#else
|
|
||||||
ArraySegment<byte> buffer;
|
|
||||||
if (!largeBuffer.TryGetBuffer(out buffer))
|
|
||||||
throw new InvalidOperationException("Failed to get response buffer.");
|
|
||||||
return Encoding.UTF8.GetString(buffer.Array, buffer.Offset, (int)largeBuffer.Length);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var response = await _client.SendAsync(msg, HttpCompletionOption.ResponseContentRead);
|
||||||
|
return await response.Content.ReadAsStringAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Stream GetDecoder(string contentEncoding, MemoryStream encodedStream)
|
private static Stream GetDecoder(string contentEncoding, MemoryStream encodedStream)
|
||||||
|
|||||||
@@ -24,5 +24,8 @@
|
|||||||
"Newtonsoft.Json": "7.0.1"
|
"Newtonsoft.Json": "7.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Net.Http": "2.2.22"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user