Skip to content

Commit

Permalink
integrate http headers into rama
Browse files Browse the repository at this point in the history
  • Loading branch information
glendc committed Nov 25, 2023
1 parent 943b73f commit a0a6521
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 0 deletions.
90 changes: 90 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rama/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ license = "MIT OR Apache-2.0"
repository = "/~https://github.com/plabayo/rama"

[dependencies]
headers = "0.4"
http = "1"
http-body = "1"
http-body-util = "0.1"
Expand Down
83 changes: 83 additions & 0 deletions rama/src/net/http/headers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//! typed http headers
//!
//! rama has the opinion that headers should be strongly-typed,
//! because that’s why we’re using Rust in the first place. To set or get any header,
//! an object must implement the Header trait from this module.
//! Several common headers are already provided, such as Host, ContentType, UserAgent, and others.
//!
//! ## Why typed?
//!
//! Or, why not stringly-typed? Types give the following advantages:
//! - More difficult to typo, since typos in types should be caught by the compiler
//! - Parsing to a proper type by default
//!
//! ## Defining Custom Headers
//!
//! ### Implementing the [`Header`] trait
//!
//! Consider a Do Not Track header. It can be true or false,
//! but it represents that via the numerals 1 and 0.
//!
//! ```rust
//! use rama::net::http::{headers::Header, HeaderName, HeaderValue};
//! struct Dnt(bool);
//!
//! impl Header for Dnt {
//! fn name() -> &'static HeaderName {
//! &http::header::DNT
//! }
//!
//! fn decode<'i, I>(values: &mut I) -> Result<Self, headers::Error>
//! where
//! I: Iterator<Item = &'i HeaderValue>,
//! {
//! let value = values
//! .next()
//! .ok_or_else(headers::Error::invalid)?;
//!
//! if value == "0" {
//! Ok(Dnt(false))
//! } else if value == "1" {
//! Ok(Dnt(true))
//! } else {
//! Err(headers::Error::invalid())
//! }
//! }
//!
//! fn encode<E>(&self, values: &mut E)
//! where
//! E: Extend<HeaderValue>,
//! {
//! let s = if self.0 {
//! "1"
//! } else {
//! "0"
//! };
//!
//! let value = HeaderValue::from_static(s);
//!
//! values.extend(std::iter::once(value));
//! }
//! }
//! ```
pub use headers::{Header, HeaderMapExt};

pub use headers::{
AcceptRanges, AccessControlAllowCredentials, AccessControlAllowHeaders,
AccessControlAllowMethods, AccessControlAllowOrigin, AccessControlExposeHeaders,
AccessControlMaxAge, AccessControlRequestHeaders, AccessControlRequestMethod, Age, Allow,
Authorization, CacheControl, Connection, ContentDisposition, ContentEncoding, ContentLength,
ContentLocation, ContentRange, Cookie, Date, ETag, Error, Expect, Expires, Host, IfMatch,
IfModifiedSince, IfNoneMatch, IfRange, IfUnmodifiedSince, LastModified, Location, Origin,
Pragma, ProxyAuthorization, Range, Referer, ReferrerPolicy, RetryAfter, SecWebsocketAccept,
SecWebsocketKey, SecWebsocketVersion, Server, SetCookie, StrictTransportSecurity, Te,
TransferEncoding, Upgrade, UserAgent, Vary,
};

pub mod authorization {
//! Authorization header and types.
pub use headers::authorization::Credentials;
pub use headers::authorization::{Authorization, Basic, Bearer};
}
2 changes: 2 additions & 0 deletions rama/src/net/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ pub use http::{
header, request, response, HeaderMap, HeaderName, HeaderValue, Method, Request, Response,
StatusCode,
};

pub mod headers;

0 comments on commit a0a6521

Please sign in to comment.