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

@@ -6,23 +6,33 @@
//!
//! * 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;
//!
//! // 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
//! }));
//! fn main() -> std::io::Result<()> {
//! // sync post request of some json.
//! let resp = ureq::post("https://myapi.example.com/ingest")
//! .set("X-My-Header", "Secret")
//! .send_json(json!({
//! "name": "martin",
//! "rust": true
//! }));
//!
//! // .ok() tells if response is 200-299.
//! if resp.ok() {
//! // ....
//! // .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.
///