mirror of
https://github.com/n0-computer/noq.git
synced 2026-09-24 20:25:00 +00:00
H3: make server receive a Request struct
This commit is contained in:
@@ -187,7 +187,7 @@ fn handle_connection(
|
||||
}
|
||||
|
||||
fn handle_request(request: RequestReady) -> impl Future<Item = (), Error = Error> {
|
||||
println!("received request: {:?}", request.headers());
|
||||
println!("received request: {:?}", request.request());
|
||||
futures::future::ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -83,3 +83,9 @@ impl From<frame::Error> for Error {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<proto::headers::Error> for Error {
|
||||
fn from(err: proto::headers::Error) -> Error {
|
||||
Error::Peer(format!("invalid headers: {:?}", err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ pub enum Error {
|
||||
HeaderListTooLarge,
|
||||
InvalidHeaderName(String),
|
||||
InvalidHeaderValue(String),
|
||||
InvalidRequest(String),
|
||||
Settings { reason: String },
|
||||
EncodeError { reason: EncoderError },
|
||||
DecodeError { reason: DecoderError },
|
||||
@@ -120,6 +121,8 @@ impl From<headers::Error> for Error {
|
||||
match err {
|
||||
headers::Error::InvalidHeaderName(s) => Error::InvalidHeaderName(s),
|
||||
headers::Error::InvalidHeaderValue(s) => Error::InvalidHeaderValue(s),
|
||||
headers::Error::InvalidRequest(e) => Error::InvalidRequest(format!("{:?}", e)),
|
||||
headers::Error::MissingMethod => Error::InvalidRequest("missing method".into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,28 @@ impl Header {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_request_parts(self) -> Result<(Method, Uri, HeaderMap), Error> {
|
||||
let mut uri = Uri::builder();
|
||||
|
||||
if let Some(path) = self.pseudo.path {
|
||||
uri.path_and_query(path.as_bytes());
|
||||
}
|
||||
|
||||
if let Some(scheme) = self.pseudo.scheme {
|
||||
uri.scheme(scheme.as_bytes());
|
||||
}
|
||||
|
||||
if let Some(authority) = self.pseudo.authority {
|
||||
uri.authority(authority.as_bytes());
|
||||
}
|
||||
|
||||
Ok((
|
||||
self.pseudo.method.ok_or(Error::MissingMethod)?,
|
||||
uri.build().map_err(|e| Error::InvalidRequest(e))?,
|
||||
self.fields,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.pseudo.len() + self.fields.len()
|
||||
}
|
||||
@@ -271,9 +293,12 @@ fn to_string(src: Bytes) -> String<Bytes> {
|
||||
unsafe { String::from_utf8_unchecked(src) }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
InvalidHeaderName(std::string::String),
|
||||
InvalidHeaderValue(std::string::String),
|
||||
InvalidRequest(http::Error),
|
||||
MissingMethod,
|
||||
}
|
||||
|
||||
impl Error {
|
||||
|
||||
+37
-8
@@ -3,6 +3,7 @@ use std::net::ToSocketAddrs;
|
||||
|
||||
use futures::task;
|
||||
use futures::{try_ready, Async, Future, Poll, Stream};
|
||||
use http::Request;
|
||||
use quinn::{EndpointBuilder, EndpointDriver, EndpointError, RecvStream, SendStream};
|
||||
use quinn_proto::StreamId;
|
||||
use slog::{self, o, Logger};
|
||||
@@ -186,12 +187,12 @@ impl Future for RecvRequest {
|
||||
Some(x) => x,
|
||||
None => return Err(Error::Internal("Recv request invalid state")),
|
||||
};
|
||||
return Ok(Async::Ready(RequestReady {
|
||||
headers: decoded,
|
||||
return Ok(Async::Ready(RequestReady::build(
|
||||
decoded,
|
||||
frame_stream,
|
||||
send: Some(send),
|
||||
conn: self.conn.clone(),
|
||||
}));
|
||||
send,
|
||||
self.conn.clone(),
|
||||
)?));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,14 +203,42 @@ impl Future for RecvRequest {
|
||||
}
|
||||
|
||||
pub struct RequestReady {
|
||||
headers: Header,
|
||||
request: Request<()>,
|
||||
frame_stream: FrameStream<RecvStream>,
|
||||
send: Option<SendStream>,
|
||||
conn: ConnectionRef,
|
||||
}
|
||||
|
||||
impl RequestReady {
|
||||
pub fn headers<'a>(&'a self) -> &'a Header {
|
||||
&self.headers
|
||||
fn build(
|
||||
headers: Header,
|
||||
frame_stream: FrameStream<RecvStream>,
|
||||
send: SendStream,
|
||||
conn: ConnectionRef,
|
||||
) -> Result<Self, Error> {
|
||||
let (method, uri, headers) = headers.into_request_parts()?;
|
||||
let mut request = Request::builder();
|
||||
request.method(method);
|
||||
request.uri(uri);
|
||||
request.version(http::version::Version::HTTP_2); // TODO change once available
|
||||
match request.headers_mut() {
|
||||
Some(h) => *h = headers,
|
||||
None => return Err(Error::peer("invalid header")),
|
||||
}
|
||||
|
||||
let request = request
|
||||
.body(())
|
||||
.map_err(|e| Error::Peer(format!("invalid request: {:?}", e)))?;
|
||||
|
||||
Ok(Self {
|
||||
request,
|
||||
frame_stream,
|
||||
conn,
|
||||
send: Some(send),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn request<'a>(&'a self) -> &'a Request<()> {
|
||||
&self.request
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user