Compare commits

..

1 Commits

Author SHA1 Message Date
Jarred Sumner
039b4a31ac Add test-http-server-response-standalone and fix ServerResponse.end 2025-05-29 15:46:01 -07:00
4 changed files with 89 additions and 63 deletions

View File

@@ -231,9 +231,54 @@ const ServerResponsePrototype = {
}
if (!handle) {
if ($isCallable(callback)) {
process.nextTick(callback);
if (!this.socket) {
if ($isCallable(callback)) {
process.nextTick(callback);
}
return this;
}
this._implicitHeader();
if (chunk) {
OutgoingMessagePrototype._send.$call(this, chunk, encoding, null);
} else {
OutgoingMessagePrototype._send.$call(this, kEmptyBuffer, encoding, null);
}
const socket = this.socket;
this.detachSocket(socket);
this.finished = true;
process.nextTick(self => {
self._ended = true;
}, this);
this.emit("prefinish");
this._callPendingCallbacks();
if (callback) {
process.nextTick(
function (callback, self) {
self.emit("finish");
try {
callback();
} catch (err) {
self.emit("error", err);
}
process.nextTick(emitCloseNT, self);
},
callback,
this,
);
} else {
process.nextTick(function (self) {
self.emit("finish");
process.nextTick(emitCloseNT, self);
}, this);
}
socket.end(Buffer.alloc(0));
return this;
}

View File

@@ -24,7 +24,6 @@ const Duplex = require("internal/streams/duplex");
const { getDefaultHighWaterMark } = require("internal/streams/state");
const EventEmitter = require("node:events");
let dns: typeof import("node:dns");
const os = require("node:os");
const [addServerName, upgradeDuplexToTLS, isNamedPipeSocket, getBufferedAmount] = $zig(
"socket.zig",
@@ -88,20 +87,6 @@ function isIP(s): 0 | 4 | 6 {
return 0;
}
function isLocalAddress(addr: string): boolean {
if (!addr) return false;
if (addr === "0.0.0.0" || addr === "::") return true;
const interfaces = os.networkInterfaces();
for (const name in interfaces) {
const list = interfaces[name];
if (!list) continue;
for (const info of list) {
if (info && info.address === addr) return true;
}
}
return false;
}
const bunTlsSymbol = Symbol.for("::buntls::");
const bunSocketServerOptions = Symbol.for("::bunnetserveroptions::");
const owner_symbol = Symbol("owner_symbol");
@@ -1717,23 +1702,13 @@ function internalConnect(self, options, address, port, addressType, localAddress
if (localAddress || localPort) {
if (addressType === 4) {
localAddress ||= DEFAULT_IPV4_ADDR;
if (!isLocalAddress(localAddress)) {
const UV_EADDRNOTAVAIL = -4090;
const ex = new ExceptionWithHostPort(UV_EADDRNOTAVAIL, "bind", localAddress, localPort);
self.destroy(ex);
return;
}
// TODO: bind socket when supported
// TODO:
// err = self._handle.bind(localAddress, localPort);
} else {
// addressType === 6
localAddress ||= DEFAULT_IPV6_ADDR;
if (!isLocalAddress(localAddress)) {
const UV_EADDRNOTAVAIL = -4090;
const ex = new ExceptionWithHostPort(UV_EADDRNOTAVAIL, "bind", localAddress, localPort);
self.destroy(ex);
return;
}
// TODO: bind6 socket when supported
// TODO:
// err = self._handle.bind6(localAddress, localPort, flags);
}
$debug(
"connect: binding to localAddress: %s and localPort: %d (addressType: %d)",

View File

@@ -1,32 +0,0 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const http = require('http');
const invalidLocalAddress = '1.2.3.4';
const server = http.createServer(function(req, res) {
console.log(`Connect from: ${req.connection.remoteAddress}`);
req.on('end', function() {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(`You are from: ${req.connection.remoteAddress}`);
});
req.resume();
});
server.listen(0, '127.0.0.1', common.mustCall(function() {
http.request({
host: 'localhost',
port: this.address().port,
path: '/',
method: 'GET',
localAddress: invalidLocalAddress
}, function(res) {
assert.fail('unexpectedly got response from server');
}).on('error', common.mustCall(function(e) {
console.log(`client got error: ${e.message}`);
server.close();
})).end();
}));

View File

@@ -0,0 +1,38 @@
const common = require('../common');
const { ServerResponse } = require('http');
const { Writable } = require('stream');
const assert = require('assert');
// Check that ServerResponse can be used without a proper Socket
// Refs: https://github.com/nodejs/node/issues/14386
// Refs: https://github.com/nodejs/node/issues/14381
const res = new ServerResponse({
method: 'GET',
httpVersionMajor: 1,
httpVersionMinor: 1
});
let firstChunk = true;
const ws = new Writable({
write: common.mustCall((chunk, encoding, callback) => {
if (firstChunk) {
assert(chunk.toString().endsWith('hello world'));
firstChunk = false;
} else {
assert.strictEqual(chunk.length, 0);
}
setImmediate(callback);
}, 2)
});
res.assignSocket(ws);
assert.throws(function() {
res.assignSocket(ws);
}, {
code: 'ERR_HTTP_SOCKET_ASSIGNED'
});
res.end('hello world');