* Remove Request::build * All mutations on Request follow builder pattern The previous `build()` on request was necessary because mutating functions did not follow a proper builder pattern (taking `&mut self` instead of `mut self`). With a proper builder pattern, the need for `.build()` goes away. * All Request body and call methods consume self Anything which "executes" the request will now consume the `Request` to produce a `Result<Response>`. * Move all config from request to agent builder Timeouts, redirect config, proxy settings and TLS config are now on `AgentBuilder`. * Rename max_pool_connections -> max_idle_connections * Rename max_pool_connections_per_host -> max_idle_connections_per_host Consistent internal and external naming. * Introduce new AgentConfig for static config created by builder. `Agent` can be seen as having two parts. Static config and a mutable shared state between all states. The static config goes into `AgentConfig` and the mutable shared state into `AgentState`. * Replace all use of `Default` for `new`. Deriving or implementing `Default` makes for a secondary instantiation API. It is useful in some cases, but gets very confusing when there is both `new` _and_ a `Default`. It's especially devious for derived values where a reasonable default is not `0`, `false` or `None`. * Remove feature native_tls, we want only native rustls. This feature made for very clunky handling throughout the code. From a security point of view, it's better to stick with one single TLS API. Rustls recently got an official audit (very positive). https://github.com/ctz/rustls/tree/master/audit Rustls deliberately omits support for older, insecure TLS such as TLS 1.1 or RC4. This might be a problem for a user of ureq, but on balance not considered important enough to keep native_tls. * Remove auth and support for basic auth. The API just wasn't enough. A future reintroduction should at least also provide a `Bearer` mechanism and possibly more. * Rename jar -> cookie_store * Rename jar -> cookie_tin Just make some field names sync up with the type. * Drop "cookies" as default feature The need for handling cookies is probably rare, let's not enable it by default. * Change all feature checks for "cookie" to "cookies" The outward facing feature is "cookies" and I think it's better form that the code uses the official feature name instead of the optional library "cookies". * Keep `set` on Agent level as well as AgentBuilder. The idea is that an auth exchange might result in a header that need to be set _after_ the agent has been built.
3.8 KiB
ureq
Minimal request library in rust.
Usage
// sync post request of some json.
// requires feature:
// `ureq = { version = "*", features = ["json"] }`
let resp = ureq::post("https://myapi.example.com/ingest")
.set("X-My-Header", "Secret")
.send_json(serde_json::json!({
"name": "martin",
"rust": true
}))?;
// .ok() tells if response is 200-299.
if resp.ok() {
println!("success: {}", resp.into_string()?);
} else {
println!("error {}: {}", resp.status(), resp.into_string()?);
}
About 1.0.0
This crate is now 1.x.x. It signifies there will be no more breaking API changes (for better or worse). I personally use this code in production system reading data from AWS. Whether the quality is good enough for other use cases is a "YMMV".
ureq's future
I asked for feedback on ureq's future direction and came to the conclusion that there's enough interest in a simple blocking http client to keep it going. Another motivation is that I use it extensively for my own work, to talk to S3.
I'll keep maintaining ureq. I will try to keep dependencies somewhat fresh and try to address bad bugs. I will however not personally implement new features in ureq, but I do welcome PR with open arms.
The code base is extremely simple, one might even call naive. It's a good project to hack on as first learning experience in Rust. I will uphold some base line of code hygiene, but won't block a PR due to something being a bit inelegant.
Features
To enable a minimal dependency tree, some features are off by default.
You can control them when including ureq as a dependency.
ureq = { version = "*", features = ["json", "charset"] }
tlsenables https. This is enabled by default.cookiesenables handling cookies between requests in an agent.jsonenablesresponse.into_json()andrequest.send_json()via serde_json.charsetenables interpreting the charset part ofContent-Type: text/plain; charset=iso-8859-1. Without this, the library defaults to rust's built inutf-8.
Motivation
- Minimal dependency tree
- Obvious API
- Blocking API
- Convenience over correctness
- No use of unsafe
This library tries to provide a convenient request library with a minimal dependency tree and an obvious API. It is inspired by libraries like superagent and fetch API.
Sync forever
This library uses blocking socket reads and writes. When it was created, there wasn't any async/await support in rust, and for my own purposes, blocking IO was fine. At this point, one good reason to keep this library going is that it is blocking (the other is that it does not use unsafe).
TODO
- Forms with application/x-www-form-urlencoded
- multipart/form-data
- Expect 100-continue
- Use
rustlswhen ring with versioned asm symbols is released. (PR is not resolved, but most implementations have settled on 0.13)
License
Copyright (c) 2019 Martin Algesten
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.