Skip to content

Commit

Permalink
fix(local-http): HttpClient send HTTP requests URI contains only Path…
Browse files Browse the repository at this point in the history
…&Query

- fix #1730
- hyper will serialize the hyper::Request<T> object with all the
  contents in the uri, which may be rejected by some of the servers.
  • Loading branch information
zonyitoo committed Oct 23, 2024
1 parent f3f2dd0 commit ab5005c
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 3 deletions.
2 changes: 1 addition & 1 deletion crates/shadowsocks-service/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ local-dns-relay = ["local-dns"]
# Currently is only used in Android
local-flow-stat = ["local"]
# Enable HTTP protocol for sslocal
local-http = ["local", "hyper", "http-body-util"]
local-http = ["local", "hyper", "http", "http-body-util"]
local-http-native-tls = ["local-http", "tokio-native-tls", "native-tls"]
local-http-native-tls-vendored = [
"local-http-native-tls",
Expand Down
19 changes: 17 additions & 2 deletions crates/shadowsocks-service/src/local/http/http_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::{
time::{Duration, Instant},
};

use http::Uri;
use hyper::{
body::{self, Body},
client::conn::{http1, http2},
Expand Down Expand Up @@ -43,6 +44,9 @@ pub enum HttpClientError {
/// std::io::Error
#[error("{0}")]
Io(#[from] io::Error),
/// Errors from http
#[error("{0}")]
Http(#[from] http::Error),
}

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -195,8 +199,19 @@ where
&self,
host: Address,
mut c: HttpConnection<B>,
req: Request<B>,
) -> hyper::Result<Response<body::Incoming>> {
mut req: Request<B>,
) -> Result<Response<body::Incoming>, HttpClientError> {
// Remove Scheme, Host part from URI
if req.uri().scheme().is_some() || req.uri().authority().is_some() {
let mut builder = Uri::builder();
if let Some(path_and_query) = req.uri().path_and_query() {
builder = builder.path_and_query(path_and_query.as_str());
} else {
builder = builder.path_and_query("/");
}
*(req.uri_mut()) = builder.build()?;
}

trace!("HTTP making request to host: {}, request: {:?}", host, req);
let response = c.send_request(req).await?;
trace!("HTTP received response from host: {}, response: {:?}", host, response);
Expand Down
4 changes: 4 additions & 0 deletions crates/shadowsocks-service/src/local/http/http_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ impl HttpService {
error!("failed to make request to host: {}, error: {}", host, err);
return make_internal_server_error();
}
Err(HttpClientError::Http(err)) => {
error!("failed to make request to host: {}, error: {}", host, err);
return make_bad_request();
}
};

trace!("received {} <- {} {:?}", self.peer_addr, host, res);
Expand Down

0 comments on commit ab5005c

Please sign in to comment.