• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

.github/H03-May-2022-9086

examples/H03-May-2022-357309

src/H03-May-2022-6,9054,534

tests/H03-May-2022-126113

.cargo-checksum.jsonH A D03-May-202289 11

.cargo_vcs_info.jsonH A D01-Jan-197074 65

.gitignoreH A D29-Nov-197338 65

CHANGELOG.mdH A D29-Nov-19737.7 KiB176150

CONTRIBUTING.mdH A D29-Nov-1973637 2214

Cargo.lockH A D01-Jan-197021.3 KiB847752

Cargo.tomlH A D01-Jan-19702.4 KiB11189

Cargo.toml.orig-cargoH A D29-Nov-19731.7 KiB5548

LICENSE-APACHEH A D29-Nov-197311.1 KiB202169

LICENSE-MITH A D29-Nov-19731 KiB2217

README.mdH A D29-Nov-197310.8 KiB272211

README.tplH A D29-Nov-19731.4 KiB2420

test.shH A D29-Nov-1973406 1511

README.md

1[comment]: # (README.md is autogenerated from src/lib.rs by `cargo readme > README.md`)
2
3# ureq
4
5A simple, safe HTTP client.
6
7Ureq's first priority is being easy for you to use. It's great for
8anyone who wants a low-overhead HTTP client that just gets the job done. Works
9very well with HTTP APIs. Its features include cookies, JSON, HTTP proxies,
10HTTPS, and charset decoding.
11
12Ureq is in pure Rust for safety and ease of understanding. It avoids using
13`unsafe` directly. It [uses blocking I/O][blocking] instead of async I/O, because that keeps
14the API simple and and keeps dependencies to a minimum. For TLS, ureq uses
15[rustls].
16
17Version 2.0.0 was released recently and changed some APIs. See the [changelog] for details.
18
19[blocking]: #blocking-io-for-simplicity
20[changelog]: https://github.com/algesten/ureq/blob/master/CHANGELOG.md
21
22
23### Usage
24
25In its simplest form, ureq looks like this:
26
27```rust
28fn main() -> Result<(), ureq::Error> {
29    let body: String = ureq::get("http://example.com")
30        .set("Example-Header", "header value")
31        .call()?
32        .into_string()?;
33    Ok(())
34}
35```
36
37For more involved tasks, you'll want to create an [Agent]. An Agent
38holds a connection pool for reuse, and a cookie store if you use the
39"cookies" feature. An Agent can be cheaply cloned due to an internal
40[Arc](std::sync::Arc) and all clones of an Agent share state among each other. Creating
41an Agent also allows setting options like the TLS configuration.
42
43```rust
44  use ureq::{Agent, AgentBuilder};
45  use std::time::Duration;
46
47  let agent: Agent = ureq::AgentBuilder::new()
48      .timeout_read(Duration::from_secs(5))
49      .timeout_write(Duration::from_secs(5))
50      .build();
51  let body: String = agent.get("http://example.com/page")
52      .call()?
53      .into_string()?;
54
55  // Reuses the connection from previous request.
56  let response: String = agent.put("http://example.com/upload")
57      .set("Authorization", "example-token")
58      .call()?
59      .into_string()?;
60```
61
62Ureq supports sending and receiving json, if you enable the "json" feature:
63
64```rust
65  // Requires the `json` feature enabled.
66  let resp: String = ureq::post("http://myapi.example.com/ingest")
67      .set("X-My-Header", "Secret")
68      .send_json(ureq::json!({
69          "name": "martin",
70          "rust": true
71      }))?
72      .into_string()?;
73```
74
75### Error handling
76
77ureq returns errors via `Result<T, ureq::Error>`. That includes I/O errors,
78protocol errors, and status code errors (when the server responded 4xx or
795xx)
80
81```rust
82use ureq::Error;
83
84match ureq::get("http://mypage.example.com/").call() {
85    Ok(response) => { /* it worked */},
86    Err(Error::Status(code, response)) => {
87        /* the server returned an unexpected status
88           code (such as 400, 500 etc) */
89    }
90    Err(_) => { /* some kind of io/transport error */ }
91}
92```
93
94More details on the [Error] type.
95
96### Features
97
98To enable a minimal dependency tree, some features are off by default.
99You can control them when including ureq as a dependency.
100
101`ureq = { version = "*", features = ["json", "charset"] }`
102
103* `tls` enables https. This is enabled by default.
104* `cookies` enables cookies.
105* `json` enables [Response::into_json()] and [Request::send_json()] via serde_json.
106* `charset` enables interpreting the charset part of the Content-Type header
107   (e.g.  `Content-Type: text/plain; charset=iso-8859-1`). Without this, the
108   library defaults to Rust's built in `utf-8`.
109* `socks-proxy` enables proxy config using the `socks4://`, `socks4a://`, `socks5://` and `socks://` (equal to `socks5://`) prefix.
110
111## Plain requests
112
113Most standard methods (GET, POST, PUT etc), are supported as functions from the
114top of the library ([get()], [post()], [put()], etc).
115
116These top level http method functions create a [Request] instance
117which follows a build pattern. The builders are finished using:
118
119* [`.call()`][Request::call()] without a request body.
120* [`.send()`][Request::send()] with a request body as [Read][std::io::Read] (chunked encoding support for non-known sized readers).
121* [`.send_string()`][Request::send_string()] body as string.
122* [`.send_bytes()`][Request::send_bytes()] body as bytes.
123* [`.send_form()`][Request::send_form()] key-value pairs as application/x-www-form-urlencoded.
124
125## JSON
126
127By enabling the `ureq = { version = "*", features = ["json"] }` feature,
128the library supports serde json.
129
130* [`request.send_json()`][Request::send_json()] send body as serde json.
131* [`response.into_json()`][Response::into_json()] transform response to json.
132
133## Content-Length and Transfer-Encoding
134
135The library will send a Content-Length header on requests with bodies of
136known size, in other words, those sent with
137[`.send_string()`][Request::send_string()],
138[`.send_bytes()`][Request::send_bytes()],
139[`.send_form()`][Request::send_form()], or
140[`.send_json()`][Request::send_json()]. If you send a
141request body with [`.send()`][Request::send()],
142which takes a [Read][std::io::Read] of unknown size, ureq will send Transfer-Encoding:
143chunked, and encode the body accordingly. Bodyless requests
144(GETs and HEADs) are sent with [`.call()`][Request::call()]
145and ureq adds neither a Content-Length nor a Transfer-Encoding header.
146
147If you set your own Content-Length or Transfer-Encoding header before
148sending the body, ureq will respect that header by not overriding it,
149and by encoding the body or not, as indicated by the headers you set.
150
151```rust
152let resp = ureq::post("http://my-server.com/ingest")
153    .set("Transfer-Encoding", "chunked")
154    .send_string("Hello world");
155```
156
157## Character encoding
158
159By enabling the `ureq = { version = "*", features = ["charset"] }` feature,
160the library supports sending/receiving other character sets than `utf-8`.
161
162For [`response.into_string()`][Response::into_string()] we read the
163header `Content-Type: text/plain; charset=iso-8859-1` and if it contains a charset
164specification, we try to decode the body using that encoding. In the absence of, or failing
165to interpret the charset, we fall back on `utf-8`.
166
167Similarly when using [`request.send_string()`][Request::send_string()],
168we first check if the user has set a `; charset=<whatwg charset>` and attempt
169to encode the request body using that.
170
171
172## Proxying
173
174ureq supports two kinds of proxies,  HTTP [`CONNECT`], [`SOCKS4`] and [`SOCKS5`], the former is
175always available while the latter must be enabled using the feature
176`ureq = { version = "*", features = ["socks-proxy"] }`.
177
178Proxies settings are configured on an [Agent] (using [AgentBuilder]). All request sent
179through the agent will be proxied.
180
181### Example using HTTP CONNECT
182
183```rust
184fn proxy_example_1() -> std::result::Result<(), ureq::Error> {
185    // Configure an http connect proxy. Notice we could have used
186    // the http:// prefix here (it's optional).
187    let proxy = ureq::Proxy::new("user:password@cool.proxy:9090")?;
188    let agent = ureq::AgentBuilder::new()
189        .proxy(proxy)
190        .build();
191
192    // This is proxied.
193    let resp = agent.get("http://cool.server").call()?;
194    Ok(())
195}
196```
197
198### Example using SOCKS5
199
200```rust
201fn proxy_example_2() -> std::result::Result<(), ureq::Error> {
202    // Configure a SOCKS proxy.
203    let proxy = ureq::Proxy::new("socks5://user:password@cool.proxy:9090")?;
204    let agent = ureq::AgentBuilder::new()
205        .proxy(proxy)
206        .build();
207
208    // This is proxied.
209    let resp = agent.get("http://cool.server").call()?;
210    Ok(())
211}
212```
213
214## Blocking I/O for simplicity
215
216Ureq uses blocking I/O rather than Rust's newer [asynchronous (async) I/O][async]. Async I/O
217allows serving many concurrent requests without high costs in memory and OS threads. But
218it comes at a cost in complexity. Async programs need to pull in a runtime (usually
219[async-std] or [tokio]). They also need async variants of any method that might block, and of
220[any method that might call another method that might block][what-color]. That means async
221programs usually have a lot of dependencies - which adds to compile times, and increases
222risk.
223
224The costs of async are worth paying, if you're writing an HTTP server that must serve
225many many clients with minimal overhead. However, for HTTP _clients_, we believe that the
226cost is usually not worth paying. The low-cost alternative to async I/O is blocking I/O,
227which has a different price: it requires an OS thread per concurrent request. However,
228that price is usually not high: most HTTP clients make requests sequentially, or with
229low concurrency.
230
231That's why ureq uses blocking I/O and plans to stay that way. Other HTTP clients offer both
232an async API and a blocking API, but we want to offer a blocking API without pulling in all
233the dependencies required by an async API.
234
235[async]: https://rust-lang.github.io/async-book/01_getting_started/02_why_async.html
236[async-std]: https://github.com/async-rs/async-std#async-std
237[tokio]: https://github.com/tokio-rs/tokio#tokio
238[what-color]: https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/
239[`CONNECT`]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT
240[`SOCKS4`]: https://en.wikipedia.org/wiki/SOCKS#SOCKS4
241[`SOCKS5`]: https://en.wikipedia.org/wiki/SOCKS#SOCKS5
242
243------------------------------------------------------------------------------
244
245Ureq is inspired by other great HTTP clients like
246[superagent](http://visionmedia.github.io/superagent/) and
247[the fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).
248
249If ureq is not what you're looking for, check out these other Rust HTTP clients:
250[surf](https://crates.io/crates/surf), [reqwest](https://crates.io/crates/reqwest),
251[isahc](https://crates.io/crates/isahc), [attohttpc](https://crates.io/crates/attohttpc),
252[actix-web](https://crates.io/crates/actix-web), and [hyper](https://crates.io/crates/hyper).
253
254
255[rustls]: https://docs.rs/rustls/
256[std::sync::Arc]: https://doc.rust-lang.org/stable/alloc/sync/struct.Arc.html
257[std::io::Read]: https://doc.rust-lang.org/stable/std/io/trait.Read.html
258[Agent]: https://docs.rs/ureq/latest/ureq/struct.Agent.html
259[get()]: https://docs.rs/ureq/latest/ureq/fn.get.html
260[post()]: https://docs.rs/ureq/latest/ureq/fn.post.html
261[put()]: https://docs.rs/ureq/latest/ureq/fn.put.html
262[Request]: https://docs.rs/ureq/latest/ureq/struct.Request.html
263[Error]: https://docs.rs/ureq/latest/ureq/enum.Error.html
264[Request::call()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.call
265[Request::send()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.send
266[Request::send_bytes()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.send_bytes
267[Request::send_string()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.send_string
268[Request::send_json()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.send_json
269[Request::send_form()]: https://docs.rs/ureq/latest/ureq/struct.Request.html#method.send_form
270[Response::into_json()]: https://docs.rs/ureq/latest/ureq/struct.Response.html#method.into_json
271[Response::into_string()]: https://docs.rs/ureq/latest/ureq/struct.Response.html#method.into_string
272

README.tpl