feat(runtime): implement server.requestIp + node:http socket.address() (#6165)

* [server] requestIp and AnyRequestContext
Changed Request.uws_request to the new AnyRequestContext. This
allows grabbing the IP from a Request. Unfinished.

* [server] basic `requestIp` implementation

Currently using uws's requestIpAsText, which always returns a ipv6
string. We should return a `SocketAddress` object to the user instead,
which will contain the formatted address string and what type it is.
We'll have to use requestIpAsBinary and parse that ourselves.

* TypeScript docs, use `bun.String`, return `undefined` instead of `null`
if we can't get the ip.

* binary address formatting

* uws getRemoteAddress binding

* remove dead code

* working

* final touches

* I will abide by the results of this poll.

---------

Co-authored-by: Parzival-3141 <29632054+Parzival-3141@users.noreply.github.com>
This commit is contained in:
dave caruso
2023-09-29 03:39:26 -07:00
committed by GitHub
parent 6514dcf4cb
commit 6afa78120a
20 changed files with 553 additions and 47 deletions

View File

@@ -125,21 +125,18 @@ function validateFunction(callable: any, field: string) {
type FakeSocket = InstanceType<typeof FakeSocket>;
var FakeSocket = class Socket extends Duplex {
[kInternalSocketData]: any;
[kInternalSocketData]!: [import("bun").Server, OutgoingMessage, Request];
bytesRead = 0;
bytesWritten = 0;
connecting = false;
remoteAddress: string | null = null;
remotePort;
timeout = 0;
isServer = false;
#address;
address() {
return {
address: this.localAddress,
family: this.localFamily,
port: this.localPort,
};
// Call server.requestIP() without doing any propety getter twice.
var internalData;
return (this.#address ??= (internalData = this[kInternalSocketData])[0].requestIP(internalData[2]));
}
get bufferSize() {
@@ -183,8 +180,31 @@ var FakeSocket = class Socket extends Duplex {
ref() {}
get remoteAddress() {
return this.address()?.address;
}
set remoteAddress(val) {
// initialize the object so that other properties wouldn't be lost
this.address().address = val;
}
get remotePort() {
return this.address()?.port;
}
set remotePort(val) {
// initialize the object so that other properties wouldn't be lost
this.address().port = val;
}
get remoteFamily() {
return "IPv4";
return this.address()?.family;
}
set remoteFamily(val) {
// initialize the object so that other properties wouldn't be lost
this.address().family = val;
}
resetAndDestroy() {}
@@ -511,14 +531,14 @@ class Server extends EventEmitter {
const http_req = new RequestClass(req);
const http_res = new ResponseClass({ reply, req: http_req });
http_req.socket[kInternalSocketData] = [_server, http_res, req];
http_req.once("error", err => reject(err));
http_res.once("error", err => reject(err));
const upgrade = req.headers.get("upgrade");
if (upgrade) {
const socket = http_req.socket;
socket[kInternalSocketData] = [_server, http_res, req];
server.emit("upgrade", http_req, socket, kEmptyBuffer);
server.emit("upgrade", http_req, http_req.socket, kEmptyBuffer);
} else {
server.emit("request", http_req, http_res);
}
@@ -598,13 +618,11 @@ class IncomingMessage extends Readable {
this.#bodyStream = undefined;
const socket = new FakeSocket();
socket.remoteAddress = url.hostname;
socket.remotePort = url.port;
if (url.protocol === "https:") socket.encrypted = true;
this.#fakeSocket = socket;
this.url = url.pathname + url.search;
this.#nodeReq = this.req = nodeReq;
this.req = nodeReq;
assignHeaders(this, req);
}
@@ -619,7 +637,6 @@ class IncomingMessage extends Readable {
#req;
url;
#type;
#nodeReq;
_construct(callback) {
// TODO: streaming