Skip to content

Commit b3069e1

Browse files
committed
Handle OHTTP key rejection responses
Clients with bad OHTTP key configurations should not retry requests to the directory with the same key configuration, so they must be able to switch on that error variant.
1 parent e1bb885 commit b3069e1

3 files changed

Lines changed: 14 additions & 0 deletions

File tree

payjoin/src/ohttp.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::{error, fmt};
33

44
use bitcoin::bech32::{self, EncodeError};
55
use bitcoin::key::constants::UNCOMPRESSED_PUBLIC_KEY_SIZE;
6+
use http::HeaderValue;
67

78
use crate::directory::ENCAPSULATED_MESSAGE_BYTES;
89

@@ -53,6 +54,7 @@ pub fn ohttp_encapsulate(
5354
pub enum DirectoryResponseError {
5455
InvalidSize(usize),
5556
OhttpDecapsulation(OhttpEncapsulationError),
57+
OhttpKeyRejected,
5658
UnexpectedStatusCode(http::StatusCode),
5759
}
5860

@@ -64,6 +66,11 @@ pub fn process_get_res(
6466
let body = match response.status() {
6567
http::StatusCode::OK => response.body().to_vec(),
6668
http::StatusCode::ACCEPTED => return Ok(None),
69+
http::StatusCode::BAD_REQUEST => match response.headers().get("content-type") {
70+
Some(t) if t == HeaderValue::from_static("application/problem+json") =>
71+
return Err(DirectoryResponseError::OhttpKeyRejected),
72+
_ => return Err(DirectoryResponseError::UnexpectedStatusCode(response.status())),
73+
},
6774
_ => return Err(DirectoryResponseError::UnexpectedStatusCode(response.status())),
6875
};
6976
Ok(Some(body))
@@ -76,6 +83,11 @@ pub fn process_post_res(
7683
let response = process_ohttp_res(res, ohttp_context)?;
7784
match response.status() {
7885
http::StatusCode::OK => return Ok(()),
86+
http::StatusCode::BAD_REQUEST => match response.headers().get("content-type") {
87+
Some(t) if t == HeaderValue::from_static("application/problem+json") =>
88+
return Err(DirectoryResponseError::OhttpKeyRejected),
89+
_ => return Err(DirectoryResponseError::UnexpectedStatusCode(response.status())),
90+
},
7991
_ => return Err(DirectoryResponseError::UnexpectedStatusCode(response.status())),
8092
};
8193
}

payjoin/src/receive/v2/error.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ impl From<DirectoryResponseError> for SessionError {
3030
InternalSessionError::OhttpEncapsulation(e),
3131
DirectoryResponseError::UnexpectedStatusCode(e) =>
3232
InternalSessionError::UnexpectedStatusCode(e),
33+
DirectoryResponseError::OhttpKeyRejected => todo!(),
3334
}
3435
.into()
3536
}

payjoin/src/send/v2/error.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ impl From<DirectoryResponseError> for EncapsulationError {
131131
DirectoryResponseError::OhttpDecapsulation(e) => InternalEncapsulationError::Ohttp(e),
132132
DirectoryResponseError::UnexpectedStatusCode(e) =>
133133
InternalEncapsulationError::UnexpectedStatusCode(e),
134+
DirectoryResponseError::OhttpKeyRejected => todo!(),
134135
}
135136
.into()
136137
}

0 commit comments

Comments
 (0)