Skip to content

Commit 08e46f2

Browse files
committed
Delete standalone ohttp-relay listeners
These were previously necessary for the integration test, but we can now use an actual mailroom instance instead of a custom ohttp_relay listener. The unix socket test wasn't adding much value AFAICT so I deleted it. Unix sockets are supported by the mailroom `listener` parameter but we'd just be testing an external dependency, not internal logic.
1 parent 01b6bdc commit 08e46f2

7 files changed

Lines changed: 29 additions & 154 deletions

File tree

Cargo-minimal.lock

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2871,7 +2871,6 @@ dependencies = [
28712871
"tokio-rustls-acme",
28722872
"tokio-stream",
28732873
"tokio-tungstenite",
2874-
"tokio-util",
28752874
"tower",
28762875
"tracing",
28772876
"tracing-subscriber",

Cargo-recent.lock

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2871,7 +2871,6 @@ dependencies = [
28712871
"tokio-rustls-acme",
28722872
"tokio-stream",
28732873
"tokio-tungstenite",
2874-
"tokio-util",
28752874
"tower",
28762875
"tracing",
28772876
"tracing-subscriber",

payjoin-mailroom/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ tokio-listener = { version = "0.5", features = ["axum08", "serde"] }
7272
tokio-rustls-acme = { version = "0.9.0", features = ["axum"], optional = true }
7373
tokio-stream = { version = "0.1.17", features = ["net"] }
7474
tokio-tungstenite = { version = "0.27.0", optional = true }
75-
tokio-util = { version = "0.7.16", features = ["net", "codec"] }
7675
tower = "0.5"
7776
tracing = "0.1"
7877
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }

payjoin-mailroom/src/lib.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub async fn serve_manual_tls(
7979
config: Config,
8080
tls_config: Option<axum_server::tls_rustls::RustlsConfig>,
8181
root_store: rustls::RootCertStore,
82+
default_gateway: Option<crate::ohttp_relay::GatewayUri>,
8283
) -> anyhow::Result<(u16, tokio::task::JoinHandle<anyhow::Result<()>>)> {
8384
use std::net::SocketAddr;
8485

@@ -91,7 +92,12 @@ pub async fn serve_manual_tls(
9192

9293
let services = Services {
9394
directory,
94-
relay: crate::ohttp_relay::Service::new_with_roots(root_store, sentinel_tag).await,
95+
relay: crate::ohttp_relay::Service::new_with_roots(
96+
sentinel_tag,
97+
root_store,
98+
default_gateway,
99+
)
100+
.await,
95101
metrics: MetricsService::new(None),
96102
#[cfg(feature = "access-control")]
97103
geoip,
@@ -439,7 +445,8 @@ mod tests {
439445
root_store.add(CertificateDer::from(cert_der.clone())).unwrap();
440446
let tls_config = RustlsConfig::from_der(vec![cert_der], key_der).await.unwrap();
441447

442-
let (port, handle) = serve_manual_tls(config, Some(tls_config), root_store).await.unwrap();
448+
let (port, handle) =
449+
serve_manual_tls(config, Some(tls_config), root_store, None).await.unwrap();
443450
(port, handle, tempdir)
444451
}
445452

payjoin-mailroom/src/ohttp_relay/mod.rs

Lines changed: 6 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,13 @@ use hyper::header::{
1414
HeaderValue, ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_METHODS,
1515
ACCESS_CONTROL_ALLOW_ORIGIN, CONTENT_LENGTH, CONTENT_TYPE,
1616
};
17-
use hyper::server::conn::http1;
1817
use hyper::{Method, Request, Response};
1918
use hyper_rustls::builderstates::WantsSchemes;
2019
use hyper_rustls::{HttpsConnector, HttpsConnectorBuilder};
2120
use hyper_util::client::legacy::connect::HttpConnector;
2221
use hyper_util::client::legacy::Client;
23-
use hyper_util::rt::{TokioExecutor, TokioIo};
24-
use hyper_util::service::TowerToHyperService;
25-
use tokio::io::{AsyncRead, AsyncWrite};
26-
#[cfg(unix)]
27-
use tokio::net::UnixListener;
28-
use tokio_util::net::Listener;
29-
use tracing::{error, instrument};
22+
use hyper_util::rt::TokioExecutor;
23+
use tracing::instrument;
3024

3125
pub mod error;
3226
#[cfg(not(feature = "_test-util"))]
@@ -45,47 +39,6 @@ pub mod bootstrap;
4539
pub const EXPECTED_MEDIA_TYPE: HeaderValue = HeaderValue::from_static("message/ohttp-req");
4640
pub const DEFAULT_GATEWAY: &str = "https://payjo.in";
4741

48-
#[instrument]
49-
#[cfg(unix)]
50-
pub async fn listen_socket(
51-
socket_path: &str,
52-
gateway_origin: GatewayUri,
53-
) -> Result<tokio::task::JoinHandle<Result<(), BoxError>>, BoxError> {
54-
let listener = UnixListener::bind(socket_path)?;
55-
tracing::info!("OHTTP relay listening on socket: {}", socket_path);
56-
let sentinel_tag = SentinelTag::new([0u8; 32]);
57-
ohttp_relay(listener, RelayConfig::new_with_default_client(gateway_origin, sentinel_tag)).await
58-
}
59-
60-
#[instrument]
61-
#[cfg(not(unix))]
62-
pub async fn listen_socket(
63-
socket_path: &str,
64-
gateway_origin: GatewayUri,
65-
) -> Result<tokio::task::JoinHandle<Result<(), BoxError>>, BoxError> {
66-
// Keep API parity across targets while making the limitation explicit at runtime.
67-
let _ = (socket_path, gateway_origin);
68-
Err(std::io::Error::new(
69-
std::io::ErrorKind::Unsupported,
70-
"UNIX_SOCKET is only supported on unix targets; use PORT instead",
71-
)
72-
.into())
73-
}
74-
75-
#[cfg(feature = "_test-util")]
76-
pub async fn listen_tcp_on_free_port(
77-
default_gateway: GatewayUri,
78-
root_store: rustls::RootCertStore,
79-
) -> Result<(u16, tokio::task::JoinHandle<Result<(), BoxError>>), BoxError> {
80-
let listener = tokio::net::TcpListener::bind("[::]:0").await?;
81-
let port = listener.local_addr()?.port();
82-
println!("OHTTP relay binding to port {}", listener.local_addr()?);
83-
let sentinel_tag = SentinelTag::new([0u8; 32]);
84-
let config = RelayConfig::new(default_gateway, root_store, sentinel_tag);
85-
let handle = ohttp_relay(listener, config).await?;
86-
Ok((port, handle))
87-
}
88-
8942
#[derive(Debug)]
9043
struct RelayConfig {
9144
default_gateway: GatewayUri,
@@ -116,8 +69,6 @@ pub struct Service {
11669
}
11770

11871
impl Service {
119-
fn from_config(config: Arc<RelayConfig>) -> Self { Self { config } }
120-
12172
pub async fn new(sentinel_tag: SentinelTag) -> Self {
12273
// The default gateway is hardcoded because it is obsolete and required only for backwards
12374
// compatibility.
@@ -131,10 +82,12 @@ impl Service {
13182

13283
#[cfg(feature = "_test-util")]
13384
pub async fn new_with_roots(
134-
root_store: rustls::RootCertStore,
13585
sentinel_tag: SentinelTag,
86+
root_store: rustls::RootCertStore,
87+
default_gateway: Option<GatewayUri>,
13688
) -> Self {
137-
let gateway_origin = GatewayUri::from_str(DEFAULT_GATEWAY).expect("valid gateway uri");
89+
let gateway_origin = default_gateway
90+
.unwrap_or_else(|| GatewayUri::from_str(DEFAULT_GATEWAY).expect("valid gateway uri"));
13891
let config = RelayConfig::new(gateway_origin, root_store, sentinel_tag);
13992
config.prober.assert_opt_in(&config.default_gateway).await;
14093
Self { config: Arc::new(config) }
@@ -197,38 +150,6 @@ impl From<rustls::RootCertStore> for HttpClient {
197150
}
198151
}
199152

200-
#[instrument(skip(listener))]
201-
async fn ohttp_relay<L>(
202-
mut listener: L,
203-
config: RelayConfig,
204-
) -> Result<tokio::task::JoinHandle<Result<(), BoxError>>, BoxError>
205-
where
206-
L: Listener + Unpin + Send + 'static,
207-
L::Io: AsyncRead + AsyncWrite + Unpin + Send + 'static,
208-
{
209-
config.prober.assert_opt_in(&config.default_gateway).await;
210-
211-
let config = Arc::new(config);
212-
213-
let handle = tokio::spawn(async move {
214-
while let Ok((stream, _)) = listener.accept().await {
215-
let service = Service::from_config(config.clone());
216-
let io = TokioIo::new(stream);
217-
tokio::spawn(async move {
218-
let hyper_service = TowerToHyperService::new(service);
219-
if let Err(err) =
220-
http1::Builder::new().serve_connection(io, hyper_service).with_upgrades().await
221-
{
222-
error!("Error serving connection: {:?}", err);
223-
}
224-
});
225-
}
226-
Ok(())
227-
});
228-
229-
Ok(handle)
230-
}
231-
232153
#[instrument]
233154
async fn serve_ohttp_relay<B>(
234155
req: Request<B>,

payjoin-mailroom/tests/integration.rs

Lines changed: 3 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ mod integration {
2222
ALLOWED_PURPOSES_CONTENT_TYPE, MAGIC_BIP77_PURPOSE,
2323
};
2424
use payjoin_mailroom::ohttp_relay::*;
25+
use payjoin_test_utils::init_ohttp_relay;
2526
use rcgen::Certificate;
2627
use rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
2728
use tempfile::NamedTempFile;
@@ -54,7 +55,7 @@ mod integration {
5455
let mut root_store = rustls::RootCertStore::empty();
5556
root_store.add(nginx_cert_der.clone()).unwrap();
5657

57-
let (relay_port, relay_handle) = listen_tcp_on_free_port(gateway.clone(), root_store)
58+
let (relay_port, relay_handle) = init_ohttp_relay(root_store, Some(gateway.clone()))
5859
.await
5960
.expect("Failed to listen on free port");
6061
let relay_task = tokio::spawn(async move {
@@ -91,60 +92,6 @@ mod integration {
9192
}
9293
}
9394

94-
// UNIX domain socket transport is only available on unix targets.
95-
#[tokio::test]
96-
#[cfg(unix)]
97-
async fn test_request_response_socket() -> Result<(), Box<dyn std::error::Error>> {
98-
init_crypto_provider();
99-
let temp_dir = std::env::temp_dir();
100-
let socket_path = temp_dir.as_path().join("test.socket");
101-
102-
if socket_path.exists() {
103-
std::fs::remove_file(&socket_path).expect("Failed to remove existing socket file");
104-
}
105-
106-
let gateway_port = find_free_port();
107-
let gateway = GatewayUri::from_str(&format!("http://0.0.0.0:{}", gateway_port)).unwrap();
108-
let nginx_cert = gen_localhost_cert();
109-
let nginx_cert_der = cert_to_cert_der(&nginx_cert);
110-
let socket_path_str = socket_path.to_str().unwrap();
111-
let relay_handle = listen_socket(socket_path_str, gateway.clone())
112-
.await
113-
.expect("Failed to listen on socket");
114-
let relay_task = tokio::spawn(async move {
115-
if let Err(e) = relay_handle.await {
116-
eprintln!("Relay failed: {}", e);
117-
}
118-
});
119-
let n_http_port = find_free_port();
120-
let n_https_port = find_free_port();
121-
let _nginx = match start_nginx(
122-
n_http_port,
123-
n_https_port,
124-
format!("unix:{}", socket_path_str),
125-
nginx_cert,
126-
)
127-
.await
128-
{
129-
Ok(nginx) => nginx,
130-
Err(NginxInitError::NginxNotAvailable) => {
131-
eprintln!("Skipping test: NGINX_EXE environment variable not set");
132-
return Ok(());
133-
}
134-
Err(e) => return Err(Box::new(e) as Box<dyn std::error::Error>),
135-
};
136-
tokio::select! {
137-
_ = example_gateway_http(gateway_port) => {
138-
panic!("Gateway is long running");
139-
}
140-
_ = relay_task => {
141-
panic!("Relay is long running");
142-
}
143-
_ = ohttp_req(n_https_port, nginx_cert_der, gateway) => {}
144-
}
145-
Ok(())
146-
}
147-
14895
async fn example_gateway_http(port: u16) -> Result<(), Box<dyn std::error::Error>> {
14996
example_gateway(port, |stream| {
15097
tokio::spawn(async move {
@@ -380,7 +327,7 @@ mod integration {
380327
let mut root_store = rustls::RootCertStore::empty();
381328
root_store.add(gateway_cert_der.clone()).unwrap();
382329
root_store.add(nginx_cert_der).unwrap();
383-
let (relay_port, relay_handle) = listen_tcp_on_free_port(gateway.clone(), root_store)
330+
let (relay_port, relay_handle) = init_ohttp_relay(root_store, Some(gateway.clone()))
384331
.await
385332
.expect("Failed to listen on free port");
386333
let relay_task = tokio::spawn(async move {

payjoin-test-utils/src/lib.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl TestServices {
6161
root_store.add(CertificateDer::from(cert.cert.der().to_vec())).unwrap();
6262

6363
let directory = init_directory(cert_key, root_store.clone()).await?;
64-
let ohttp_relay = init_ohttp_relay(root_store).await?;
64+
let ohttp_relay = init_ohttp_relay(root_store, None).await?;
6565

6666
let http_agent: Arc<Client> = Arc::new(http_agent(cert_der)?);
6767

@@ -126,9 +126,10 @@ pub async fn init_directory(
126126

127127
let tls_config = RustlsConfig::from_der(vec![local_cert_key.0], local_cert_key.1).await?;
128128

129-
let (port, handle) = payjoin_mailroom::serve_manual_tls(config, Some(tls_config), root_store)
130-
.await
131-
.map_err(|e| e.to_string())?;
129+
let (port, handle) =
130+
payjoin_mailroom::serve_manual_tls(config, Some(tls_config), root_store, None)
131+
.await
132+
.map_err(|e| e.to_string())?;
132133

133134
let handle = tokio::spawn(async move {
134135
let _tempdir = tempdir; // keep the tempdir until the directory shuts down
@@ -138,8 +139,9 @@ pub async fn init_directory(
138139
Ok((port, handle))
139140
}
140141

141-
async fn init_ohttp_relay(
142+
pub async fn init_ohttp_relay(
142143
root_store: RootCertStore,
144+
default_gateway: Option<payjoin_mailroom::ohttp_relay::GatewayUri>,
143145
) -> std::result::Result<
144146
(u16, tokio::task::JoinHandle<std::result::Result<(), BoxSendSyncError>>),
145147
BoxSendSyncError,
@@ -152,9 +154,10 @@ async fn init_ohttp_relay(
152154
None,
153155
);
154156

155-
let (port, handle) = payjoin_mailroom::serve_manual_tls(config, None, root_store)
156-
.await
157-
.map_err(|e| e.to_string())?;
157+
let (port, handle) =
158+
payjoin_mailroom::serve_manual_tls(config, None, root_store, default_gateway)
159+
.await
160+
.map_err(|e| e.to_string())?;
158161

159162
let handle = tokio::spawn(async move {
160163
let _tempdir = tempdir; // keep the tempdir until the relay shuts down

0 commit comments

Comments
 (0)