mirror of
https://github.com/YGGverse/aquatic.git
synced 2026-03-31 09:45:31 +00:00
aquatic_http: move request parsing into protocol crate
This commit is contained in:
parent
2521c89109
commit
95e25710dc
6 changed files with 43 additions and 30 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -79,7 +79,6 @@ dependencies = [
|
|||
"either",
|
||||
"flume",
|
||||
"hashbrown",
|
||||
"httparse",
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"log",
|
||||
|
|
@ -123,6 +122,7 @@ dependencies = [
|
|||
"criterion",
|
||||
"hashbrown",
|
||||
"hex",
|
||||
"httparse",
|
||||
"itoa",
|
||||
"log",
|
||||
"memchr",
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ aquatic_http_protocol = { path = "../aquatic_http_protocol" }
|
|||
either = "1"
|
||||
flume = "0.7"
|
||||
hashbrown = { version = "0.7", features = ["serde"] }
|
||||
httparse = "1"
|
||||
indexmap = "1"
|
||||
itoa = "0.4"
|
||||
log = "0.4"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use mio::net::TcpStream;
|
|||
use native_tls::{TlsAcceptor, MidHandshakeTlsStream};
|
||||
|
||||
use aquatic_common_tcp::network::stream::Stream;
|
||||
use aquatic_http_protocol::request::Request;
|
||||
use aquatic_http_protocol::request::{Request, RequestParseError};
|
||||
|
||||
use crate::common::*;
|
||||
|
||||
|
|
@ -17,10 +17,9 @@ use crate::common::*;
|
|||
#[derive(Debug)]
|
||||
pub enum RequestReadError {
|
||||
NeedMoreData,
|
||||
Invalid(anyhow::Error),
|
||||
StreamEnded,
|
||||
Parse(anyhow::Error),
|
||||
Io(::std::io::Error),
|
||||
Parse(::httparse::Error),
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -71,31 +70,20 @@ impl EstablishedConnection {
|
|||
}
|
||||
}
|
||||
|
||||
let mut headers = [httparse::EMPTY_HEADER; 16];
|
||||
let mut http_request = httparse::Request::new(&mut headers);
|
||||
match Request::from_bytes(&self.buf[..self.bytes_read]){
|
||||
Ok(request) => {
|
||||
self.clear_buffer();
|
||||
|
||||
match http_request.parse(&self.buf[..self.bytes_read]){
|
||||
Ok(httparse::Status::Complete(_)) => {
|
||||
if let Some(path) = http_request.path {
|
||||
let res_request = Request::from_http_get_path(path);
|
||||
|
||||
self.clear_buffer();
|
||||
|
||||
res_request.map_err(RequestReadError::Invalid)
|
||||
} else {
|
||||
self.clear_buffer();
|
||||
|
||||
Err(RequestReadError::Invalid(anyhow::anyhow!("no http path")))
|
||||
}
|
||||
Ok(request)
|
||||
},
|
||||
Ok(httparse::Status::Partial) => {
|
||||
Err(RequestParseError::NeedMoreData) => {
|
||||
Err(RequestReadError::NeedMoreData)
|
||||
},
|
||||
Err(err) => {
|
||||
Err(RequestParseError::Invalid(err)) => {
|
||||
self.clear_buffer();
|
||||
|
||||
Err(RequestReadError::Parse(err))
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -227,8 +227,8 @@ pub fn handle_connection_read_event(
|
|||
// Stop reading data (defer to later events)
|
||||
break;
|
||||
},
|
||||
Err(RequestReadError::Invalid(err)) => {
|
||||
info!("error reading request (invalid): {}", err);
|
||||
Err(RequestReadError::Parse(err)) => {
|
||||
info!("error reading request (invalid): {:#?}", err);
|
||||
|
||||
let meta = ConnectionMeta {
|
||||
worker_index: socket_worker_index,
|
||||
|
|
@ -253,11 +253,6 @@ pub fn handle_connection_read_event(
|
|||
|
||||
break
|
||||
},
|
||||
Err(RequestReadError::Parse(err)) => {
|
||||
::log::info!("request httparse error: {}", err);
|
||||
|
||||
break
|
||||
},
|
||||
Err(RequestReadError::Io(err)) => {
|
||||
::log::info!("error reading request (io): {}", err);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ anyhow = "1"
|
|||
bendy = { version = "0.3", features = ["std", "serde"] }
|
||||
hashbrown = { version = "0.7", features = ["serde"] }
|
||||
hex = { version = "0.4", default-features = false }
|
||||
httparse = "1"
|
||||
itoa = "0.4"
|
||||
log = "0.4"
|
||||
memchr = "2"
|
||||
|
|
|
|||
|
|
@ -109,6 +109,12 @@ impl ScrapeRequest {
|
|||
}
|
||||
|
||||
|
||||
pub enum RequestParseError {
|
||||
NeedMoreData,
|
||||
Invalid(anyhow::Error),
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Request {
|
||||
Announce(AnnounceRequest),
|
||||
|
|
@ -117,6 +123,30 @@ pub enum Request {
|
|||
|
||||
|
||||
impl Request {
|
||||
/// Parse Request from HTTP request bytes
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, RequestParseError> {
|
||||
let mut headers = [httparse::EMPTY_HEADER; 16];
|
||||
let mut http_request = httparse::Request::new(&mut headers);
|
||||
|
||||
match http_request.parse(bytes){
|
||||
Ok(httparse::Status::Complete(_)) => {
|
||||
if let Some(path) = http_request.path {
|
||||
let res_request = Self::from_http_get_path(path);
|
||||
|
||||
res_request.map_err(RequestParseError::Invalid)
|
||||
} else {
|
||||
Err(RequestParseError::Invalid(anyhow::anyhow!("no http path")))
|
||||
}
|
||||
},
|
||||
Ok(httparse::Status::Partial) => {
|
||||
Err(RequestParseError::NeedMoreData)
|
||||
},
|
||||
Err(err) => {
|
||||
Err(RequestParseError::Invalid(anyhow::anyhow!("httparse: {:?}", err)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse Request from http path (GET `/announce?info_hash=...`)
|
||||
///
|
||||
/// Existing serde-url decode crates were insufficient, so the decision was
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue