Update documentation. (#73)

* Update documentation.

Synchronize goals section between README and rustdoc, and add two goals
(blocking API; no unsafe) that were mentioned elsewhere in the README.

Add error handling to examples for the module and for the Response
object.

And a section on synthetic errors to the top-level module documentation.

* Add back missing close brace.

* Add main function that returns Result.

* Add links to send_bytes and send_form.

* Document chunked encoding for send.

* Use a larger vec of bytes for send.
This commit is contained in:
Jacob Hoffman-Andrews
2020-06-21 00:55:50 -07:00
committed by GitHub
parent 7adbd57308
commit fdc1f37662
4 changed files with 71 additions and 31 deletions

View File

@@ -13,10 +13,8 @@
#[macro_use]
extern crate ureq;
fn main() {
// sync post request of some json.
let resp = ureq::post("https://myapi.acme.com/ingest")
let resp = ureq::post("https://myapi.example.com/ingest")
.set("X-My-Header", "Secret")
.send_json(json!({
"name": "martin",
@@ -25,8 +23,11 @@ fn main() {
// .ok() tells if response is 200-299.
if resp.ok() {
// ...
}
println!("success: {}", resp.into_string()?);
} else {
// This can include errors like failure to parse URL or connect timeout.
// They are treated as synthetic HTTP-level error statuses.
println!("error {}: {}", resp.status(), resp.into_string()?);
}
```
@@ -77,7 +78,9 @@ You can control them when including `ureq` as a dependency.
* Minimal dependency tree
* Obvious API
* Convencience over correctness
* 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
@@ -104,8 +107,8 @@ for convenience over correctness, so the decision is left to the user.
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 relies
on very little use of unsafe).
this library going is that it is blocking (the other is that it does not
use unsafe).
## TODO

View File

@@ -6,14 +6,18 @@
//!
//! * Minimal dependency tree
//! * Obvious API
//! * Blocking API
//! * Convenience over correctness
//! * No use of unsafe
//!
//! ```
//! // requires feature: `ureq = { version = "*", features = ["json"] }`
//! # #[cfg(feature = "json")] {
//! use ureq::json;
//!
//! fn main() -> std::io::Result<()> {
//! // sync post request of some json.
//! let resp = ureq::post("https://myapi.acme.com/ingest")
//! let resp = ureq::post("https://myapi.example.com/ingest")
//! .set("X-My-Header", "Secret")
//! .send_json(json!({
//! "name": "martin",
@@ -22,7 +26,13 @@
//!
//! // .ok() tells if response is 200-299.
//! if resp.ok() {
//! // ....
//! println!("success: {}", resp.into_string()?);
//! } else {
//! // This can include errors like failure to parse URL or connect timeout.
//! // They are treated as synthetic HTTP-level error statuses.
//! println!("error {}: {}", resp.status(), resp.into_string()?);
//! }
//! Ok(())
//! }
//! # }
//! ```
@@ -37,8 +47,10 @@
//! 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()`](struct.Request.html#method.send) with a request body as `Read` (chunked encoding).
//! * [`.send_string()`](struct.Request.html#method.send_string) body as string.
//! * [`.send_bytes()`](struct.Request.html#method.send_bytes) body as bytes.
//! * [`.send_form()`](struct.Request.html#method.send_form) key-value pairs as application/x-www-form-urlencoded.
//!
//! # JSON
//!
@@ -91,6 +103,20 @@
//! we first check if the user has set a `; charset=<whatwg charset>` and attempt
//! to encode the request body using that.
//!
//! # Synthetic errors
//!
//! Rather than exposing a custom error type through results, this library has opted for
//! representing potential connection/TLS/etc errors as HTTP response codes. These invented codes
//! are called "[synthetic](struct.Response.html#method.synthetic)."
//!
//! The idea is that from a library user's point of view the distinction of whether a failure
//! originated in the remote server (500, 502) etc, or some transient network failure, the code
//! path of handling that would most often be the same.
//!
//! As a result, reading from a Response may yield an error message generated by the ureq library.
//! To handle these errors, use the
//! [`response.synthetic_error()`](struct.Response.html#method.synthetic_error) method.
//!
mod agent;
mod body;

View File

@@ -214,16 +214,19 @@ impl Request {
/// Send data from a reader.
///
/// The `Content-Length` header is not set because we can't know the length of the reader.
/// This uses [chunked transfer encoding](https://tools.ietf.org/html/rfc7230#section-4.1).
/// The caller is responsible for setting the Transfer-Encoding: chunked header.
///
/// The input from the reader is buffered into chunks of size 16,384, the max size of a TLS fragment.
///
/// ```
/// use std::io::Cursor;
///
/// let text = "Hello there!\n";
/// let read = Cursor::new(text.to_string().into_bytes());
/// let read = Cursor::new(vec![0x20; 100_000]);
///
/// let resp = ureq::post("/somewhere")
/// let resp = ureq::post("http://localhost/example-upload")
/// .set("Content-Type", "text/plain")
/// .set("Transfer-Encoding", "chunked")
/// .send(read);
/// ```
pub fn send(&mut self, reader: impl Read + 'static) -> Response {

View File

@@ -29,8 +29,16 @@ pub const DEFAULT_CHARACTER_SET: &str = "utf-8";
/// [`into_json_deserialize()`](#method.into_json_deserialize) or
/// [`into_string()`](#method.into_string) consumes the response.
///
/// All error handling, including URL parse errors and connection errors, is done by mapping onto
/// [synthetic errors](#method.synthetic). Callers must check response.synthetic_error(),
/// response.is_ok(), or response.error() before relying on the contents of the reader.
///
/// ```
/// let response = ureq::get("https://www.google.com").call();
/// if let Some(error) = response.synthetic_error() {
/// eprintln!("{}", error);
/// return;
/// }
///
/// // socket is still open and the response body has not been read.
///