aboutsummaryrefslogtreecommitdiff
path: root/src/client/http/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/http/mod.rs')
-rw-r--r--src/client/http/mod.rs751
1 files changed, 751 insertions, 0 deletions
diff --git a/src/client/http/mod.rs b/src/client/http/mod.rs
new file mode 100644
index 0000000..9ef9bac
--- /dev/null
+++ b/src/client/http/mod.rs
@@ -0,0 +1,751 @@
+//! The HTTP module which provides functions for performing requests to
+//! endpoints in Discord's API.
+//!
+//! An important function of the REST API is ratelimiting. Requests to endpoints
+//! are ratelimited to prevent spam, and once ratelimited Discord will stop
+//! performing requests. The library implements protection to pre-emptively
+//! ratelimit, to ensure that no wasted requests are made.
+//!
+//! The HTTP module comprises of two types of requests:
+//!
+//! - REST API requests, which require an authorization token;
+//! - Other requests, which do not require an authorization token.
+//!
+//! The former require a [`Client`] to have logged in, while the latter may be
+//! made regardless of any other usage of the library.
+//!
+//! If a request spuriously fails, it will be retried once.
+//!
+//! [`Client`]: ../struct.Client.html
+
+mod ratelimiting;
+
+use hyper::client::{
+ Client as HyperClient,
+ RequestBuilder,
+ Response as HyperResponse,
+ Request,
+};
+use hyper::method::Method;
+use hyper::status::StatusCode;
+use hyper::{Error as HyperError, Result as HyperResult, Url, header};
+use multipart::client::Multipart;
+use self::ratelimiting::Route;
+use serde_json;
+use std::default::Default;
+use std::io::{ErrorKind as IoErrorKind, Read};
+use std::sync::{Arc, Mutex};
+use ::constants;
+use ::model::*;
+use ::prelude_internal::*;
+use ::utils::decode_array;
+
+lazy_static! {
+ static ref TOKEN: Arc<Mutex<String>> = Arc::new(Mutex::new(String::default()));
+}
+
+#[doc(hidden)]
+pub fn set_token(token: &str) {
+ TOKEN.lock().unwrap().clone_from(&token.to_owned());
+}
+
+pub fn accept_invite(code: &str) -> Result<Invite> {
+ let response = request!(Route::InvitesCode, post, "/invites/{}", code);
+
+ Invite::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn ack_message(channel_id: u64, message_id: u64) -> Result<()> {
+ verify(204, request!(Route::ChannelsIdMessagesIdAck(channel_id),
+ post,
+ "/channels/{}/messages/{}/ack",
+ channel_id,
+ message_id))
+}
+
+pub fn add_group_recipient(group_id: u64, user_id: u64)
+ -> Result<()> {
+ verify(204, request!(Route::None,
+ put,
+ "/channels/{}/recipients/{}",
+ group_id,
+ user_id))
+}
+
+pub fn ban_user(guild_id: u64, user_id: u64, delete_message_days: u8)
+ -> Result<()> {
+ verify(204, request!(Route::GuildsIdBansUserId(guild_id),
+ put,
+ "/guilds/{}/bans/{}?delete_message_days={}",
+ guild_id,
+ user_id,
+ delete_message_days))
+}
+
+pub fn broadcast_typing(channel_id: u64) -> Result<()> {
+ verify(204, request!(Route::ChannelsIdTyping(channel_id),
+ post,
+ "/channels/{}/typing",
+ channel_id))
+}
+
+pub fn create_channel(guild_id: u64, map: Value) -> Result<Channel> {
+ let body = try!(serde_json::to_string(&map));
+ let response = request!(Route::GuildsIdChannels(guild_id),
+ post(body),
+ "/guilds/{}/channels",
+ guild_id);
+
+ Channel::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn create_emoji(guild_id: u64, map: Value)
+ -> Result<Emoji> {
+ let body = try!(serde_json::to_string(&map));
+ let response = request!(Route::GuildsIdEmojis(guild_id),
+ post(body),
+ "/guilds/{}/emojis",
+ guild_id);
+
+ Emoji::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn create_guild(map: Value) -> Result<Guild> {
+ let body = try!(serde_json::to_string(&map));
+ let response = request!(Route::Guilds, post(body), "/guilds");
+
+ Guild::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn create_guild_integration(guild_id: u64,
+ integration_id: u64,
+ map: Value) -> Result<()> {
+ let body = try!(serde_json::to_string(&map));
+
+ verify(204, request!(Route::GuildsIdIntegrations(guild_id),
+ post(body),
+ "/guilds/{}/integrations/{}",
+ guild_id,
+ integration_id))
+}
+
+pub fn create_invite(channel_id: u64, map: Value)
+ -> Result<RichInvite> {
+ let body = try!(serde_json::to_string(&map));
+ let response = request!(Route::ChannelsIdInvites(channel_id),
+ post(body),
+ "/channels/{}/invites",
+ channel_id);
+
+ RichInvite::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn create_permission(channel_id: u64, target_id: u64, map: Value)
+ -> Result<()> {
+ let body = try!(serde_json::to_string(&map));
+
+ verify(204, request!(Route::ChannelsIdPermissionsOverwriteId(channel_id),
+ put(body),
+ "/channels/{}/permissions/{}",
+ channel_id,
+ target_id))
+}
+
+pub fn create_private_channel(map: Value)
+ -> Result<PrivateChannel> {
+ let body = try!(serde_json::to_string(&map));
+ let response = request!(Route::UsersMeChannels,
+ post(body),
+ "/users/@me/channels");
+
+ PrivateChannel::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn create_reaction(channel_id: u64,
+ message_id: u64,
+ reaction_type: ReactionType)
+ -> Result<()> {
+ verify(204, request!(Route::ChannelsIdMessagesIdReactionsUserIdType(channel_id),
+ put,
+ "/channels/{}/messages/{}/reactions/{}/@me",
+ channel_id,
+ message_id,
+ reaction_type.as_data()))
+}
+
+pub fn create_role(guild_id: u64) -> Result<Role> {
+ let body = String::from("{}");
+ let response = request!(Route::GuildsIdRoles(guild_id),
+ post(body),
+ "/guilds/{}/roles",
+ guild_id);
+
+ Role::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn delete_channel(channel_id: u64) -> Result<Channel> {
+ let response = request!(Route::ChannelsId(channel_id),
+ delete,
+ "/channels/{}",
+ channel_id);
+
+ Channel::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn delete_emoji(guild_id: u64, emoji_id: u64) -> Result<()> {
+ verify(204, request!(Route::GuildsIdEmojisId(guild_id),
+ delete,
+ "/guilds/{}/emojis/{}",
+ guild_id,
+ emoji_id))
+}
+
+pub fn delete_guild(guild_id: u64) -> Result<Guild> {
+ let response = request!(Route::GuildsId(guild_id),
+ delete,
+ "/guilds/{}",
+ guild_id);
+
+ Guild::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn delete_guild_integration(guild_id: u64, integration_id: u64)
+ -> Result<()> {
+ verify(204, request!(Route::GuildsIdIntegrationsId(guild_id),
+ delete,
+ "/guilds/{}/integrations/{}",
+ guild_id,
+ integration_id))
+}
+
+pub fn delete_invite(code: &str) -> Result<Invite> {
+ let response = request!(Route::InvitesCode, delete, "/invite/{}", code);
+
+ Invite::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn delete_message(channel_id: u64, message_id: u64)
+ -> Result<()> {
+ verify(204, request!(Route::ChannelsIdMessagesId(channel_id),
+ delete,
+ "/channels/{}/messages/{}",
+ channel_id,
+ message_id))
+}
+
+pub fn delete_messages(channel_id: u64, map: Value) -> Result<()> {
+ let body = try!(serde_json::to_string(&map));
+
+ verify(204, request!(Route::ChannelsIdMessagesBulkDelete(channel_id),
+ post(body),
+ "/channels/{}/messages/bulk_delete",
+ channel_id))
+}
+
+pub fn delete_permission(channel_id: u64, target_id: u64)
+ -> Result<()> {
+ verify(204, request!(Route::ChannelsIdPermissionsOverwriteId(channel_id),
+ delete,
+ "/channels/{}/permissions/{}",
+ channel_id,
+ target_id))
+}
+
+pub fn delete_reaction(channel_id: u64,
+ message_id: u64,
+ user_id: Option<u64>,
+ reaction_type: ReactionType)
+ -> Result<()> {
+ let user = user_id.map(|uid| uid.to_string()).unwrap_or("@me".to_string());
+
+ verify(204, request!(Route::ChannelsIdMessagesIdReactionsUserIdType(channel_id),
+ delete,
+ "/channels/{}/messages/{}/reactions/{}/{}",
+ channel_id,
+ message_id,
+ reaction_type.as_data(),
+ user))
+}
+
+pub fn delete_role(guild_id: u64, role_id: u64) -> Result<()> {
+ verify(204, request!(Route::GuildsIdRolesId(guild_id),
+ delete,
+ "/guilds/{}/roles/{}",
+ guild_id,
+ role_id))
+}
+
+pub fn edit_channel(channel_id: u64, map: Value)
+ -> Result<PublicChannel> {
+ let body = try!(serde_json::to_string(&map));
+ let response = request!(Route::ChannelsId(channel_id),
+ patch(body),
+ "/channels/{}",
+ channel_id);
+
+ PublicChannel::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn edit_emoji(guild_id: u64, emoji_id: u64, map: Value)
+ -> Result<Emoji> {
+ let body = try!(serde_json::to_string(&map));
+ let response = request!(Route::GuildsIdEmojisId(guild_id),
+ patch(body),
+ "/guilds/{}/emojis/{}",
+ guild_id,
+ emoji_id);
+
+ Emoji::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn edit_guild(guild_id: u64, map: Value) -> Result<Guild> {
+ let body = try!(serde_json::to_string(&map));
+ let response = request!(Route::GuildsId(guild_id),
+ patch(body),
+ "/guilds/{}",
+ guild_id);
+
+ Guild::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn edit_member(guild_id: u64, user_id: u64, map: Value)
+ -> Result<()> {
+ let body = try!(serde_json::to_string(&map));
+
+ verify(204, request!(Route::GuildsIdMembersId(guild_id),
+ patch(body),
+ "/guilds/{}/members/{}",
+ guild_id,
+ user_id))
+}
+
+pub fn edit_message(channel_id: u64,
+ message_id: u64,
+ map: Value)
+ -> Result<Message> {
+ let body = try!(serde_json::to_string(&map));
+ let response = request!(Route::ChannelsIdMessagesId(channel_id),
+ patch(body),
+ "/channels/{}/messages/{}",
+ channel_id,
+ message_id);
+
+ Message::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn edit_note(user_id: u64, map: Value) -> Result<()> {
+ let body = try!(serde_json::to_string(&map));
+
+ verify(204, request!(Route::None,
+ put(body),
+ "/users/@me/notes/{}",
+ user_id))
+}
+
+pub fn edit_profile(map: Value) -> Result<CurrentUser> {
+ let body = try!(serde_json::to_string(&map));
+ let response = request!(Route::UsersMe, patch(body), "/users/@me");
+
+ CurrentUser::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn edit_role(guild_id: u64, role_id: u64, map: Value)
+ -> Result<Role> {
+ let body = try!(serde_json::to_string(&map));
+ let response = request!(Route::GuildsIdRolesId(guild_id),
+ patch(body),
+ "/guilds/{}/roles/{}",
+ guild_id,
+ role_id);
+
+ Role::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn get_application_info() -> Result<CurrentApplicationInfo> {
+ let response = request!(Route::None, get, "/oauth2/applications/@me");
+
+ CurrentApplicationInfo::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn get_applications() -> Result<Vec<ApplicationInfo>> {
+ let response = request!(Route::None, get, "/oauth2/applications");
+ let decoded = try!(serde_json::from_reader(response));
+
+ decode_array(decoded, ApplicationInfo::decode)
+}
+
+pub fn get_bans(guild_id: u64) -> Result<Vec<Ban>> {
+ let response = request!(Route::GuildsIdBans(guild_id),
+ get,
+ "/guilds/{}/bans",
+ guild_id);
+
+ decode_array(try!(serde_json::from_reader(response)), Ban::decode)
+}
+
+pub fn get_bot_gateway() -> Result<BotGateway> {
+ let response = request!(Route::GatewayBot, get, "/gateway/bot");
+
+ BotGateway::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn get_channel_invites(channel_id: u64)
+ -> Result<Vec<RichInvite>> {
+ let response = request!(Route::ChannelsIdInvites(channel_id),
+ get,
+ "/channels/{}/invites",
+ channel_id);
+
+ decode_array(try!(serde_json::from_reader(response)),
+ RichInvite::decode)
+}
+
+pub fn get_channel(channel_id: u64) -> Result<Channel> {
+ let response = request!(Route::ChannelsId(channel_id),
+ get,
+ "/channels/{}",
+ channel_id);
+
+ Channel::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn get_channels(guild_id: u64) -> Result<Vec<PublicChannel>> {
+ let response = request!(Route::ChannelsId(guild_id),
+ get,
+ "/guilds/{}/channels",
+ guild_id);
+
+ decode_array(try!(serde_json::from_reader(response)),
+ PublicChannel::decode)
+}
+
+pub fn get_current_user() -> Result<CurrentUser> {
+ let response = request!(Route::UsersMe, get, "/users/@me");
+
+ CurrentUser::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn get_gateway() -> Result<Gateway> {
+ let response = request!(Route::Gateway, get, "/gateway");
+
+ Gateway::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn get_emoji(guild_id: u64, emoji_id: u64) -> Result<Emoji> {
+ let response = request!(Route::GuildsIdEmojisId(guild_id),
+ get,
+ "/guilds/{}/emojis/{}",
+ guild_id,
+ emoji_id);
+
+ Emoji::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn get_emojis(guild_id: u64) -> Result<Vec<Emoji>> {
+ let response = request!(Route::GuildsIdEmojis(guild_id),
+ get,
+ "/guilds/{}/emojis",
+ guild_id);
+
+ decode_array(try!(serde_json::from_reader(response)), Emoji::decode)
+}
+
+pub fn get_guild(guild_id: u64) -> Result<Guild> {
+ let response = request!(Route::GuildsId(guild_id),
+ get,
+ "/guilds/{}",
+ guild_id);
+
+ Guild::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn get_guild_integrations(guild_id: u64)
+ -> Result<Vec<Integration>> {
+ let response = request!(Route::GuildsIdIntegrations(guild_id),
+ get,
+ "/guilds/{}/integrations",
+ guild_id);
+
+ decode_array(try!(serde_json::from_reader(response)), Integration::decode)
+}
+
+pub fn get_guild_invites(guild_id: u64) -> Result<Vec<RichInvite>> {
+ let response = request!(Route::GuildsIdInvites(guild_id),
+ get,
+ "/guilds/{}/invites",
+ guild_id);
+
+ decode_array(try!(serde_json::from_reader(response)),
+ RichInvite::decode)
+}
+
+pub fn get_guild_prune_count(guild_id: u64, map: Value)
+ -> Result<GuildPrune> {
+ let body = try!(serde_json::to_string(&map));
+ let response = request!(Route::GuildsIdPrune(guild_id),
+ get(body),
+ "/guilds/{}/prune",
+ guild_id);
+
+ GuildPrune::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn get_guilds() -> Result<Vec<GuildInfo>> {
+ let response = request!(Route::UsersMeGuilds,
+ get,
+ "/users/@me/guilds");
+
+ decode_array(try!(serde_json::from_reader(response)), GuildInfo::decode)
+}
+
+pub fn get_invite(code: &str) -> Result<Invite> {
+ let invite = ::utils::parse_invite(code);
+ let response = request!(Route::InvitesCode, get, "/invite/{}", invite);
+
+ Invite::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn get_member(guild_id: u64, user_id: u64) -> Result<Member> {
+ let response = request!(Route::GuildsIdMembersId(guild_id),
+ get,
+ "/guilds/{}/members/{}",
+ guild_id,
+ user_id);
+
+ Member::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn get_message(channel_id: u64, message_id: u64)
+ -> Result<Message> {
+ let response = request!(Route::ChannelsIdMessagesId(channel_id),
+ get,
+ "/channels/{}/messages/{}",
+ channel_id,
+ message_id);
+
+ Message::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn get_messages(channel_id: u64, query: &str)
+ -> Result<Vec<Message>> {
+ let url = format!(api_concat!("/channels/{}/messages{}"),
+ channel_id,
+ query);
+ let client = HyperClient::new();
+ let response = try!(request(Route::ChannelsIdMessages(channel_id),
+ || client.get(&url)));
+
+ decode_array(try!(serde_json::from_reader(response)), Message::decode)
+}
+
+pub fn get_pins(channel_id: u64) -> Result<Vec<Message>> {
+ let response = request!(Route::ChannelsIdPins(channel_id),
+ get,
+ "/channels/{}/pins",
+ channel_id);
+
+ decode_array(try!(serde_json::from_reader(response)), Message::decode)
+}
+
+pub fn get_reaction_users(channel_id: u64,
+ message_id: u64,
+ reaction_type: ReactionType,
+ limit: u8,
+ after: Option<u64>)
+ -> Result<Vec<User>> {
+ let mut uri = format!("/channels/{}/messages/{}/reactions/{}?limit={}",
+ channel_id,
+ message_id,
+ reaction_type.as_data(),
+ limit);
+
+ if let Some(user_id) = after {
+ uri.push_str("&after=");
+ uri.push_str(&user_id.to_string());
+ }
+
+ let response = request!(Route::ChannelsIdMessagesIdReactionsUserIdType(channel_id),
+ get,
+ "{}",
+ uri);
+
+ decode_array(try!(serde_json::from_reader(response)), User::decode)
+}
+
+pub fn get_user(user_id: u64) -> Result<CurrentUser> {
+ let response = request!(Route::UsersId, get, "/users/{}", user_id);
+
+ CurrentUser::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn get_voice_regions() -> Result<Vec<VoiceRegion>> {
+ let response = request!(Route::VoiceRegions, get, "/voice/regions");
+
+ decode_array(try!(serde_json::from_reader(response)), VoiceRegion::decode)
+}
+
+pub fn kick_member(guild_id: u64, user_id: u64) -> Result<()> {
+ verify(204, request!(Route::GuildsIdMembersId(guild_id),
+ delete,
+ "/guilds/{}/members/{}",
+ guild_id,
+ user_id))
+}
+
+pub fn leave_group(guild_id: u64) -> Result<Group> {
+ let response = request!(Route::None,
+ delete,
+ "/channels/{}",
+ guild_id);
+
+ Group::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn leave_guild(guild_id: u64) -> Result<Guild> {
+ let response = request!(Route::GuildsId(guild_id),
+ delete,
+ "/guilds/{}",
+ guild_id);
+
+ Guild::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn logout(map: Value) -> Result<()> {
+ let body = try!(serde_json::to_string(&map));
+
+ verify(204, request!(Route::None, post(body), "/auth/logout"))
+}
+
+pub fn remove_group_recipient(group_id: u64, user_id: u64)
+ -> Result<()> {
+ verify(204, request!(Route::None,
+ delete,
+ "/channels/{}/recipients/{}",
+ group_id,
+ user_id))
+}
+
+pub fn send_file<R: Read>(channel_id: u64,
+ content: &str,
+ mut file: R,
+ filename: &str)
+ -> Result<Message> {
+ let uri = format!(api_concat!("/channels/{}/messages"), channel_id);
+ let url = match Url::parse(&uri) {
+ Ok(url) => url,
+ Err(_why) => return Err(Error::Url(uri)),
+ };
+
+ let mut request = try!(Request::new(Method::Post, url));
+ request.headers_mut().set(header::Authorization(TOKEN.lock().unwrap().clone()));
+ request.headers_mut()
+ .set(header::UserAgent(constants::USER_AGENT.to_owned()));
+
+ let mut request = try!(Multipart::from_request(request));
+ try!(request.write_text("content", content));
+ try!(request.write_stream("file", &mut file, Some(&filename), None));
+
+ Message::decode(try!(serde_json::from_reader(try!(request.send()))))
+}
+
+pub fn send_message(channel_id: u64, map: Value) -> Result<Message> {
+ let body = try!(serde_json::to_string(&map));
+ let response = request!(Route::ChannelsIdMessages(channel_id),
+ post(body),
+ "/channels/{}/messages",
+ channel_id);
+
+ Message::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn pin_message(channel_id: u64, message_id: u64) -> Result<()> {
+ verify(204, request!(Route::ChannelsIdPinsMessageId(channel_id),
+ put,
+ "/channels/{}/pins/{}",
+ channel_id,
+ message_id))
+}
+
+pub fn remove_ban(guild_id: u64, user_id: u64) -> Result<()> {
+ verify(204, request!(Route::GuildsIdBansUserId(guild_id),
+ delete,
+ "/guilds/{}/bans/{}",
+ guild_id,
+ user_id))
+}
+
+pub fn start_guild_prune(guild_id: u64, map: Value)
+ -> Result<GuildPrune> {
+ let body = try!(serde_json::to_string(&map));
+ let response = request!(Route::GuildsIdPrune(guild_id),
+ post(body),
+ "/guilds/{}/prune",
+ guild_id);
+
+ GuildPrune::decode(try!(serde_json::from_reader(response)))
+}
+
+pub fn start_integration_sync(guild_id: u64, integration_id: u64)
+ -> Result<()> {
+ verify(204, request!(Route::GuildsIdIntegrationsId(guild_id),
+ post,
+ "/guilds/{}/integrations/{}",
+ guild_id,
+ integration_id))
+}
+
+pub fn unpin_message(channel_id: u64, message_id: u64) -> Result<()> {
+ verify(204, request!(Route::ChannelsIdPinsMessageId(channel_id),
+ delete,
+ "/channels/{}/pins/{}",
+ channel_id,
+ message_id))
+}
+
+fn request<'a, F>(route: Route, f: F) -> Result<HyperResponse>
+ where F: Fn() -> RequestBuilder<'a> {
+ ratelimiting::perform(route, || f()
+ .header(header::Authorization(TOKEN.lock().unwrap().clone()))
+ .header(header::ContentType::json()))
+}
+
+#[doc(hidden)]
+pub fn retry<'a, F>(f: F) -> HyperResult<HyperResponse>
+ where F: Fn() -> RequestBuilder<'a> {
+ let req = || f()
+ .header(header::UserAgent(constants::USER_AGENT.to_owned()))
+ .send();
+
+ match req() {
+ Err(HyperError::Io(ref io))
+ if io.kind() == IoErrorKind::ConnectionAborted => req(),
+ other => other,
+ }
+}
+
+fn verify(expected_status_code: u16,
+ mut response: HyperResponse)
+ -> Result<()> {
+ let expected_status = match expected_status_code {
+ 204 => StatusCode::NoContent,
+ 401 => StatusCode::Unauthorized,
+ _ => {
+ let client_error = ClientError::UnknownStatus(expected_status_code);
+
+ return Err(Error::Client(client_error));
+ },
+ };
+
+ if response.status == expected_status {
+ return Ok(());
+ }
+
+ debug!("Expected {}, got {}", expected_status_code, response.status);
+
+ let mut s = String::default();
+ try!(response.read_to_string(&mut s));
+
+ debug!("Content: {}", s);
+
+ Err(Error::Client(ClientError::UnexpectedStatusCode(response.status)))
+}