Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion lib/_http_outgoing.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,14 +287,20 @@ OutgoingMessage.prototype.uncork = function uncork() {
callbacks.push(buf[n + 2]);
}
}
this._send(crlf_buf, null, callbacks.length ? (err) => {
const ret = this._send(crlf_buf, null, callbacks.length ? (err) => {
for (const callback of callbacks) {
callback(err);
}
} : null);

this[kChunkedBuffer].length = 0;
this[kChunkedLength] = 0;

// If we successfully flushed and had pending drain, emit it
if (ret && this[kNeedDrain]) {
this[kNeedDrain] = false;
this.emit('drain');
}
};

OutgoingMessage.prototype.setTimeout = function setTimeout(msecs, callback) {
Expand Down
70 changes: 70 additions & 0 deletions test/parallel/test-http-response-drain-cork.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
'use strict';
const common = require('../common');
const http = require('http');
const assert = require('assert');

// Test that drain event is emitted correctly when using cork/uncork
// with ServerResponse and the write buffer is full

const server = http.createServer(common.mustCall(async (req, res) => {
res.cork();

Check failure on line 11 in test/parallel/test-http-response-drain-cork.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Trailing spaces not allowed
// Write small amount - won't need drain
assert.strictEqual(res.write('1'.repeat(100)), true);

Check failure on line 14 in test/parallel/test-http-response-drain-cork.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Trailing spaces not allowed
// Write large amount that should require drain
const needsDrain = !res.write('2'.repeat(1000000));

Check failure on line 17 in test/parallel/test-http-response-drain-cork.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Trailing spaces not allowed
if (needsDrain) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should always need drain right? It's corked so there's no race condition or anything.

Unless there's a good reason, imo it would be better to enforce that (assert.strictEqual(res.write('2'.repeat(1000000)), false)) and drop the if here entirely.

// Verify writableNeedDrain is set
assert.strictEqual(res.writableNeedDrain, true);

Check failure on line 21 in test/parallel/test-http-response-drain-cork.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Trailing spaces not allowed
// Wait for drain event after uncorking
const drainPromise = new Promise((resolve) => {
res.once('drain', common.mustCall(() => {
// After drain, writableNeedDrain should be false
assert.strictEqual(res.writableNeedDrain, false);
resolve();
}));
});

Check failure on line 30 in test/parallel/test-http-response-drain-cork.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Trailing spaces not allowed
// Uncork should trigger drain if needed
res.uncork();

Check failure on line 33 in test/parallel/test-http-response-drain-cork.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Trailing spaces not allowed
await drainPromise;

Check failure on line 35 in test/parallel/test-http-response-drain-cork.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Trailing spaces not allowed
// Cork again for next write
res.cork();
}

Check failure on line 39 in test/parallel/test-http-response-drain-cork.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Trailing spaces not allowed
// Write more data
res.write('3'.repeat(100));

Check failure on line 42 in test/parallel/test-http-response-drain-cork.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Trailing spaces not allowed
// Final uncork and end
res.uncork();
res.end();
}));

server.listen(0, common.mustCall(() => {
http.get({
port: server.address().port,
}, common.mustCall((res) => {
let data = '';
res.setEncoding('utf8');

Check failure on line 54 in test/parallel/test-http-response-drain-cork.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Trailing spaces not allowed
res.on('data', (chunk) => {
data += chunk;
});

res.on('end', common.mustCall(() => {
// Verify we got all the data
assert.strictEqual(data.length, 100 + 1000000 + 100);
assert.strictEqual(data.substring(0, 100), '1'.repeat(100));
assert.strictEqual(data.substring(100, 1000100), '2'.repeat(1000000));
assert.strictEqual(data.substring(1000100), '3'.repeat(100));

server.close();
}));
}));
}));

Loading