0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-02-08 07:16:56 -05:00

fix(ext/node): support proxy http request (#27871)

This commit is contained in:
Yoshiya Hinosawa 2025-01-31 21:46:54 +09:00 committed by GitHub
parent 057f257052
commit 1cecc0a8b0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 49 additions and 5 deletions

View file

@ -113,6 +113,9 @@ pub enum ConnError {
#[error("Invalid URL {0}")]
InvalidUrl(Url),
#[class(type)]
#[error("Invalid Path {0}")]
InvalidPath(String),
#[class(type)]
#[error(transparent)]
InvalidHeaderName(#[from] http::header::InvalidHeaderName),
#[class(type)]
@ -150,6 +153,7 @@ pub async fn op_node_http_request_with_conn<P>(
state: Rc<RefCell<OpState>>,
#[serde] method: ByteString,
#[string] url: String,
#[string] request_path: Option<String>,
#[serde] headers: Vec<(ByteString, ByteString)>,
#[smi] body: Option<ResourceId>,
#[smi] conn_rid: ResourceId,
@ -247,11 +251,17 @@ where
*request.method_mut() = method.clone();
let path = url_parsed.path();
let query = url_parsed.query();
if let Some(request_path) = request_path {
*request.uri_mut() = request_path
.parse()
.map_err(|_| ConnError::InvalidPath(request_path.clone()))?;
} else {
*request.uri_mut() = query
.map(|q| format!("{}?{}", path, q))
.unwrap_or_else(|| path.to_string())
.parse()
.map_err(|_| ConnError::InvalidUrl(url_parsed.clone()))?;
}
*request.headers_mut() = header_map;
if let Some((username, password)) = maybe_authority {

View file

@ -479,6 +479,7 @@ class ClientRequest extends OutgoingMessage {
this._req = await op_node_http_request_with_conn(
this.method,
url,
this._createRequestPath(),
headers,
this._bodyWriteRid,
baseConnRid,
@ -817,6 +818,15 @@ class ClientRequest extends OutgoingMessage {
return url.href;
}
_createRequestPath(): string | undefined {
// If the path starts with protocol, pass this to op_node_http_request_with_conn
// This will be used as Request.uri in hyper for supporting http proxy
if (this.path?.startsWith("http://") || this.path?.startsWith("https://")) {
return this.path;
}
return undefined;
}
setTimeout(msecs: number, callback?: () => void) {
if (msecs === 0) {
if (this._timeout) {

View file

@ -1892,3 +1892,27 @@ Deno.test("[node/http] an error with DNS propagates to request object", async ()
});
await promise;
});
Deno.test("[node/http] supports proxy http request", async () => {
const { promise, resolve } = Promise.withResolvers<void>();
const server = Deno.serve({ port: 0, onListen }, (req) => {
console.log("server received", req.url);
assertEquals(req.url, "http://example.com/");
return new Response("ok");
});
function onListen({ port }: { port: number }) {
http.request({
host: "localhost",
port,
path: "http://example.com",
}, async (res) => {
assertEquals(res.statusCode, 200);
assertEquals(await text(res), "ok");
resolve();
server.shutdown();
}).end();
}
await promise;
await server.finished;
});