mirror of
https://git.asonix.dog/asonix/http-signature-normalization.git
synced 2024-11-25 10:51:01 +00:00
Add ability to set host header
This commit is contained in:
parent
7538969a0b
commit
2c031a7a1d
3 changed files with 41 additions and 2 deletions
|
@ -37,7 +37,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
std::env::set_var("RUST_LOG", "info");
|
std::env::set_var("RUST_LOG", "info");
|
||||||
pretty_env_logger::init();
|
pretty_env_logger::init();
|
||||||
|
|
||||||
let config = Config::default().require_header("accept");
|
let config = Config::default().require_header("accept").set_host_header();
|
||||||
|
|
||||||
request(config.clone()).await?;
|
request(config.clone()).await?;
|
||||||
request(config.dont_use_created_field()).await?;
|
request(config.dont_use_created_field()).await?;
|
||||||
|
|
|
@ -279,6 +279,9 @@ pub trait Sign {
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// The inner config type
|
/// The inner config type
|
||||||
config: http_signature_normalization::Config,
|
config: http_signature_normalization::Config,
|
||||||
|
|
||||||
|
/// Whether to set the Host header
|
||||||
|
set_host: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
@ -315,6 +318,10 @@ pub enum PrepareSignError {
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
/// Some headers were marked as required, but are missing
|
/// Some headers were marked as required, but are missing
|
||||||
RequiredError(#[from] RequiredError),
|
RequiredError(#[from] RequiredError),
|
||||||
|
|
||||||
|
#[error("No host provided for URL, {0}")]
|
||||||
|
/// Missing host
|
||||||
|
Host(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<http_signature_normalization::PrepareVerifyError> for PrepareVerifyError {
|
impl From<http_signature_normalization::PrepareVerifyError> for PrepareVerifyError {
|
||||||
|
@ -342,6 +349,16 @@ impl Config {
|
||||||
Config::default()
|
Config::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Since manually setting the Host header doesn't work so well in AWC, you can use this method
|
||||||
|
/// to enable setting the Host header for signing requests without breaking client
|
||||||
|
/// functionality
|
||||||
|
pub fn set_host_header(self) -> Self {
|
||||||
|
Config {
|
||||||
|
config: self.config,
|
||||||
|
set_host: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Opt out of using the (created) and (expires) fields introduced in draft 11
|
/// Opt out of using the (created) and (expires) fields introduced in draft 11
|
||||||
///
|
///
|
||||||
/// Use this for compatibility with mastodon
|
/// Use this for compatibility with mastodon
|
||||||
|
@ -351,6 +368,7 @@ impl Config {
|
||||||
pub fn dont_use_created_field(self) -> Self {
|
pub fn dont_use_created_field(self) -> Self {
|
||||||
Config {
|
Config {
|
||||||
config: self.config.dont_use_created_field(),
|
config: self.config.dont_use_created_field(),
|
||||||
|
set_host: self.set_host,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,6 +376,7 @@ impl Config {
|
||||||
pub fn set_expiration(self, expires_after: Duration) -> Self {
|
pub fn set_expiration(self, expires_after: Duration) -> Self {
|
||||||
Config {
|
Config {
|
||||||
config: self.config.set_expiration(expires_after),
|
config: self.config.set_expiration(expires_after),
|
||||||
|
set_host: self.set_host,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,6 +384,7 @@ impl Config {
|
||||||
pub fn require_header(self, header: &str) -> Self {
|
pub fn require_header(self, header: &str) -> Self {
|
||||||
Config {
|
Config {
|
||||||
config: self.config.require_header(header),
|
config: self.config.require_header(header),
|
||||||
|
set_host: self.set_host,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,10 +66,29 @@ where
|
||||||
E: From<BlockingError<E>> + From<PrepareSignError> + std::fmt::Debug + Send + 'static,
|
E: From<BlockingError<E>> + From<PrepareSignError> + std::fmt::Debug + Send + 'static,
|
||||||
K: Display,
|
K: Display,
|
||||||
{
|
{
|
||||||
|
let mut headers = request.headers().clone();
|
||||||
|
if config.set_host {
|
||||||
|
let header_string = request
|
||||||
|
.get_uri()
|
||||||
|
.host()
|
||||||
|
.ok_or_else(|| PrepareSignError::Host(request.get_uri().to_string()))?
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
let header_string = match request.get_uri().port().map(|p| p.as_u16()) {
|
||||||
|
None | Some(443) | Some(80) => header_string,
|
||||||
|
Some(port) => format!("{}:{}", header_string, port),
|
||||||
|
};
|
||||||
|
headers.insert(
|
||||||
|
"Host".parse().unwrap(),
|
||||||
|
header_string
|
||||||
|
.parse()
|
||||||
|
.map_err(|_| PrepareSignError::Host(request.get_uri().to_string()))?,
|
||||||
|
);
|
||||||
|
}
|
||||||
let unsigned = config.begin_sign(
|
let unsigned = config.begin_sign(
|
||||||
request.get_method(),
|
request.get_method(),
|
||||||
request.get_uri().path_and_query(),
|
request.get_uri().path_and_query(),
|
||||||
request.headers().clone(),
|
headers,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let key_id = key_id.to_string();
|
let key_id = key_id.to_string();
|
||||||
|
|
Loading…
Reference in a new issue