From 6aa790c5160b34b27fdc791075301cc80a6c07e4 Mon Sep 17 00:00:00 2001 From: Brian White Date: Wed, 7 Jun 2017 11:25:24 -0400 Subject: [PATCH] http: always cork outgoing writes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/13522 Reviewed-By: Matteo Collina Reviewed-By: Colin Ihrig Reviewed-By: Tobias Nießen Reviewed-By: James M Snell Reviewed-By: Fedor Indutny --- benchmark/fixtures/simple-http-server.js | 62 +++++++++++------------- benchmark/http/simple.js | 6 ++- lib/_http_outgoing.js | 10 ++-- 3 files changed, 38 insertions(+), 40 deletions(-) diff --git a/benchmark/fixtures/simple-http-server.js b/benchmark/fixtures/simple-http-server.js index 1dda98e9f2d9c1..854d249ac803e0 100644 --- a/benchmark/fixtures/simple-http-server.js +++ b/benchmark/fixtures/simple-http-server.js @@ -27,13 +27,14 @@ module.exports = http.createServer(function(req, res) { dom.add(res); } - // URL format: //// + // URL format: /////chunkedEnc var params = req.url.split('/'); var command = params[1]; var body = ''; var arg = params[2]; var n_chunks = parseInt(params[3], 10); var resHow = (params.length >= 5 ? params[4] : 'normal'); + var chunkedEnc = (params.length >= 6 && params[5] === 'false' ? false : true); var status = 200; var n, i; @@ -95,48 +96,43 @@ module.exports = http.createServer(function(req, res) { // example: http://localhost:port/bytes/512/4 // sends a 512 byte body in 4 chunks of 128 bytes - if (n_chunks > 0) { - switch (resHow) { - case 'setHeader': - res.statusCode = status; - res.setHeader('Content-Type', 'text/plain'); + var len = body.length; + switch (resHow) { + case 'setHeader': + res.statusCode = status; + res.setHeader('Content-Type', 'text/plain'); + if (chunkedEnc) res.setHeader('Transfer-Encoding', 'chunked'); - break; - case 'setHeaderWH': - res.setHeader('Content-Type', 'text/plain'); + else + res.setHeader('Content-Length', len.toString()); + break; + case 'setHeaderWH': + res.setHeader('Content-Type', 'text/plain'); + if (chunkedEnc) res.writeHead(status, { 'Transfer-Encoding': 'chunked' }); - break; - default: + else + res.writeHead(status, { 'Content-Length': len.toString() }); + break; + default: + if (chunkedEnc) { res.writeHead(status, { 'Content-Type': 'text/plain', 'Transfer-Encoding': 'chunked' }); - } - // send body in chunks - var len = body.length; + } else { + res.writeHead(status, { + 'Content-Type': 'text/plain', + 'Content-Length': len.toString() + }); + } + } + // send body in chunks + if (n_chunks > 1) { var step = Math.floor(len / n_chunks) || 1; - - for (i = 0, n = (n_chunks - 1); i < n; ++i) { + for (i = 0, n = (n_chunks - 1); i < n; ++i) res.write(body.slice(i * step, i * step + step)); - } res.end(body.slice((n_chunks - 1) * step)); } else { - switch (resHow) { - case 'setHeader': - res.statusCode = status; - res.setHeader('Content-Type', 'text/plain'); - res.setHeader('Content-Length', body.length.toString()); - break; - case 'setHeaderWH': - res.setHeader('Content-Type', 'text/plain'); - res.writeHead(status, { 'Content-Length': body.length.toString() }); - break; - default: - res.writeHead(status, { - 'Content-Type': 'text/plain', - 'Content-Length': body.length.toString() - }); - } res.end(body); } }); diff --git a/benchmark/http/simple.js b/benchmark/http/simple.js index 81b7cb5afb2614..6dc69a2d8f6e85 100644 --- a/benchmark/http/simple.js +++ b/benchmark/http/simple.js @@ -6,8 +6,9 @@ var bench = common.createBenchmark(main, { // unicode confuses ab on os x. type: ['bytes', 'buffer'], len: [4, 1024, 102400], - chunks: [0, 1, 4], // chunks=0 means 'no chunked encoding'. + chunks: [1, 4], c: [50, 500], + chunkedEnc: ['true', 'false'], res: ['normal', 'setHeader', 'setHeaderWH'] }); @@ -16,7 +17,8 @@ function main(conf) { var server = require('../fixtures/simple-http-server.js') .listen(process.env.PORT || common.PORT) .on('listening', function() { - var path = `/${conf.type}/${conf.len}/${conf.chunks}/${conf.res}`; + var path = + `/${conf.type}/${conf.len}/${conf.chunks}/${conf.res}/${conf.chunkedEnc}`; bench.http({ path: path, diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index 84aa57151f2182..b3706d5a9ef811 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -660,6 +660,11 @@ function write_(msg, chunk, encoding, callback, fromEnd) { // signal the user to keep writing. if (chunk.length === 0) return true; + if (!fromEnd && msg.connection && !msg.connection.corked) { + msg.connection.cork(); + process.nextTick(connectionCorkNT, msg.connection); + } + var len, ret; if (msg.chunkedEncoding) { if (typeof chunk === 'string') @@ -667,11 +672,6 @@ function write_(msg, chunk, encoding, callback, fromEnd) { else len = chunk.length; - if (msg.connection && !msg.connection.corked) { - msg.connection.cork(); - process.nextTick(connectionCorkNT, msg.connection); - } - msg._send(len.toString(16), 'latin1', null); msg._send(crlf_buf, null, null); msg._send(chunk, encoding, null);