Skip to content

Conversation

@awwright
Copy link
Contributor

This is a test that, by all indications, should pass, and would have passed prior to 206ae31

See #29609 for information.

@nodejs-github-botnodejs-github-bot added the test Issues and PRs related to the tests. label Sep 22, 2019
@mscdex
Copy link
Contributor

Subsystem prefix in the commit message should be test instead of http.

@BridgeAR
Copy link
Member

@nodejs/http PTAL

@Trott
Copy link
Member

@lpinca

@TrottTrott added the http Issues or PRs related to the http subsystem. label Sep 24, 2019
@lpinca
Copy link
Member

lpinca commented Sep 24, 2019

This needs investigation. I cannot reproduce with net.Socket.

'use strict';constassert=require('assert');consthttp=require('http');consttestData='Hello, World!\n';constserver=http.createServer(function(req,res){res.statusCode=200;res.setHeader('Content-Type','text/plain');res.end(testData);req.once('end',function(){res.end(testData);});});server.listen(8080,function(){constreq=http.request({port: 8080},function(res){res.setEncoding('utf8');letdata='';res.on('data',function(chunk){data+=chunk;});res.on('end',function(){assert.strictEqual(data,testData);server.close();});});req.end();});

Works as expected.

@awwright
Copy link
ContributorAuthor

@lpinca Your test ends the response twice, this hangs for me when I remove the first call to res.end:

'use strict';constassert=require('assert');consthttp=require('http');consttestData='Hello, World!\n';constserver=http.createServer(function(req,res){res.statusCode=200;res.setHeader('Content-Type','text/plain');// res.end(testData);req.once('end',function(){res.end(testData);});});server.listen(8080,function(){constreq=http.request({port: 8080},function(res){res.setEncoding('utf8');letdata='';res.on('data',function(chunk){data+=chunk;});res.on('end',function(){assert.strictEqual(data,testData);server.close();});});req.end();});

@awwright
Copy link
ContributorAuthor

Actually, that's because the request was never resumed, ugh

req.resume();

seems to make it work again

The bug I'm looking to reproduce calls the request "end" event, but fails to write the ending to the response.

@awwright
Copy link
ContributorAuthor

I'm going to spend some time better adapting #29609

@awwright
Copy link
ContributorAuthor

Added a chunked test case that passes, and a Content-Length test case that does not (but clearly should)

@awwright
Copy link
ContributorAuthor

In chunked mode, Node.js works as expected (in all versions).

In Content-Length mode, Node.js fails:

Prior to 206ae31, Node.js failed only serverSide.on('end', common.mustCall());.

Starting 206ae31, Node.js fails both clientSide.on('end', common.mustCall()); and serverSide.on('end', common.mustCall());

@lpinca
Copy link
Member

@awwright I copied your tests and again I can't reproduce with net.Socket.

Details
constassert=require('assert');consthttp=require('http');consttestData='Hello, World!\n';{constserver=http.createServer(function(req,res){req.setEncoding('utf8');letdata='';req.on('data',function(chunk){data+=chunk;});req.on('end',function(){assert.strictEqual(data,testData);res.statusCode=200;res.setHeader('Content-Type','text/plain');res.write(testData);res.end();});});server.listen(function(){constreq=http.request({port: server.address().port,method: 'PUT',headers: {Connection: 'close'}},function(res){res.setEncoding('utf8');letdata='';res.on('data',function(chunk){data+=chunk;});res.on('end',function(){assert.strictEqual(data,testData);server.close();});});req.write(testData);req.end();});}{constlength=String(testData.length);constserver=http.createServer(function(req,res){assert.strictEqual(req.headers['content-length'],length);req.setEncoding('utf8');letdata='';req.on('data',function(chunk){data+=chunk;});req.once('end',function(){assert.strictEqual(data,testData);res.statusCode=200;res.setHeader('Content-Type','text/plain');res.setHeader('Content-Length',testData.length);res.write(testData);res.end();});});server.listen(function(){constreq=http.request({port: server.address().port,method: 'PUT',headers: {Connection: 'close','Content-Length': length}},function(res){assert.strictEqual(res.headers['content-length'],length);res.setEncoding('utf8');letdata='';res.on('data',function(chunk){data+=chunk;});res.on('end',function(){assert.strictEqual(data,testData);server.close();});});req.write(testData);req.end();});}

@awwright
Copy link
ContributorAuthor

@lpinca I assume Socket is doing some work that avoids a race condition; I was able to recreate the bug with only "stream", so it's not even related to http, see #29609 (comment)

Nonetheless, is my assessment correct that this test should pass?

@lpinca
Copy link
Member

lpinca commented Sep 29, 2019

Nonetheless, is my assessment correct that this test should pass?

Yes, that's why in #29649 (comment) I said this needs investigation.

@ronagronag mentioned this pull request Oct 3, 2019
4 tasks
@mscdexmscdex changed the title http: test server response that waits for request endtest: test server response that waits for request endOct 3, 2019
@Trott
Copy link
Member

Trott commented Oct 4, 2019

@awwright Any chance that applying #29836 will cause the test to pass?

@ronag
Copy link
Member

ronag commented Oct 4, 2019

@Trott: The commit and test from this PR is included in #29836

@awwright
Copy link
ContributorAuthor

awwright commented Oct 4, 2019

@Trott I suppose #29649 (that seems to be included in #29836) would pass, but makeDuplexPair is also implemented in and at least a couple packages: https://yarnpkg.com/en/package/duplexpairhttps://yarnpkg.com/en/package/native-duplexpair

(edit) Actually this would fix "tls", to whatever extent that's impacted

@awwright
Copy link
ContributorAuthor

I didn't realize this was the test case I wrote up, let's try this again...

#29836 is a decedent commit of this PR so it seems to cause the test to pass; but few other libraries still use the old code; e.g. https://yarnpkg.com/en/package/native-duplexpair; and it would need to be updated in the Writable documentation why I need to handle an empty write as a special case.

Also, historical versions of my package would continue to fail, even though it was written for Node.js 12.0.0. Not the end of the world, but it makes e.g. git blame somewhat more difficult.

@ronag
Copy link
Member

ronag commented Oct 4, 2019

Writable documentation why I need to handle an empty write as a special case

Updated PR with doc changes. Please take a look and see if you have any further suggestion.

@awwright
Copy link
ContributorAuthor

@ronag It seems unintuitive to me, but with that explanation (that _read isn't really a callback, more like an event, so note a special case where it doesn't get called), I don't really have any reason to object.

@ronag
Copy link
Member

ronag commented Oct 4, 2019

@awwright: I didn't quite follow that :). If you make a commit or PR I'm more than happy to cherry pick your suggestion.

Trott pushed a commit that referenced this pull request Oct 6, 2019
If nothing is buffered then _read will not be called and the callback will not be invoked, effectivly deadlocking. Fixes: #29758 PR-URL: #29836 Refs: #29649 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Minwoo Jung <[email protected]>
Trott pushed a commit that referenced this pull request Oct 6, 2019
PR-URL: #29836 Refs: #29758 Refs: #29649 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Minwoo Jung <[email protected]>
@awwright
Copy link
ContributorAuthor

Included in #29836

@awwrightawwright closed this Oct 8, 2019
BridgeAR pushed a commit that referenced this pull request Oct 9, 2019
If nothing is buffered then _read will not be called and the callback will not be invoked, effectivly deadlocking. Fixes: #29758 PR-URL: #29836 Refs: #29649 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Minwoo Jung <[email protected]>
BridgeAR pushed a commit that referenced this pull request Oct 9, 2019
PR-URL: #29836 Refs: #29758 Refs: #29649 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Minwoo Jung <[email protected]>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

httpIssues or PRs related to the http subsystem.testIssues and PRs related to the tests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@awwright@mscdex@BridgeAR@Trott@lpinca@ronag@nodejs-github-bot