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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use std::convert::TryFrom;
use bytes::Buf;
use http::{Request, StatusCode};
use crate::{error::Code, proto::headers::Header, qpack, quic, server::RequestStream, Error};
pub struct ResolveRequest<C: quic::Connection<B>, B: Buf> {
request_stream: RequestStream<C::BidiStream, B>,
// Ok or `REQUEST_HEADER_FIELDS_TO_LARGE` which neeeds to be sent
decoded: Result<qpack::Decoded, u64>,
max_field_section_size: u64,
}
impl<B: Buf, C: quic::Connection<B>> ResolveRequest<C, B> {
pub fn new(
request_stream: RequestStream<C::BidiStream, B>,
decoded: Result<qpack::Decoded, u64>,
max_field_section_size: u64,
) -> Self {
Self {
request_stream,
decoded,
max_field_section_size,
}
}
/// Finishes the resolution of the request
pub async fn resolve(
mut self,
) -> Result<(Request<()>, RequestStream<C::BidiStream, B>), Error> {
let fields = match self.decoded {
Ok(v) => v.fields,
Err(cancel_size) => {
// Send and await the error response
self.request_stream
.send_response(
http::Response::builder()
.status(StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE)
.body(())
.expect("header too big response"),
)
.await?;
return Err(Error::header_too_big(
cancel_size,
self.max_field_section_size,
));
}
};
// Parse the request headers
let (method, uri, protocol, headers) = match Header::try_from(fields) {
Ok(header) => match header.into_request_parts() {
Ok(parts) => parts,
Err(err) => {
//= https://www.rfc-editor.org/rfc/rfc9114#section-4.1.2
//# Malformed requests or responses that are
//# detected MUST be treated as a stream error of type H3_MESSAGE_ERROR.
let error: Error = err.into();
self.request_stream
.stop_stream(error.try_get_code().unwrap_or(Code::H3_MESSAGE_ERROR));
return Err(error);
}
},
Err(err) => {
//= https://www.rfc-editor.org/rfc/rfc9114#section-4.1.2
//# Malformed requests or responses that are
//# detected MUST be treated as a stream error of type H3_MESSAGE_ERROR.
let error: Error = err.into();
self.request_stream
.stop_stream(error.try_get_code().unwrap_or(Code::H3_MESSAGE_ERROR));
return Err(error);
}
};
// request_stream.stop_stream(Code::H3_MESSAGE_ERROR).await;
let mut req = http::Request::new(());
*req.method_mut() = method;
*req.uri_mut() = uri;
*req.headers_mut() = headers;
// NOTE: insert `Protocol` and not `Option<Protocol>`
if let Some(protocol) = protocol {
req.extensions_mut().insert(protocol);
}
*req.version_mut() = http::Version::HTTP_3;
// send the grease frame only once
// self.inner.send_grease_frame = false;
tracing::trace!("replying with: {:?}", req);
Ok((req, self.request_stream))
}
}