1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-24 15:19:26 -05:00

fix(node/http): use fake socket and proper url handling (#19340)

Fixes https://github.com/denoland/deno/issues/19349

---------

Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
This commit is contained in:
Leo Kettmeir 2023-06-06 16:37:10 +02:00 committed by GitHub
parent c76f9a0227
commit 5aca8b9e5d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 41 deletions

View file

@ -195,11 +195,14 @@ Deno.test("[node/http] request default protocol", async () => {
// @ts-ignore IncomingMessageForClient // @ts-ignore IncomingMessageForClient
// deno-lint-ignore no-explicit-any // deno-lint-ignore no-explicit-any
let clientRes: any; let clientRes: any;
// deno-lint-ignore no-explicit-any
let clientReq: any;
server.listen(() => { server.listen(() => {
const req = http.request( clientReq = http.request(
// deno-lint-ignore no-explicit-any // deno-lint-ignore no-explicit-any
{ host: "localhost", port: (server.address() as any).port }, { host: "localhost", port: (server.address() as any).port },
(res) => { (res) => {
assert(res.socket instanceof EventEmitter);
assertEquals(res.complete, false); assertEquals(res.complete, false);
res.on("data", () => {}); res.on("data", () => {});
res.on("end", () => { res.on("end", () => {
@ -210,13 +213,14 @@ Deno.test("[node/http] request default protocol", async () => {
promise2.resolve(); promise2.resolve();
}, },
); );
req.end(); clientReq.end();
}); });
server.on("close", () => { server.on("close", () => {
promise.resolve(); promise.resolve();
}); });
await promise; await promise;
await promise2; await promise2;
assert(clientReq.socket instanceof EventEmitter);
assertEquals(clientRes!.complete, true); assertEquals(clientRes!.complete, true);
}); });
@ -596,3 +600,24 @@ Deno.test("[node/http] ClientRequest PUT", async () => {
await def; await def;
assertEquals(body, "hello world"); assertEquals(body, "hello world");
}); });
Deno.test("[node/http] ClientRequest search params", async () => {
let body = "";
const def = deferred();
const req = http.request({
host: "localhost:4545",
path: "search_params?foo=bar",
}, (resp) => {
resp.on("data", (chunk) => {
body += chunk;
});
resp.on("end", () => {
def.resolve();
});
});
req.once("error", (e) => def.reject(e));
req.end();
await def;
assertEquals(body, "foo=bar");
});

View file

@ -267,6 +267,9 @@ const kError = Symbol("kError");
const kUniqueHeaders = Symbol("kUniqueHeaders"); const kUniqueHeaders = Symbol("kUniqueHeaders");
class FakeSocket extends EventEmitter {
}
/** ClientRequest represents the http(s) request from the client */ /** ClientRequest represents the http(s) request from the client */
class ClientRequest extends OutgoingMessage { class ClientRequest extends OutgoingMessage {
defaultProtocol = "http:"; defaultProtocol = "http:";
@ -541,6 +544,7 @@ class ClientRequest extends OutgoingMessage {
this.onSocket(createConnection(optsWithoutSignal)); this.onSocket(createConnection(optsWithoutSignal));
} }
}*/ }*/
this.onSocket(new FakeSocket());
const url = this._createUrlStrFromOptions(); const url = this._createUrlStrFromOptions();
@ -570,41 +574,12 @@ class ClientRequest extends OutgoingMessage {
return undefined; return undefined;
} }
onSocket(socket, err) { // TODO(bartlomieju): handle error
if (this.destroyed || err) { onSocket(socket, _err) {
this.destroyed = true; nextTick(() => {
this.socket = socket;
// deno-lint-ignore no-inner-declarations this.emit("socket", socket);
function _destroy(req, err) { });
if (!req.aborted && !err) {
err = connResetException("socket hang up");
}
if (err) {
req.emit("error", err);
}
req._closed = true;
req.emit("close");
}
if (socket) {
if (!err && this.agent && !socket.destroyed) {
socket.emit("free");
} else {
finished(socket.destroy(err || this[kError]), (er) => {
if (er?.code === "ERR_STREAM_PREMATURE_CLOSE") {
er = null;
}
_destroy(this, er || err);
});
return;
}
}
_destroy(this, err || this[kError]);
} else {
//tickOnSocket(this, socket);
//this._flush();
}
} }
// deno-lint-ignore no-explicit-any // deno-lint-ignore no-explicit-any
@ -737,16 +712,19 @@ class ClientRequest extends OutgoingMessage {
const auth = this.auth; const auth = this.auth;
const host = this.host ?? this.hostname ?? "localhost"; const host = this.host ?? this.hostname ?? "localhost";
const hash = this.hash ? `#${this.hash}` : ""; const hash = this.hash ? `#${this.hash}` : "";
const search = this.search ? this.search : "";
const defaultPort = this.agent?.defaultPort; const defaultPort = this.agent?.defaultPort;
const port = this.port ?? defaultPort ?? 80; const port = this.port ?? defaultPort ?? 80;
let path = this.path ?? "/"; let path = this.path ?? "/";
if (!path.startsWith("/")) { if (!path.startsWith("/")) {
path = "/" + path; path = "/" + path;
} }
return `${protocol}//${auth ? `${auth}@` : ""}${host}${ const url = new URL(
port === 80 ? "" : `:${port}` `${protocol}//${auth ? `${auth}@` : ""}${host}${
}${path}${search}${hash}`; port === 80 ? "" : `:${port}`
}${path}`,
);
url.hash = hash;
return url.href;
} }
setTimeout(msecs: number, callback?: () => void) { setTimeout(msecs: number, callback?: () => void) {

View file

@ -1085,6 +1085,11 @@ async fn main_server(
)); ));
Ok(res) Ok(res)
} }
(_, "/search_params") => {
let query = req.uri().query().map(|s| s.to_string());
let res = Response::new(Body::from(query.unwrap_or_default()));
Ok(res)
}
_ => { _ => {
let mut file_path = testdata_path(); let mut file_path = testdata_path();
file_path.push(&req.uri().path()[1..]); file_path.push(&req.uri().path()[1..]);