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
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]
#![allow(clippy::needless_doctest_main)]
//! This project's goal is to provide a lightweight and simple HTTP client for the Rust ecosystem. The intended use is for
//! projects that have HTTP needs where performance is not critical or when HTTP is not the main purpose of the application.
//! Note that the project still tries to perform well and avoid allocation where possible, but stays away from Rust's
//! asynchronous stack to provide a crate that's as small as possible. Features are provided behind feature flags when
//! possible to allow users to get just what they need.
//!
//! Check out the [repository](https://github.com/sbstp/attohttpc) for more information and examples.
//!
//! # Quick start
//! ```no_run
//! # #[cfg(feature = "json")]
//! # use serde_json::json;
//! # #[cfg(feature = "json")]
//! # fn main() -> attohttpc::Result {
//! let obj = json!({
//! "hello": "world",
//! });
//!
//! let resp = attohttpc::post("https://my-api.org/do/something")
//! .header("X-My-Header", "foo") // set a header for the request
//! .param("qux", "baz") // set a query parameter
//! .json(&obj)? // set the request body (json feature required)
//! .send()?; // send the request
//!
//! // Check if the status is a 2XX code.
//! if resp.is_success() {
//! // Consume the response body as text and print it.
//! println!("{}", resp.text()?);
//! }
//! # Ok(())
//! # }
//! # #[cfg(not(feature = "json"))]
//! # fn main() {
//! # }
//! ```
//!
//! # Features
//! * `basic-auth` support for basic auth
//! * `charsets` support for decoding more text encodings than just UTF-8
//! * `compress` support for decompressing response bodies using `miniz_oxide` (**default**)
//! * `compress-zlib` support for decompressing response bodies using `zlib` instead of `miniz_oxide`
//! (see [flate2 backends](https://github.com/rust-lang/flate2-rs#backends))
//! * `compress-zlib-ng` support for decompressing response bodies using `zlib-ng` instead of `miniz_oxide`
//! (see [flate2 backends](https://github.com/rust-lang/flate2-rs#backends))
//! * `json` support for serialization and deserialization
//! * `form` support for url encoded forms (does not include support for multipart)
//! * `multipart-form` support for multipart forms (does not include support for url encoding)
//! * `tls-native` support for tls connections using the `native-tls` crate (**default**)
//! * `tls-native-vendored` activate the `vendored` feature of `native-tls`
//! * `tls-rustls-webpki-roots` support for TLS connections using `rustls` instead of `native-tls` with Web PKI roots
//! * `tls-rustls-native-roots` support for TLS connections using `rustls` with root certificates loaded from the `rustls-native-certs` crate
//!
//! # Activating a feature
//! To activate a feature, specify it in your `Cargo.toml` file like so
//! ```toml
//! attohttpc = { version = "...", features = ["json", "form", ...] }
//! ```
//!
#[cfg(feature = "__rustls")]
extern crate rustls_opt_dep as rustls;
macro_rules! debug {
($($arg:tt)+) => { log::debug!(target: "attohttpc", $($arg)+) };
}
macro_rules! warn {
($($arg:tt)+) => { log::warn!(target: "attohttpc", $($arg)+) };
}
#[cfg(feature = "charsets")]
pub mod charsets;
mod error;
mod happy;
#[cfg(feature = "multipart")]
mod multipart;
mod parsing;
mod request;
mod streams;
mod tls;
pub use crate::error::{Error, ErrorKind, InvalidResponseKind, Result};
#[cfg(feature = "multipart")]
pub use crate::multipart::{Multipart, MultipartBuilder, MultipartFile};
pub use crate::parsing::{Response, ResponseReader};
pub use crate::request::proxy::{ProxySettings, ProxySettingsBuilder};
pub use crate::request::{body, PreparedRequest, RequestBuilder, RequestInspector, Session};
#[cfg(feature = "charsets")]
pub use crate::{charsets::Charset, parsing::TextReader};
pub use http::Method;
pub use http::StatusCode;
pub mod header {
//! This module is a re-export of the `http` crate's `header` module.
pub use http::header::*;
}
/// Create a new `RequestBuilder` with the GET method.
pub fn get<U>(base_url: U) -> RequestBuilder
where
U: AsRef<str>,
{
RequestBuilder::new(Method::GET, base_url)
}
/// Create a new `RequestBuilder` with the POST method.
pub fn post<U>(base_url: U) -> RequestBuilder
where
U: AsRef<str>,
{
RequestBuilder::new(Method::POST, base_url)
}
/// Create a new `RequestBuilder` with the PUT method.
pub fn put<U>(base_url: U) -> RequestBuilder
where
U: AsRef<str>,
{
RequestBuilder::new(Method::PUT, base_url)
}
/// Create a new `RequestBuilder` with the DELETE method.
pub fn delete<U>(base_url: U) -> RequestBuilder
where
U: AsRef<str>,
{
RequestBuilder::new(Method::DELETE, base_url)
}
/// Create a new `RequestBuilder` with the HEAD method.
pub fn head<U>(base_url: U) -> RequestBuilder
where
U: AsRef<str>,
{
RequestBuilder::new(Method::HEAD, base_url)
}
/// Create a new `RequestBuilder` with the OPTIONS method.
pub fn options<U>(base_url: U) -> RequestBuilder
where
U: AsRef<str>,
{
RequestBuilder::new(Method::OPTIONS, base_url)
}
/// Create a new `RequestBuilder` with the PATCH method.
pub fn patch<U>(base_url: U) -> RequestBuilder
where
U: AsRef<str>,
{
RequestBuilder::new(Method::PATCH, base_url)
}
/// Create a new `RequestBuilder` with the TRACE method.
pub fn trace<U>(base_url: U) -> RequestBuilder
where
U: AsRef<str>,
{
RequestBuilder::new(Method::TRACE, base_url)
}
mod skip_debug {
use std::fmt;
#[derive(Clone)]
pub struct SkipDebug<T>(pub T);
impl<T> fmt::Debug for SkipDebug<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "...")
}
}
impl<T> From<T> for SkipDebug<T> {
fn from(val: T) -> SkipDebug<T> {
SkipDebug(val)
}
}
}