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:
parent
057f257052
commit
1cecc0a8b0
3 changed files with 49 additions and 5 deletions
|
@ -113,6 +113,9 @@ pub enum ConnError {
|
||||||
#[error("Invalid URL {0}")]
|
#[error("Invalid URL {0}")]
|
||||||
InvalidUrl(Url),
|
InvalidUrl(Url),
|
||||||
#[class(type)]
|
#[class(type)]
|
||||||
|
#[error("Invalid Path {0}")]
|
||||||
|
InvalidPath(String),
|
||||||
|
#[class(type)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
InvalidHeaderName(#[from] http::header::InvalidHeaderName),
|
InvalidHeaderName(#[from] http::header::InvalidHeaderName),
|
||||||
#[class(type)]
|
#[class(type)]
|
||||||
|
@ -150,6 +153,7 @@ pub async fn op_node_http_request_with_conn<P>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[serde] method: ByteString,
|
#[serde] method: ByteString,
|
||||||
#[string] url: String,
|
#[string] url: String,
|
||||||
|
#[string] request_path: Option<String>,
|
||||||
#[serde] headers: Vec<(ByteString, ByteString)>,
|
#[serde] headers: Vec<(ByteString, ByteString)>,
|
||||||
#[smi] body: Option<ResourceId>,
|
#[smi] body: Option<ResourceId>,
|
||||||
#[smi] conn_rid: ResourceId,
|
#[smi] conn_rid: ResourceId,
|
||||||
|
@ -247,11 +251,17 @@ where
|
||||||
*request.method_mut() = method.clone();
|
*request.method_mut() = method.clone();
|
||||||
let path = url_parsed.path();
|
let path = url_parsed.path();
|
||||||
let query = url_parsed.query();
|
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
|
*request.uri_mut() = query
|
||||||
.map(|q| format!("{}?{}", path, q))
|
.map(|q| format!("{}?{}", path, q))
|
||||||
.unwrap_or_else(|| path.to_string())
|
.unwrap_or_else(|| path.to_string())
|
||||||
.parse()
|
.parse()
|
||||||
.map_err(|_| ConnError::InvalidUrl(url_parsed.clone()))?;
|
.map_err(|_| ConnError::InvalidUrl(url_parsed.clone()))?;
|
||||||
|
}
|
||||||
*request.headers_mut() = header_map;
|
*request.headers_mut() = header_map;
|
||||||
|
|
||||||
if let Some((username, password)) = maybe_authority {
|
if let Some((username, password)) = maybe_authority {
|
||||||
|
|
|
@ -479,6 +479,7 @@ class ClientRequest extends OutgoingMessage {
|
||||||
this._req = await op_node_http_request_with_conn(
|
this._req = await op_node_http_request_with_conn(
|
||||||
this.method,
|
this.method,
|
||||||
url,
|
url,
|
||||||
|
this._createRequestPath(),
|
||||||
headers,
|
headers,
|
||||||
this._bodyWriteRid,
|
this._bodyWriteRid,
|
||||||
baseConnRid,
|
baseConnRid,
|
||||||
|
@ -817,6 +818,15 @@ class ClientRequest extends OutgoingMessage {
|
||||||
return url.href;
|
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) {
|
setTimeout(msecs: number, callback?: () => void) {
|
||||||
if (msecs === 0) {
|
if (msecs === 0) {
|
||||||
if (this._timeout) {
|
if (this._timeout) {
|
||||||
|
|
|
@ -1892,3 +1892,27 @@ Deno.test("[node/http] an error with DNS propagates to request object", async ()
|
||||||
});
|
});
|
||||||
await promise;
|
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;
|
||||||
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue