Skip to content

Commit

Permalink
Refactor tunnel error messages for more detailed information
Browse files Browse the repository at this point in the history
Signed-off-by: ifuryst <[email protected]>
  • Loading branch information
iFurySt committed Aug 4, 2024
1 parent b63cc56 commit 0506cc8
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 7 deletions.
78 changes: 71 additions & 7 deletions src/connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -773,10 +773,23 @@ where
return Err("proxy headers too long for tunnel".into());
}
// else read more
} else if recvd.starts_with(b"HTTP/1.1 407") {
return Err("proxy authentication required".into());
} else {
return Err("unsuccessful tunnel".into());
} else {
return if let Some(line_end) = recvd.windows(2).position(|w| w == b"\r\n") {
let line = &buf[..line_end];
let line = std::str::from_utf8(line)?;
let mut splits = line.splitn(3, ' ');
splits.next().unwrap_or("");
splits.next().unwrap_or("");
let status_text = splits.next().unwrap_or("");

return if !status_text.is_empty() {
Err(status_text.into())
} else {
Err("unsuccessful tunnel".into())
}
} else {
Err("unsuccessful tunnel".into())
}
}
}
}
Expand Down Expand Up @@ -1351,7 +1364,8 @@ mod tests {
tunnel(tcp, host, port, ua(), None).await
};

rt.block_on(f).unwrap_err();
let error = rt.block_on(f).unwrap_err();
assert_eq!(error.to_string(), "unexpected eof while tunneling");
}

#[test]
Expand All @@ -1369,7 +1383,8 @@ mod tests {
tunnel(tcp, host, port, ua(), None).await
};

rt.block_on(f).unwrap_err();
let error = rt.block_on(f).unwrap_err();
assert_eq!(error.to_string(), "unsuccessful tunnel");
}

#[test]
Expand All @@ -1394,7 +1409,56 @@ mod tests {
};

let error = rt.block_on(f).unwrap_err();
assert_eq!(error.to_string(), "proxy authentication required");
assert_eq!(error.to_string(), "Proxy Authentication Required");
}

#[test]
fn test_tunnel_service_unavailable() {
let addr = mock_tunnel!(
b"\
HTTP/1.1 503 Service Unavailable\r\n\
Retry-After: 3600\r\n\
\r\n\
"
);

let rt = runtime::Builder::new_current_thread()
.enable_all()
.build()
.expect("new rt");
let f = async move {
let tcp = TokioIo::new(TcpStream::connect(&addr).await?);
let host = addr.ip().to_string();
let port = addr.port();
tunnel(tcp, host, port, ua(), None).await
};

let error = rt.block_on(f).unwrap_err();
assert_eq!(error.to_string(), "Service Unavailable");
}

#[test]
fn test_tunnel_bad_gateway() {
let addr = mock_tunnel!(
b"\
HTTP/1.1 502 Bad Gateway\r\n\
\r\n\
"
);

let rt = runtime::Builder::new_current_thread()
.enable_all()
.build()
.expect("new rt");
let f = async move {
let tcp = TokioIo::new(TcpStream::connect(&addr).await?);
let host = addr.ip().to_string();
let port = addr.port();
tunnel(tcp, host, port, ua(), None).await
};

let error = rt.block_on(f).unwrap_err();
assert_eq!(error.to_string(), "Bad Gateway");
}

#[test]
Expand Down
32 changes: 32 additions & 0 deletions tests/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,35 @@ async fn http_over_http() {
assert_eq!(res.url().as_str(), url);
assert_eq!(res.status(), reqwest::StatusCode::OK);
}


#[tokio::test]
async fn http_proxy_authentication_required() {
let url = "http://hyper.rs/prox";
let server = server::http(move |req| {
assert_eq!(req.method(), "GET");
assert_eq!(req.uri(), url);
assert_eq!(req.headers()["host"], "hyper.rs");

async {
http::Response::builder()
.status(407)
.body(reqwest::Body::from(Vec::new()))
.unwrap()
}
});

let proxy = format!("http://{}", server.addr());

let res = reqwest::Client::builder()
.proxy(reqwest::Proxy::http(&proxy).unwrap())
.build()
.unwrap()
.get(url)
.send()
.await;

assert!(res.is_err());
let err = res.unwrap_err();
assert_eq!(err.to_string(), "proxy authentication required");
}

0 comments on commit 0506cc8

Please sign in to comment.