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
#![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
//! * `charsets` support for decoding more text encodings than just UTF-8
//! * `compress` support for decompressing response bodies (**default**)
//! * `json` support for serialization and deserialization
//! * `form` support for url encoded forms (does not include support for multipart)
//! * `tls` support for tls connections (**default**)
//! * `tls-rustls` support for TLS connections using `rustls` instead of `native-tls`
//! * `multipart-form` support for multipart forms (does not include support for url encoding)
//!
//! # Activating a feature
//! To activate a feature, specify it in your `Cargo.toml` file like so
//! ```toml
//! attohttpc = { version = "...", features = ["json", "form", ...] }
//! ```
//!
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)
}
}
}