-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
http2: fix compat stream read handling, add tests
Handle edge case where stream pause is called between resume being called and actually evaluated. Other minor adjustments to avoid various edge cases around stream events. Add new tests that cover all changes. Fixes: #15491 PR-URL: #15503 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]>
- Loading branch information
1 parent
ebc58d7
commit c705f10
Showing
4 changed files
with
170 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// Flags: --expose-http2 | ||
'use strict'; | ||
|
||
const common = require('../common'); | ||
if (!common.hasCrypto) | ||
common.skip('missing crypto'); | ||
const assert = require('assert'); | ||
const h2 = require('http2'); | ||
|
||
// Check that pause & resume work as expected with Http2ServerRequest | ||
|
||
const testStr = 'Request Body from Client'; | ||
|
||
const server = h2.createServer(); | ||
|
||
server.on('request', common.mustCall((req, res) => { | ||
let data = ''; | ||
req.pause(); | ||
req.setEncoding('utf8'); | ||
req.on('data', common.mustCall((chunk) => (data += chunk))); | ||
setTimeout(common.mustCall(() => { | ||
assert.strictEqual(data, ''); | ||
req.resume(); | ||
}), common.platformTimeout(100)); | ||
req.on('end', common.mustCall(() => { | ||
assert.strictEqual(data, testStr); | ||
res.end(); | ||
})); | ||
|
||
// shouldn't throw if underlying Http2Stream no longer exists | ||
res.on('finish', common.mustCall(() => process.nextTick(() => { | ||
assert.doesNotThrow(() => req.pause()); | ||
assert.doesNotThrow(() => req.resume()); | ||
}))); | ||
})); | ||
|
||
server.listen(0, common.mustCall(() => { | ||
const port = server.address().port; | ||
|
||
const client = h2.connect(`http://localhost:${port}`); | ||
const request = client.request({ | ||
':path': '/foobar', | ||
':method': 'POST', | ||
':scheme': 'http', | ||
':authority': `localhost:${port}` | ||
}); | ||
request.resume(); | ||
request.end(testStr); | ||
request.on('end', common.mustCall(function() { | ||
client.destroy(); | ||
server.close(); | ||
})); | ||
})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Flags: --expose-http2 | ||
'use strict'; | ||
|
||
const common = require('../common'); | ||
if (!common.hasCrypto) | ||
common.skip('missing crypto'); | ||
const assert = require('assert'); | ||
const http2 = require('http2'); | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
|
||
// piping should work as expected with createWriteStream | ||
|
||
const loc = path.join(common.fixturesDir, 'person.jpg'); | ||
const fn = path.join(common.tmpDir, 'http2pipe.jpg'); | ||
common.refreshTmpDir(); | ||
|
||
const server = http2.createServer(); | ||
|
||
server.on('request', common.mustCall((req, res) => { | ||
const dest = req.pipe(fs.createWriteStream(fn)); | ||
dest.on('finish', common.mustCall(() => { | ||
assert.deepStrictEqual(fs.readFileSync(loc), fs.readFileSync(fn)); | ||
fs.unlinkSync(fn); | ||
res.end(); | ||
})); | ||
})); | ||
|
||
server.listen(0, common.mustCall(() => { | ||
const port = server.address().port; | ||
const client = http2.connect(`http://localhost:${port}`); | ||
|
||
let remaining = 2; | ||
function maybeClose() { | ||
if (--remaining === 0) { | ||
server.close(); | ||
client.destroy(); | ||
} | ||
} | ||
|
||
const req = client.request({ ':method': 'POST' }); | ||
req.on('response', common.mustCall()); | ||
req.resume(); | ||
req.on('end', common.mustCall(maybeClose)); | ||
const str = fs.createReadStream(loc); | ||
str.on('end', common.mustCall(maybeClose)); | ||
str.pipe(req); | ||
})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Flags: --expose-http2 | ||
'use strict'; | ||
|
||
const common = require('../common'); | ||
if (!common.hasCrypto) | ||
common.skip('missing crypto'); | ||
const assert = require('assert'); | ||
const h2 = require('http2'); | ||
|
||
// Check that drain event is passed from Http2Stream | ||
|
||
const testString = 'tests'; | ||
|
||
const server = h2.createServer(); | ||
|
||
server.on('request', common.mustCall((req, res) => { | ||
res.stream._writableState.highWaterMark = testString.length; | ||
assert.strictEqual(res.write(testString), false); | ||
res.on('drain', common.mustCall(() => res.end(testString))); | ||
})); | ||
|
||
server.listen(0, common.mustCall(() => { | ||
const port = server.address().port; | ||
|
||
const client = h2.connect(`http://localhost:${port}`); | ||
const request = client.request({ | ||
':path': '/foobar', | ||
':method': 'POST', | ||
':scheme': 'http', | ||
':authority': `localhost:${port}` | ||
}); | ||
request.resume(); | ||
request.end(); | ||
|
||
let data = ''; | ||
request.setEncoding('utf8'); | ||
request.on('data', (chunk) => (data += chunk)); | ||
|
||
request.on('end', common.mustCall(function() { | ||
assert.strictEqual(data, testString.repeat(2)); | ||
client.destroy(); | ||
server.close(); | ||
})); | ||
})); |