Use actix rt for axum example

This commit is contained in:
Paul Delafosse 2022-11-27 20:50:15 +01:00
parent aa43308749
commit 4777d114c7
7 changed files with 98 additions and 26 deletions

62
Cargo.lock generated
View file

@ -12,7 +12,6 @@ dependencies = [
"anyhow",
"async-trait",
"axum",
"axum-macros",
"background-jobs",
"base64",
"chrono",
@ -40,6 +39,7 @@ dependencies = [
"tower",
"tower-http",
"tracing",
"tracing-subscriber",
"url",
]
@ -1138,6 +1138,15 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "matchers"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
dependencies = [
"regex-automata",
]
[[package]]
name = "matchit"
version = "0.6.0"
@ -1196,6 +1205,16 @@ dependencies = [
"tempfile",
]
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
dependencies = [
"overload",
"winapi",
]
[[package]]
name = "num-integer"
version = "0.1.45"
@ -1276,6 +1295,12 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "parking_lot"
version = "0.12.1"
@ -1423,6 +1448,15 @@ dependencies = [
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
dependencies = [
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.28"
@ -1895,6 +1929,7 @@ dependencies = [
"tower",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
@ -1940,6 +1975,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
@ -1962,15 +1998,33 @@ dependencies = [
"tracing",
]
[[package]]
name = "tracing-log"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
dependencies = [
"lazy_static",
"log",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
dependencies = [
"matchers",
"nu-ansi-term",
"once_cell",
"regex",
"sharded-slab",
"smallvec",
"thread_local",
"tracing",
"tracing-core",
"tracing-log",
]
[[package]]
@ -2043,6 +2097,12 @@ dependencies = [
"serde",
]
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "vcpkg"
version = "0.2.15"

View file

@ -31,26 +31,27 @@ enum_delegate = "0.2.0"
httpdate = "1.0.2"
http-signature-normalization-reqwest = { version = "0.7.1", default-features = false, features = ["sha-2", "middleware"] }
http-signature-normalization = "0.6.0"
actix-rt = { version = "2.7.0" }
actix-web = { version = "4.2.1", default-features = false, optional = true }
http-signature-normalization-actix = { version = "0.6.1", default-features = false, features = ["server", "sha-2"], optional = true }
axum = { version = "0.6.0-rc.5", features = ["json", "headers", "macros", "original-uri"], optional = true }
# Axum
tower-http = { version = "0.3", features = ["map-request-body", "util"], optional = true }
tower-http = { version = "0.3", features = ["map-request-body", "util", "trace"], optional = true }
tower = { version = "0.4.13", optional = true }
hyper = { version = "0.14", optional = true }
## FIXME: this is for debugging purpose
axum-macros = "0.3.0"
tracing-subscriber = { version = "0.3", features = ["env-filter"], optional = true }
[features]
default = ["actix"]
actix = ["dep:actix-web", "dep:http-signature-normalization-actix"]
axum = [
"dep:axum",
"dep:tower-http",
"dep:tower",
"dep:hyper",
"dep:tracing-subscriber",
]
[dev-dependencies]

View file

@ -24,7 +24,6 @@ use activitypub_federation::{
use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer};
use async_trait::async_trait;
/// FIXME: actix
use http_signature_normalization_actix::prelude::VerifyDigest;
use reqwest::Client;
use sha2::{Digest, Sha256};

View file

@ -30,11 +30,10 @@ use axum::{
Extension,
Router,
};
use http::{header::CONTENT_TYPE, HeaderMap, Request, Response};
use http::{header::CONTENT_TYPE, HeaderMap, Method, Request, Response};
use reqwest::Client;
use std::{
net::SocketAddr,
str::FromStr,
net::ToSocketAddrs,
sync::{Arc, Mutex},
};
use tokio::task;
@ -104,10 +103,14 @@ impl Instance {
.layer(middleware::from_fn(verify_request_payload)),
)
.route("/objects/:user_name", get(http_get_user))
.with_state(instance);
.with_state(instance)
.layer(TraceLayer::new_for_http());
// run it
let addr = SocketAddr::from_str(hostname)?;
let addr = hostname
.to_socket_addrs()?
.next()
.expect("Failed to lookup domain name");
let server = axum::Server::bind(&addr).serve(app.into_make_service());
task::spawn(server);
@ -116,11 +119,8 @@ impl Instance {
}
use activitypub_federation::core::axum::inbox::receive_activity;
/// FIXME
use axum_macros::debug_handler;
use tower_http::trace::TraceLayer;
#[debug_handler(body = Body)]
/// Handles requests to fetch user json over HTTP
async fn http_get_user(
State(data): State<InstanceHandle>,
request: Request<Body>,
@ -149,10 +149,9 @@ async fn http_get_user(
.expect("failed to build response")
}
/// Handles messages received in user inbox
#[debug_handler(body = BoxBody)]
async fn http_post_user_inbox(
headers: HeaderMap,
method: Method,
OriginalUri(uri): OriginalUri,
State(data): State<InstanceHandle>,
Extension(digest_verified): Extension<DigestVerified>,
@ -164,6 +163,7 @@ async fn http_post_user_inbox(
&data.clone().local_instance,
&Data::new(data),
headers,
method,
uri,
)
.await

View file

@ -1,5 +1,5 @@
use crate::{error::Error, instance::Instance, objects::note::MyPost, utils::generate_object_id};
use tracing::log::LevelFilter;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
mod activities;
mod error;
@ -7,10 +7,15 @@ mod instance;
mod objects;
mod utils;
#[tokio::main]
#[actix_rt::main]
async fn main() -> Result<(), Error> {
env_logger::builder()
.filter_level(LevelFilter::Debug)
tracing_subscriber::registry()
.with(tracing_subscriber::EnvFilter::new(
std::env::var("RUST_LOG").unwrap_or_else(|_| {
"activitypub_federation=debug,federation-axum=debug,tower_http=debug".into()
}),
))
.with(tracing_subscriber::fmt::layer())
.init();
let alpha = Instance::new("localhost:8001".to_string())?;
@ -23,6 +28,7 @@ async fn main() -> Result<(), Error> {
.local_user()
.follow(&beta.local_user(), &alpha)
.await?;
// assert that follow worked correctly
assert_eq!(
beta.local_user().followers(),

View file

@ -8,7 +8,7 @@ use crate::{
Error,
LocalInstance,
};
use http::{HeaderMap, Uri};
use http::{HeaderMap, Method, Uri};
use serde::de::DeserializeOwned;
use tracing::debug;
@ -19,6 +19,7 @@ pub async fn receive_activity<Activity, ActorT, Datatype>(
local_instance: &LocalInstance,
data: &Data<Datatype>,
headers: HeaderMap,
method: Method,
uri: Uri,
) -> Result<(), <Activity as ActivityHandler>::Error>
where
@ -29,7 +30,6 @@ where
+ From<Error>
+ From<<ActorT as ApubObject>::Error>
+ From<serde_json::Error>,
// + From<http_signature_normalization_actix::digest::middleware::VerifyError>,
<ActorT as ApubObject>::Error: From<Error> + From<anyhow::Error>,
{
local_instance.verify_url_and_domain(&activity).await?;
@ -39,7 +39,7 @@ where
.dereference(data, local_instance, request_counter)
.await?;
verify_signature(&headers, uri, actor.public_key())?;
verify_signature(&headers, method, uri, actor.public_key())?;
debug!("Verifying activity {}", activity.id().to_string());
activity.verify(data, request_counter).await?;

View file

@ -1,5 +1,5 @@
use anyhow::anyhow;
use http::{HeaderMap, Uri};
use http::{HeaderMap, Method, Uri};
use http_signature_normalization::Config;
use openssl::{hash::MessageDigest, pkey::PKey, sign::Verifier};
use std::collections::BTreeMap;
@ -8,6 +8,7 @@ use tracing::debug;
/// Verifies the HTTP signature on an incoming inbox request.
pub fn verify_signature(
headers: &HeaderMap,
method: Method,
uri: Uri,
public_key: &str,
) -> Result<(), anyhow::Error> {
@ -19,8 +20,13 @@ pub fn verify_signature(
}
}
let path_and_query = uri
.path_and_query()
.ok_or(anyhow!("empty uri while veryfying signature "))?
.as_str();
let verified = config
.begin_verify("GET", "/foo?bar=baz", header_map)?
.begin_verify(method.as_str(), path_and_query, header_map)?
.verify(|signature, signing_string| -> anyhow::Result<bool> {
debug!(
"Verifying with key {}, message {}",