1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#![warn(
missing_debug_implementations,
missing_docs,
rust_2018_idioms,
unreachable_pub
)]
pub mod wallet;
use bytes::Buf;
use http::header::{HeaderMap, HeaderValue, ACCEPT, CONTENT_TYPE};
use prost::{DecodeError, Message};
use thiserror::Error;
#[allow(missing_docs)]
pub mod bip70 {
include!(concat!(env!("OUT_DIR"), "/bip70.rs"));
}
use bip70::Payment;
#[derive(Debug, Error)]
pub enum PreprocessingError {
#[error("missing accept header")]
MissingAcceptHeader,
#[error("invalid content-type")]
MissingContentTypeHeader,
#[error("payment decoding failure: {0}")]
PaymentDecode(DecodeError),
}
pub async fn preprocess_payment<B: Buf>(
headers: HeaderMap,
body: B,
) -> Result<Payment, PreprocessingError> {
let bch_content_type_value = HeaderValue::from_static("application/bitcoincash-payment");
let bch_accept_value = HeaderValue::from_static("application/bitcoincash-paymentack");
if !headers
.get_all(CONTENT_TYPE)
.iter()
.any(|header_val| header_val == bch_content_type_value)
{
return Err(PreprocessingError::MissingContentTypeHeader);
}
if !headers
.get_all(ACCEPT)
.iter()
.any(|header_val| header_val == bch_accept_value)
{
return Err(PreprocessingError::MissingAcceptHeader);
}
let payment = bip70::Payment::decode(body).map_err(PreprocessingError::PaymentDecode)?;
Ok(payment)
}