about summary refs log tree commit diff
path: root/net/crimp
diff options
context:
space:
mode:
Diffstat (limited to 'net/crimp')
-rw-r--r--net/crimp/src/lib.rs137
-rw-r--r--net/crimp/src/tests.rs93
2 files changed, 149 insertions, 81 deletions
diff --git a/net/crimp/src/lib.rs b/net/crimp/src/lib.rs
index b52ebc3ef09c..4dd4d6c31bd7 100644
--- a/net/crimp/src/lib.rs
+++ b/net/crimp/src/lib.rs
@@ -33,9 +33,12 @@
 //! use crimp::Request;
 //!
 //! let response = Request::get("http://httpbin.org/get")
-//!     .user_agent("crimp test suite").unwrap()
-//!     .send().unwrap()
-//!     .as_string().unwrap();
+//!     .user_agent("crimp test suite")
+//!     .unwrap()
+//!     .send()
+//!     .unwrap()
+//!     .as_string()
+//!     .unwrap();
 //!
 //! println!("Status: {}\nBody: {}", response.status, response.body);
 //! # assert_eq!(response.status, 200);
@@ -54,10 +57,9 @@
 //!
 //! All optional features are enabled by default.
 //!
-//! * `json`: Adds `Request::json` and `Response::as_json` methods
-//!   which can be used for convenient serialisation of
-//!   request/response bodies using `serde_json`. This feature adds a
-//!   dependency on the `serde` and `serde_json` crates.
+//! * `json`: Adds `Request::json` and `Response::as_json` methods which can be used for convenient
+//!   serialisation of request/response bodies using `serde_json`. This feature adds a dependency on
+//!   the `serde` and `serde_json` crates.
 //!
 //! ## Initialisation
 //!
@@ -72,32 +74,42 @@
 
 extern crate curl;
 
-#[cfg(feature = "json")] extern crate serde;
-#[cfg(feature = "json")] extern crate serde_json;
+#[cfg(feature = "json")]
+extern crate serde;
+#[cfg(feature = "json")]
+extern crate serde_json;
 
 pub use curl::init;
 
-use curl::easy::{Auth, Easy, Form, List, Transfer, ReadError, WriteError};
+use curl::easy::{Auth, Easy, Form, List, ReadError, Transfer, WriteError};
 use std::collections::HashMap;
 use std::io::Write;
 use std::path::Path;
 use std::string::{FromUtf8Error, ToString};
 use std::time::Duration;
 
-#[cfg(feature = "json")] use serde::Serialize;
-#[cfg(feature = "json")] use serde::de::DeserializeOwned;
+#[cfg(feature = "json")]
+use serde::de::DeserializeOwned;
+#[cfg(feature = "json")]
+use serde::Serialize;
 
 #[cfg(test)]
 mod tests;
 
 /// HTTP method to use for the request.
 enum Method {
-    Get, Post, Put, Patch, Delete
+    Get,
+    Post,
+    Put,
+    Patch,
+    Delete,
 }
 
 /// Certificate types for client-certificate key pairs.
 pub enum CertType {
-    P12, PEM, DER
+    P12,
+    PEM,
+    DER,
 }
 
 /// Builder structure for an HTTP request.
@@ -145,7 +157,7 @@ pub struct Response<T> {
     pub body: T,
 }
 
-impl <'a> Request<'a> {
+impl<'a> Request<'a> {
     /// Initiate an HTTP request with the given method and URL.
     fn new(method: Method, url: &'a str) -> Self {
         Request {
@@ -158,19 +170,29 @@ impl <'a> Request<'a> {
     }
 
     /// Initiate a GET request with the given URL.
-    pub fn get(url: &'a str) -> Self { Request::new(Method::Get, url) }
+    pub fn get(url: &'a str) -> Self {
+        Request::new(Method::Get, url)
+    }
 
     /// Initiate a POST request with the given URL.
-    pub fn post(url: &'a str) -> Self { Request::new(Method::Post, url) }
+    pub fn post(url: &'a str) -> Self {
+        Request::new(Method::Post, url)
+    }
 
     /// Initiate a PUT request with the given URL.
-    pub fn put(url: &'a str) -> Self { Request::new(Method::Put, url) }
+    pub fn put(url: &'a str) -> Self {
+        Request::new(Method::Put, url)
+    }
 
     /// Initiate a PATCH request with the given URL.
-    pub fn patch(url: &'a str) -> Self { Request::new(Method::Patch, url) }
+    pub fn patch(url: &'a str) -> Self {
+        Request::new(Method::Patch, url)
+    }
 
     /// Initiate a DELETE request with the given URL.
-    pub fn delete(url: &'a str) -> Self { Request::new(Method::Delete, url) }
+    pub fn delete(url: &'a str) -> Self {
+        Request::new(Method::Delete, url)
+    }
 
     /// Add an HTTP header to a request.
     pub fn header(mut self, k: &str, v: &str) -> Result<Self, curl::Error> {
@@ -188,7 +210,8 @@ impl <'a> Request<'a> {
     /// Set the `Authorization` header to a `Bearer` value with the
     /// supplied token.
     pub fn bearer_auth(mut self, token: &str) -> Result<Self, curl::Error> {
-        self.headers.append(&format!("Authorization: Bearer {}", token))?;
+        self.headers
+            .append(&format!("Authorization: Bearer {}", token))?;
         Ok(self)
     }
 
@@ -212,8 +235,11 @@ impl <'a> Request<'a> {
     /// Consult the documentation for the `ssl_cert` and `ssl_key`
     /// functions in `curl::easy::Easy2` for details on supported
     /// formats and defaults.
-    pub fn tls_client_cert<P: AsRef<Path>>(mut self, cert_type: CertType, cert: P)
-                                           -> Result<Self, curl::Error> {
+    pub fn tls_client_cert<P: AsRef<Path>>(
+        mut self,
+        cert_type: CertType,
+        cert: P,
+    ) -> Result<Self, curl::Error> {
         self.handle.ssl_cert(cert)?;
         self.handle.ssl_cert_type(match cert_type {
             CertType::P12 => "P12",
@@ -262,13 +288,17 @@ impl <'a> Request<'a> {
     /// ```
     /// # use crimp::Request;
     /// let response = Request::get("https://httpbin.org/get")
-    ///     .with_handle(|mut handle| handle.referer("Example-Referer")).unwrap()
-    ///     .send().unwrap();
+    ///     .with_handle(|mut handle| handle.referer("Example-Referer"))
+    ///     .unwrap()
+    ///     .send()
+    ///     .unwrap();
     /// #
     /// # assert!(response.is_success());
     /// ```
     pub fn with_handle<F>(mut self, function: F) -> Result<Self, curl::Error>
-    where F: FnOnce(&mut Easy) -> Result<(), curl::Error> {
+    where
+        F: FnOnce(&mut Easy) -> Result<(), curl::Error>,
+    {
         function(&mut self.handle)?;
         Ok(self)
     }
@@ -293,12 +323,15 @@ impl <'a> Request<'a> {
     /// let mut form = Form::new();
     /// form.part("some-name")
     ///     .contents("some-data".as_bytes())
-    ///     .add().unwrap();
+    ///     .add()
+    ///     .unwrap();
     ///
     /// let response = Request::post("https://httpbin.org/post")
-    ///     .user_agent("crimp test suite").unwrap()
+    ///     .user_agent("crimp test suite")
+    ///     .unwrap()
     ///     .form(form)
-    ///     .send().unwrap();
+    ///     .send()
+    ///     .unwrap();
     /// #
     /// # assert_eq!(200, response.status, "form POST should succeed");
     /// # assert_eq!(
@@ -330,10 +363,10 @@ impl <'a> Request<'a> {
         self.handle.url(self.url)?;
 
         match self.method {
-            Method::Get    => self.handle.get(true)?,
-            Method::Post   => self.handle.post(true)?,
-            Method::Put    => self.handle.put(true)?,
-            Method::Patch  => self.handle.custom_request("PATCH")?,
+            Method::Get => self.handle.get(true)?,
+            Method::Post => self.handle.post(true)?,
+            Method::Put => self.handle.put(true)?,
+            Method::Patch => self.handle.custom_request("PATCH")?,
             Method::Delete => self.handle.custom_request("DELETE")?,
         }
 
@@ -351,21 +384,22 @@ impl <'a> Request<'a> {
 
         // Optionally set content type if a body payload is configured
         // and configure the expected body size (or form payload).
-         match self.body {
+        match self.body {
             Body::Bytes { content_type, data } => {
                 self.handle.post_field_size(data.len() as u64)?;
-                self.headers.append(&format!("Content-Type: {}", content_type))?;
-            },
+                self.headers
+                    .append(&format!("Content-Type: {}", content_type))?;
+            }
 
             #[cfg(feature = "json")]
             Body::Json(ref data) => {
                 self.handle.post_field_size(data.len() as u64)?;
                 self.headers.append("Content-Type: application/json")?;
-            },
+            }
 
-             // Do not set content-type header at all if there is no
-             // body, or if the form handler was invoked above.
-             _ => (),
+            // Do not set content-type header at all if there is no
+            // body, or if the form handler was invoked above.
+            _ => (),
         };
 
         // Configure headers on the request:
@@ -407,9 +441,7 @@ impl <'a> Request<'a> {
                     return true;
                 }
 
-                headers.insert(
-                    split[0].trim().to_string(), split[1].trim().to_string()
-                );
+                headers.insert(split[0].trim().to_string(), split[1].trim().to_string());
                 true
             })?;
 
@@ -427,7 +459,7 @@ impl <'a> Request<'a> {
         Ok(Response {
             status: self.handle.response_code()?,
             headers,
-            body
+            body,
         })
     }
 }
@@ -438,13 +470,14 @@ impl <'a> Request<'a> {
 ///
 /// As we manually set the expected upload size, cURL will call the
 /// read callback repeatedly until it has all the data it needs.
-fn chunked_read_function<'easy, 'data>(transfer: &mut Transfer<'easy, 'data>,
-                                       data: &'data [u8]) -> Result<(), curl::Error> {
+fn chunked_read_function<'easy, 'data>(
+    transfer: &mut Transfer<'easy, 'data>,
+    data: &'data [u8],
+) -> Result<(), curl::Error> {
     let mut data = data;
 
     transfer.read_function(move |mut into| {
-        let written = into.write(data)
-            .map_err(|_| ReadError::Abort)?;
+        let written = into.write(data).map_err(|_| ReadError::Abort)?;
 
         data = &data[written..];
 
@@ -452,7 +485,7 @@ fn chunked_read_function<'easy, 'data>(transfer: &mut Transfer<'easy, 'data>,
     })
 }
 
-impl <T> Response<T> {
+impl<T> Response<T> {
     /// Check whether the status code of this HTTP response is a
     /// success (i.e. in the 200-299 range).
     pub fn is_success(&self) -> bool {
@@ -466,9 +499,11 @@ impl <T> Response<T> {
     /// This function exists for convenience to avoid having to write
     /// repetitive `if !response.is_success() { ... }` blocks.
     pub fn error_for_status<F, E>(self, closure: F) -> Result<Self, E>
-    where F: FnOnce(Self) -> E {
+    where
+        F: FnOnce(Self) -> E,
+    {
         if !self.is_success() {
-            return Err(closure(self))
+            return Err(closure(self));
         }
 
         Ok(self)
diff --git a/net/crimp/src/tests.rs b/net/crimp/src/tests.rs
index 6c2bc4f5b37a..e8e9223ce804 100644
--- a/net/crimp/src/tests.rs
+++ b/net/crimp/src/tests.rs
@@ -6,7 +6,7 @@
 //    docker run --rm -p 4662:80 kennethreitz/httpbin
 
 use super::*;
-use serde_json::{Value, json};
+use serde_json::{json, Value};
 
 // These tests check whether the correct HTTP method is used in the
 // requests.
@@ -14,7 +14,8 @@ use serde_json::{Value, json};
 #[test]
 fn test_http_get() {
     let resp = Request::get("http://127.0.0.1:4662/get")
-        .send().expect("failed to send request");
+        .send()
+        .expect("failed to send request");
 
     assert!(resp.is_success(), "request should have succeeded");
 }
@@ -22,7 +23,8 @@ fn test_http_get() {
 #[test]
 fn test_http_delete() {
     let resp = Request::delete("http://127.0.0.1:4662/delete")
-        .send().expect("failed to send request");
+        .send()
+        .expect("failed to send request");
 
     assert_eq!(200, resp.status, "response status should be 200 OK");
 }
@@ -30,7 +32,8 @@ fn test_http_delete() {
 #[test]
 fn test_http_put() {
     let resp = Request::put("http://127.0.0.1:4662/put")
-        .send().expect("failed to send request");
+        .send()
+        .expect("failed to send request");
 
     assert_eq!(200, resp.status, "response status should be 200 OK");
 }
@@ -38,7 +41,8 @@ fn test_http_put() {
 #[test]
 fn test_http_patch() {
     let resp = Request::patch("http://127.0.0.1:4662/patch")
-        .send().expect("failed to send request");
+        .send()
+        .expect("failed to send request");
 
     assert_eq!(200, resp.status, "response status should be 200 OK");
 }
@@ -50,18 +54,25 @@ fn test_http_patch() {
 fn test_http_post() {
     let body = "test body";
     let response = Request::post("http://127.0.0.1:4662/post")
-        .user_agent("crimp test suite").expect("failed to set user-agent")
-        .timeout(Duration::from_secs(5)).expect("failed to set request timeout")
+        .user_agent("crimp test suite")
+        .expect("failed to set user-agent")
+        .timeout(Duration::from_secs(5))
+        .expect("failed to set request timeout")
         .body("text/plain", &body.as_bytes())
-        .send().expect("failed to send request")
-        .as_json::<Value>().expect("failed to deserialize response");
+        .send()
+        .expect("failed to send request")
+        .as_json::<Value>()
+        .expect("failed to deserialize response");
 
     let data = response.body;
 
     assert_eq!(200, response.status, "response status should be 200 OK");
 
-    assert_eq!(data.get("data").unwrap(), &json!("test body"),
-               "test body should have been POSTed");
+    assert_eq!(
+        data.get("data").unwrap(),
+        &json!("test body"),
+        "test body should have been POSTed"
+    );
 
     assert_eq!(
         data.get("headers").unwrap().get("Content-Type").unwrap(),
@@ -70,26 +81,34 @@ fn test_http_post() {
     );
 }
 
-#[cfg(feature = "json")] #[test]
+#[cfg(feature = "json")]
+#[test]
 fn test_http_post_json() {
     let body = json!({
         "purpose": "testing!"
     });
 
     let response = Request::post("http://127.0.0.1:4662/post")
-        .user_agent("crimp test suite").expect("failed to set user-agent")
-        .timeout(Duration::from_secs(5)).expect("failed to set request timeout")
-        .json(&body).expect("request serialization failed")
-        .send().expect("failed to send request")
-        .as_json::<Value>().expect("failed to deserialize response");
-
+        .user_agent("crimp test suite")
+        .expect("failed to set user-agent")
+        .timeout(Duration::from_secs(5))
+        .expect("failed to set request timeout")
+        .json(&body)
+        .expect("request serialization failed")
+        .send()
+        .expect("failed to send request")
+        .as_json::<Value>()
+        .expect("failed to deserialize response");
 
     let data = response.body;
 
     assert_eq!(200, response.status, "response status should be 200 OK");
 
-    assert_eq!(data.get("json").unwrap(), &body,
-               "test body should have been POSTed");
+    assert_eq!(
+        data.get("json").unwrap(),
+        &body,
+        "test body should have been POSTed"
+    );
 
     assert_eq!(
         data.get("headers").unwrap().get("Content-Type").unwrap(),
@@ -104,8 +123,10 @@ fn test_http_post_json() {
 #[test]
 fn test_bearer_auth() {
     let response = Request::get("http://127.0.0.1:4662/bearer")
-        .bearer_auth("some-token").expect("failed to set auth header")
-        .send().expect("failed to send request");
+        .bearer_auth("some-token")
+        .expect("failed to set auth header")
+        .send()
+        .expect("failed to send request");
 
     assert!(response.is_success(), "authorized request should succeed");
 }
@@ -115,8 +136,10 @@ fn test_basic_auth() {
     let request = Request::get("http://127.0.0.1:4662/basic-auth/alan_watts/oneness");
 
     let response = request
-        .basic_auth("alan_watts", "oneness").expect("failed to set auth header")
-        .send().expect("failed to send request");
+        .basic_auth("alan_watts", "oneness")
+        .expect("failed to set auth header")
+        .send()
+        .expect("failed to send request");
 
     assert!(response.is_success(), "authorized request should succeed");
 }
@@ -129,14 +152,20 @@ fn test_large_body() {
 
     let resp = Request::post("http://127.0.0.1:4662/post")
         .body("application/octet-stream", &[0; BODY_SIZE])
-        .send().expect("sending request")
-        .as_json::<Value>().expect("JSON deserialisation");
+        .send()
+        .expect("sending request")
+        .as_json::<Value>()
+        .expect("JSON deserialisation");
 
     // httpbin returns the uploaded data as a string in the `data`
     // field.
     let data = resp.body.get("data").unwrap().as_str().unwrap();
 
-    assert_eq!(BODY_SIZE, data.len(), "uploaded data length should be correct");
+    assert_eq!(
+        BODY_SIZE,
+        data.len(),
+        "uploaded data length should be correct"
+    );
 }
 
 // Tests for various other features.
@@ -144,9 +173,13 @@ fn test_large_body() {
 #[test]
 fn test_error_for_status() {
     let response = Request::get("http://127.0.0.1:4662/patch")
-        .send().expect("failed to send request")
+        .send()
+        .expect("failed to send request")
         .error_for_status(|resp| format!("Response error code: {}", resp.status));
 
-    assert_eq!(Err("Response error code: 405".into()), response,
-               "returned error should be converted into Result::Err");
+    assert_eq!(
+        Err("Response error code: 405".into()),
+        response,
+        "returned error should be converted into Result::Err"
+    );
 }