#http-request #http #signatures #digest #signature #http-client

http-signature-normalization-reqwest

An HTTP Signatures library that leaves the signing to you

18 releases (11 breaking)

0.12.0 Apr 15, 2024
0.11.0 Nov 26, 2023
0.10.0 Aug 17, 2023
0.9.0 Jul 6, 2023
0.1.3 Sep 30, 2020

#968 in Cryptography

Download history 171/week @ 2024-07-03 302/week @ 2024-07-10 333/week @ 2024-07-17 397/week @ 2024-07-24 362/week @ 2024-07-31 294/week @ 2024-08-07 165/week @ 2024-08-14 123/week @ 2024-08-21 201/week @ 2024-08-28 190/week @ 2024-09-04 1037/week @ 2024-09-11 1051/week @ 2024-09-18 1140/week @ 2024-09-25 1124/week @ 2024-10-02 874/week @ 2024-10-09 1002/week @ 2024-10-16

4,438 downloads per month
Used in 17 crates (4 directly)

AGPL-3.0

68KB
1.5K SLoC

HTTP Signature Normaliztion Reqwest

An HTTP Signatures library that leaves the signing to you

Http Signature Normalization is a minimal-dependency crate for producing HTTP Signatures with user-provided signing and verification. The API is simple; there's a series of steps for creation and verification with types that ensure reasonable usage.

Usage

This crate provides extensions the RequestBuilder type from reqwest

First, add this crate to your dependencies

http-signature-normalization-reqwest = { version = "0.2.0", default-features = false, features = ["sha-2"] }
reqwest = "0.11"
sha2 = "0.9"
thiserror = "0.1"
tokio = "1"

Then, use it in your client

use http_signature_normalization_reqwest::prelude::*;
use reqwest::{header::DATE, Client};
use sha2::{Digest, Sha256};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = Config::default().require_header("accept");

    let digest = Sha256::new();

    let response = Client::new()
        .post("http://127.0.0.1:8010/")
        .header("User-Agent", "Reqwest")
        .header("Accept", "text/plain")
        .signature_with_digest(config, "my-key-id", digest, "my request body", |s| {
            println!("Signing String\n{}", s);
            Ok(base64::encode(s)) as Result<_, MyError>
        })
        .await?;

    let body = response.bytes().await.map_err(MyError::Body)?;

    println!("{:?}", body);
    Ok(())
}

#[derive(Debug, thiserror::Error)]
pub enum MyError {
    #[error("Failed to create signing string, {0}")]
    Convert(#[from] SignError),

    #[error("Failed to send request")]
    SendRequest(#[from] reqwest::Error),

    #[error("Failed to retrieve request body")]
    Body(reqwest::Error),
}

Contributing

Feel free to open issues for anything you find an issue with. Please note that any contributed code will be licensed under the AGPLv3.

License

Copyright © 2022 Riley Trautman

HTTP Signature Normalization Reqwest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

HTTP Signature Normalization Reqwest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. This file is part of HTTP Signature Normalization Reqwest.

You should have received a copy of the GNU General Public License along with HTTP Signature Normalization Reqwest. If not, see http://www.gnu.org/licenses/.

Dependencies

~4–16MB
~250K SLoC