1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
//! ureq is a minimal request library.
//!
//! The goals of this library are:
//!
//! * Minimal dependency tree
//! * Obvious API
//!
//! ```
//! // requires feature: `ureq = { version = "*", features = ["json"] }`
//! #[macro_use]
//! extern crate ureq;
//!
//! fn main() {
//! // sync post request of some json.
//! let resp = ureq::post("https://myapi.acme.com/ingest")
//! .set("X-My-Header", "Secret")
//! .send_json(json!({
//! "name": "martin",
//! "rust": true
//! }));
//!
//! // .ok() tells if response is 200-299.
//! if resp.ok() {
//! // ....
//! }
//! }
//! ```
//!
//! # Plain requests
//!
//! Most standard methods (GET, POST, PUT etc), are supported as functions from the
//! top of the library ([`ureq::get`](fn.get.html), [`ureq::post`](fn.post.html),
//! [`ureq::put`](fn.put.html), etc).
//!
//! These top level http method functions create a [Request](struct.Request.html) instance
//! which follows a build pattern. The builders are finished using:
//!
//! * [`.call()`](struct.Request.html#method.call) without a request body.
//! * [`.send()`](struct.Request.html#method.send) with a request body as `Read`.
//! * [`.send_string()`](struct.Request.html#method.send_string) body as string.
//!
//! # JSON
//!
//! By enabling the `ureq = { version = "*", features = ["json"] }` feature,
//! the library supports serde json.
//!
//! * [`request.send_json()`](struct.Request.html#method.send_json) send body as serde json.
//! * [`response.into_json()`](struct.Response.html#method.into_json) transform response to json.
//!
//! # Agents
//!
//! To maintain a state, cookies, between requests, you use an [agent](struct.Agent.html).
//! Agents also follow the build pattern. Agents are created with
//! [`ureq::agent()`](struct.Agent.html).
//!
//! # Content-Length
//!
//! The library will set the content length on the request when using
//! [`.send_string()`](struct.Request.html#method.send_string) or
//! [`.send_json()`](struct.Request.html#method.send_json). In other cases the user
//! can optionally `request.set("Content-Length", 1234)`.
//!
//! For responses, if the `Content-Length` header is present, the methods that reads the
//! body (as string, json or read trait) are all limited to the length specified in the header.
//!
//! # Transfer-Encoding: chunked
//!
//! Dechunking is a response body is done automatically if the response headers contains
//! a `Transfer-Encoding` header.
//!
//! Sending a chunked request body is done by setting the header prior to sending a body.
//!
//! ```
//! let resp = ureq::post("http://my-server.com/ingest")
//! .set("Transfer-Encoding", "chunked")
//! .send_string("Hello world");
//! ```
//!
//! # Character encoding
//!
//! By enabling the `ureq = { version = "*", features = ["charset"] }` feature,
//! the library supports sending/receiving other character sets than `utf-8`.
//!
//! For [`response.into_string()`](struct.Response.html#method.into_string) we read the
//! header `Content-Type: text/plain; charset=iso-8859-1` and if it contains a charset
//! specification, we try to decode the body using that encoding. In the absence of, or failing
//! to interpret the charset, we fall back on `utf-8`.
//!
//! Similarly when using [`request.send_string()`](struct.Request.html#method.send_string),
//! we first check if the user has set a `; charset=<whatwg charset>` and attempt
//! to encode the request body using that.
//!
extern crate ascii;
extern crate base64;
extern crate chunked_transfer;
extern crate cookie;
#[macro_use]
extern crate lazy_static;
extern crate qstring;
extern crate url;
#[cfg(feature = "charset")]
extern crate encoding;
#[cfg(feature = "tls")]
extern crate native_tls;
#[cfg(feature = "json")]
extern crate serde_json;
mod agent;
mod body;
mod error;
mod header;
mod pool;
mod response;
mod stream;
#[cfg(feature = "json")]
mod serde_macros;
#[cfg(test)]
mod test;
pub use agent::{Agent, Request};
pub use error::Error;
pub use header::Header;
pub use response::Response;
// re-export
pub use cookie::Cookie;
#[cfg(feature = "json")]
pub use serde_json::{to_value as serde_to_value, Map as SerdeMap, Value as SerdeValue};
/// Agents are used to keep state between requests.
pub fn agent() -> Agent {
Agent::new().build()
}
/// Make a request setting the HTTP method via a string.
///
/// ```
/// ureq::request("GET", "https://www.google.com").call();
/// ```
pub fn request(method: &str, path: &str) -> Request
{
Agent::new().request(method, path)
}
/// Make a GET request.
pub fn get(path: &str) -> Request
{
request("GET", path)
}
/// Make a HEAD request.
pub fn head(path: &str) -> Request
{
request("HEAD", path)
}
/// Make a POST request.
pub fn post(path: &str) -> Request
{
request("POST", path)
}
/// Make a PUT request.
pub fn put(path: &str) -> Request
{
request("PUT", path)
}
/// Make a DELETE request.
pub fn delete(path: &str) -> Request
{
request("DELETE", path)
}
/// Make a TRACE request.
pub fn trace(path: &str) -> Request
{
request("TRACE", path)
}
/// Make an OPTIONS request.
pub fn options(path: &str) -> Request
{
request("OPTIONS", path)
}
/// Make an CONNECT request.
pub fn connect(path: &str) -> Request
{
request("CONNECT", path)
}
/// Make an PATCH request.
pub fn patch(path: &str) -> Request
{
request("PATCH", path)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn connect_http_google() {
let resp = get("http://www.google.com/").call();
assert_eq!(
"text/html; charset=ISO-8859-1",
resp.header("content-type").unwrap()
);
assert_eq!("text/html", resp.content_type());
}
#[test]
#[cfg(feature = "tls")]
fn connect_https_google() {
let resp = get("https://www.google.com/").call();
assert_eq!(
"text/html; charset=ISO-8859-1",
resp.header("content-type").unwrap()
);
assert_eq!("text/html", resp.content_type());
}
}