From 3a18e17f61ebec997b002a9040dfe0ecbc795064 Mon Sep 17 00:00:00 2001 From: sogaani Date: Fri, 3 Aug 2018 00:22:57 +0900 Subject: [PATCH 01/16] http2 support --- index.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 4da7301..28ecde0 100644 --- a/index.js +++ b/index.js @@ -84,16 +84,32 @@ function typeis (value, types_) { * or `content-length` headers set. * http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3 * + * A http/2 request with DataFrame can have no `content-length` header. + * https://httpwg.org/specs/rfc7540.html + * * @param {Object} request * @return {Boolean} * @public */ function hasbody (req) { - return req.headers['transfer-encoding'] !== undefined || + return ishttp2(req) || + req.headers['transfer-encoding'] !== undefined || !isNaN(req.headers['content-length']) } +/** + * Check if a request is a http2 request. + * + * @param {Object} request + * @return {Boolean} + * @public + */ + +function ishttp2 (req) { + return req.httpVersionMajor === 2 +} + /** * Check if the incoming request contains the "Content-Type" * header field, and it contains any of the give mime `type`s. From 61e5115368ebee73265920f3280294753ff1c69e Mon Sep 17 00:00:00 2001 From: sogaani Date: Fri, 3 Aug 2018 00:35:08 +0900 Subject: [PATCH 02/16] Add http2 tests --- .travis.yml | 6 ++++++ test/test.js | 25 +++++++++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index bf4f58f..8081e80 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,3 +37,9 @@ script: - "test -z $(npm -ps ls eslint ) || npm run-script lint" after_script: - "test -e ./coverage/lcov.info && npm install coveralls@2 && cat ./coverage/lcov.info | coveralls" +matrix: + include: + - node_js: "9.5" + env: HTTP2_TEST=1 + - node_js: "8.9" + env: HTTP2_TEST=1 diff --git a/test/test.js b/test/test.js index 4fe654f..6e6d59d 100644 --- a/test/test.js +++ b/test/test.js @@ -174,13 +174,30 @@ describe('typeis.hasBody(req)', function () { assert.strictEqual(typeis.hasBody(req), true) }) }) + + describe('http2 request', function () { + it('should indicate body', function () { + var req = {headers: {}, httpVersionMajor: 2} + assert.strictEqual(typeis.hasBody(req), true) + }) + }) }) function createRequest (type) { - return { - headers: { - 'content-type': type || '', - 'transfer-encoding': 'chunked' + if (process.env.HTTP2_TEST) { + console.log('http2') + return { + headers: { + 'content-type': type || '' + }, + httpVersionMajor: 2 + } + } else { + return { + headers: { + 'content-type': type || '', + 'transfer-encoding': 'chunked' + } } } } From e8e8cbc7d8bacdcea8efe7e058836506351122c9 Mon Sep 17 00:00:00 2001 From: sogaani Date: Tue, 7 Aug 2018 00:46:10 +0900 Subject: [PATCH 03/16] Check body by if readableStream ended --- index.js | 6 +++++- test/test.js | 29 +++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 28ecde0..04b9f1f 100644 --- a/index.js +++ b/index.js @@ -86,6 +86,10 @@ function typeis (value, types_) { * * A http/2 request with DataFrame can have no `content-length` header. * https://httpwg.org/specs/rfc7540.html + * + * A http/2 request without DataFrame send HeaderFrame with end-stream-flag. + * If nodejs gets end-stream-flag, then nodejs ends readable stream. + * https://github.com/nodejs/node/blob/master/lib/internal/http2/core.js#L301 * * @param {Object} request * @return {Boolean} @@ -93,7 +97,7 @@ function typeis (value, types_) { */ function hasbody (req) { - return ishttp2(req) || + return (ishttp2(req) && !req.stream._readableState.ended)|| req.headers['transfer-encoding'] !== undefined || !isNaN(req.headers['content-length']) } diff --git a/test/test.js b/test/test.js index 6e6d59d..d0ee1c5 100644 --- a/test/test.js +++ b/test/test.js @@ -176,8 +176,29 @@ describe('typeis.hasBody(req)', function () { }) describe('http2 request', function () { + it('should not indicate body', function () { + var req = { + headers: {}, + stream: { + _readableState: { + ended: true + } + }, + httpVersionMajor: 2 + } + assert.strictEqual(typeis.hasBody(req), false) + }) + it('should indicate body', function () { - var req = {headers: {}, httpVersionMajor: 2} + var req = { + headers: {}, + stream: { + _readableState: { + ended: false + } + }, + httpVersionMajor: 2 + } assert.strictEqual(typeis.hasBody(req), true) }) }) @@ -185,11 +206,15 @@ describe('typeis.hasBody(req)', function () { function createRequest (type) { if (process.env.HTTP2_TEST) { - console.log('http2') return { headers: { 'content-type': type || '' }, + stream: { + _readableState: { + ended: false + } + }, httpVersionMajor: 2 } } else { From c2806ac0990048439382b6b31aadffa30aa92a50 Mon Sep 17 00:00:00 2001 From: sogaani Date: Tue, 7 Aug 2018 00:52:40 +0900 Subject: [PATCH 04/16] Lint --- index.js | 4 ++-- test/test.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 04b9f1f..22fe5af 100644 --- a/index.js +++ b/index.js @@ -86,7 +86,7 @@ function typeis (value, types_) { * * A http/2 request with DataFrame can have no `content-length` header. * https://httpwg.org/specs/rfc7540.html - * + * * A http/2 request without DataFrame send HeaderFrame with end-stream-flag. * If nodejs gets end-stream-flag, then nodejs ends readable stream. * https://github.com/nodejs/node/blob/master/lib/internal/http2/core.js#L301 @@ -97,7 +97,7 @@ function typeis (value, types_) { */ function hasbody (req) { - return (ishttp2(req) && !req.stream._readableState.ended)|| + return (ishttp2(req) && !req.stream._readableState.ended) || req.headers['transfer-encoding'] !== undefined || !isNaN(req.headers['content-length']) } diff --git a/test/test.js b/test/test.js index d0ee1c5..cd403d6 100644 --- a/test/test.js +++ b/test/test.js @@ -178,7 +178,7 @@ describe('typeis.hasBody(req)', function () { describe('http2 request', function () { it('should not indicate body', function () { var req = { - headers: {}, + headers: {}, stream: { _readableState: { ended: true @@ -191,7 +191,7 @@ describe('typeis.hasBody(req)', function () { it('should indicate body', function () { var req = { - headers: {}, + headers: {}, stream: { _readableState: { ended: false From e0f0cc6d57398103b977b1eb741a9c734b04f54a Mon Sep 17 00:00:00 2001 From: sogaani Date: Tue, 7 Aug 2018 23:09:02 +0900 Subject: [PATCH 05/16] Don't use mock in http2 test --- package.json | 3 +- test/test.js | 337 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 205 insertions(+), 135 deletions(-) diff --git a/package.json b/package.json index 5b8e207..0803066 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "eslint-plugin-promise": "3.6.0", "eslint-plugin-standard": "3.0.1", "istanbul": "0.4.5", - "mocha": "1.21.5" + "mocha": "1.21.5", + "superagent": "git+https://github.com/visionmedia/superagent.git" }, "engines": { "node": ">= 0.6" diff --git a/test/test.js b/test/test.js index cd403d6..6464763 100644 --- a/test/test.js +++ b/test/test.js @@ -1,151 +1,209 @@ var assert = require('assert') var typeis = require('..') +var request = require('superagent') +var http2 + +if (process.env.HTTP2_TEST) { + request.http2 = true + http2 = require('http2') +} describe('typeis(req, type)', function () { - it('should ignore params', function () { - var req = createRequest('text/html; charset=utf-8') - assert.equal(typeis(req, ['text/*']), 'text/html') + it('should ignore params', function (done) { + createRequest('text/html; charset=utf-8', function (req) { + assert.equal(typeis(req, ['text/*']), 'text/html') + done() + }) }) - it('should ignore params LWS', function () { - var req = createRequest('text/html ; charset=utf-8') - assert.equal(typeis(req, ['text/*']), 'text/html') + it('should ignore params LWS', function (done) { + createRequest('text/html ; charset=utf-8', function (req) { + assert.equal(typeis(req, ['text/*']), 'text/html') + done() + }) }) - it('should ignore casing', function () { - var req = createRequest('text/HTML') - assert.equal(typeis(req, ['text/*']), 'text/html') + it('should ignore casing', function (done) { + createRequest('text/HTML', function (req) { + assert.equal(typeis(req, ['text/*']), 'text/html') + done() + }) }) - it('should fail invalid type', function () { - var req = createRequest('text/html**') - assert.strictEqual(typeis(req, ['text/*']), false) + it('should fail invalid type', function (done) { + createRequest('text/html**', function (req) { + assert.strictEqual(typeis(req, ['text/*']), false) + done() + }) }) - it('should not match invalid type', function () { - var req = createRequest('text/html') - assert.strictEqual(typeis(req, ['text/html/']), false) - assert.strictEqual(typeis(req, [undefined, null, true, function () {}]), false) + it('should not match invalid type', function (done) { + createRequest('text/html', function (req) { + assert.strictEqual(typeis(req, ['text/html/']), false) + assert.strictEqual(typeis(req, [undefined, null, true, function () {}]), false) + done() + }) }) describe('when no body is given', function () { - it('should return null', function () { - var req = {headers: {}} - - assert.strictEqual(typeis(req), null) - assert.strictEqual(typeis(req, ['image/*']), null) - assert.strictEqual(typeis(req, 'image/*', 'text/*'), null) + it('should return null', function (done) { + createBodylessRequest('', function (req) { + assert.strictEqual(typeis(req), null) + assert.strictEqual(typeis(req, ['image/*']), null) + assert.strictEqual(typeis(req, 'image/*', 'text/*'), null) + done() + }) }) }) describe('when no content type is given', function () { - it('should return false', function () { - var req = createRequest() - assert.strictEqual(typeis(req), false) - assert.strictEqual(typeis(req, ['image/*']), false) - assert.strictEqual(typeis(req, ['text/*', 'image/*']), false) - }) + if (!process.env.HTTP2_TEST) { + it('should return false', function (done) { + createRequest('', function (req) { + assert.strictEqual(typeis(req), false) + assert.strictEqual(typeis(req, ['image/*']), false) + assert.strictEqual(typeis(req, ['text/*', 'image/*']), false) + done() + }) + }) + } }) describe('give no types', function () { - it('should return the mime type', function () { - var req = createRequest('image/png') - assert.equal(typeis(req), 'image/png') + it('should return the mime type', function (done) { + createRequest('image/png', function (req) { + assert.equal(typeis(req), 'image/png') + done() + }) }) }) describe('given one type', function () { - it('should return the type or false', function () { - var req = createRequest('image/png') - - assert.equal(typeis(req, ['png']), 'png') - assert.equal(typeis(req, ['.png']), '.png') - assert.equal(typeis(req, ['image/png']), 'image/png') - assert.equal(typeis(req, ['image/*']), 'image/png') - assert.equal(typeis(req, ['*/png']), 'image/png') - - assert.strictEqual(typeis(req, ['jpeg']), false) - assert.strictEqual(typeis(req, ['.jpeg']), false) - assert.strictEqual(typeis(req, ['image/jpeg']), false) - assert.strictEqual(typeis(req, ['text/*']), false) - assert.strictEqual(typeis(req, ['*/jpeg']), false) - - assert.strictEqual(typeis(req, ['bogus']), false) - assert.strictEqual(typeis(req, ['something/bogus*']), false) + it('should return the type or false', function (done) { + createRequest('image/png', function (req) { + assert.equal(typeis(req, ['png']), 'png') + assert.equal(typeis(req, ['.png']), '.png') + assert.equal(typeis(req, ['image/png']), 'image/png') + assert.equal(typeis(req, ['image/*']), 'image/png') + assert.equal(typeis(req, ['*/png']), 'image/png') + + assert.strictEqual(typeis(req, ['jpeg']), false) + assert.strictEqual(typeis(req, ['.jpeg']), false) + assert.strictEqual(typeis(req, ['image/jpeg']), false) + assert.strictEqual(typeis(req, ['text/*']), false) + assert.strictEqual(typeis(req, ['*/jpeg']), false) + + assert.strictEqual(typeis(req, ['bogus']), false) + assert.strictEqual(typeis(req, ['something/bogus*']), false) + done() + }) }) }) describe('given multiple types', function () { - it('should return the first match or false', function () { - var req = createRequest('image/png') - - assert.equal(typeis(req, ['png']), 'png') - assert.equal(typeis(req, '.png'), '.png') - assert.equal(typeis(req, ['text/*', 'image/*']), 'image/png') - assert.equal(typeis(req, ['image/*', 'text/*']), 'image/png') - assert.equal(typeis(req, ['image/*', 'image/png']), 'image/png') - assert.equal(typeis(req, 'image/png', 'image/*'), 'image/png') - - assert.strictEqual(typeis(req, ['jpeg']), false) - assert.strictEqual(typeis(req, ['.jpeg']), false) - assert.strictEqual(typeis(req, ['text/*', 'application/*']), false) - assert.strictEqual(typeis(req, ['text/html', 'text/plain', 'application/json']), false) + it('should return the first match or false', function (done) { + createRequest('image/png', function (req) { + assert.equal(typeis(req, ['png']), 'png') + assert.equal(typeis(req, '.png'), '.png') + assert.equal(typeis(req, ['text/*', 'image/*']), 'image/png') + assert.equal(typeis(req, ['image/*', 'text/*']), 'image/png') + assert.equal(typeis(req, ['image/*', 'image/png']), 'image/png') + assert.equal(typeis(req, 'image/png', 'image/*'), 'image/png') + + assert.strictEqual(typeis(req, ['jpeg']), false) + assert.strictEqual(typeis(req, ['.jpeg']), false) + assert.strictEqual(typeis(req, ['text/*', 'application/*']), false) + assert.strictEqual(typeis(req, ['text/html', 'text/plain', 'application/json']), false) + done() + }) }) }) describe('given +suffix', function () { - it('should match suffix types', function () { - var req = createRequest('application/vnd+json') - - assert.equal(typeis(req, '+json'), 'application/vnd+json') - assert.equal(typeis(req, 'application/vnd+json'), 'application/vnd+json') - assert.equal(typeis(req, 'application/*+json'), 'application/vnd+json') - assert.equal(typeis(req, '*/vnd+json'), 'application/vnd+json') - assert.strictEqual(typeis(req, 'application/json'), false) - assert.strictEqual(typeis(req, 'text/*+json'), false) + it('should match suffix types', function (done) { + createRequest('application/vnd+json', function (req) { + assert.equal(typeis(req, '+json'), 'application/vnd+json') + assert.equal(typeis(req, 'application/vnd+json'), 'application/vnd+json') + assert.equal(typeis(req, 'application/*+json'), 'application/vnd+json') + assert.equal(typeis(req, '*/vnd+json'), 'application/vnd+json') + assert.strictEqual(typeis(req, 'application/json'), false) + assert.strictEqual(typeis(req, 'text/*+json'), false) + done() + }) }) }) describe('given "*/*"', function () { - it('should match any content-type', function () { - assert.equal(typeis(createRequest('text/html'), '*/*'), 'text/html') - assert.equal(typeis(createRequest('text/xml'), '*/*'), 'text/xml') - assert.equal(typeis(createRequest('application/json'), '*/*'), 'application/json') - assert.equal(typeis(createRequest('application/vnd+json'), '*/*'), 'application/vnd+json') + describe('should match any content-type', function () { + it('text/html', function (done) { + createRequest('text/html', function (req) { + assert.equal(typeis(req, '*/*'), 'text/html') + done() + }) + }) + + it('text/xml', function (done) { + createRequest('text/xml', function (req) { + assert.equal(typeis(req, '*/*'), 'text/xml') + done() + }) + }) + + it('application/json', function (done) { + createRequest('application/json', function (req) { + assert.equal(typeis(req, '*/*'), 'application/json') + done() + }) + }) + + it('application/vnd+json', function (done) { + createRequest('application/vnd+json', function (req) { + assert.equal(typeis(req, '*/*'), 'application/vnd+json') + done() + }) + }) }) - it('should not match invalid content-type', function () { - assert.strictEqual(typeis(createRequest('bogus'), '*/*'), false) + it('should not match invalid content-type', function (done) { + createRequest('bogus', function (req) { + assert.strictEqual(typeis(req, '*/*'), false) + done() + }) }) - it('should not match body-less request', function () { - var req = {headers: {'content-type': 'text/html'}} - assert.strictEqual(typeis(req, '*/*'), null) + it('should not match body-less request', function (done) { + createBodylessRequest('text/html', function (req) { + assert.strictEqual(typeis(req, '*/*'), null) + done() + }) }) }) describe('when Content-Type: application/x-www-form-urlencoded', function () { - it('should match "urlencoded"', function () { - var req = createRequest('application/x-www-form-urlencoded') - - assert.equal(typeis(req, ['urlencoded']), 'urlencoded') - assert.equal(typeis(req, ['json', 'urlencoded']), 'urlencoded') - assert.equal(typeis(req, ['urlencoded', 'json']), 'urlencoded') + it('should match "urlencoded"', function (done) { + createRequest('application/x-www-form-urlencoded', function (req) { + assert.equal(typeis(req, ['urlencoded']), 'urlencoded') + assert.equal(typeis(req, ['json', 'urlencoded']), 'urlencoded') + assert.equal(typeis(req, ['urlencoded', 'json']), 'urlencoded') + done() + }) }) }) describe('when Content-Type: multipart/form-data', function () { - it('should match "multipart/*"', function () { - var req = createRequest('multipart/form-data') - - assert.equal(typeis(req, ['multipart/*']), 'multipart/form-data') + it('should match "multipart/*"', function (done) { + createRequest('multipart/form-data', function (req) { + assert.equal(typeis(req, ['multipart/*']), 'multipart/form-data') + done() + }) }) - it('should match "multipart"', function () { - var req = createRequest('multipart/form-data') - - assert.equal(typeis(req, ['multipart']), 'multipart') + it('should match "multipart"', function (done) { + createRequest('multipart/form-data', function (req) { + assert.equal(typeis(req, ['multipart']), 'multipart') + done() + }) }) }) }) @@ -175,54 +233,65 @@ describe('typeis.hasBody(req)', function () { }) }) - describe('http2 request', function () { - it('should not indicate body', function () { - var req = { - headers: {}, - stream: { - _readableState: { - ended: true - } - }, - httpVersionMajor: 2 - } - assert.strictEqual(typeis.hasBody(req), false) - }) - - it('should indicate body', function () { - var req = { - headers: {}, - stream: { - _readableState: { - ended: false - } - }, - httpVersionMajor: 2 - } - assert.strictEqual(typeis.hasBody(req), true) + if (process.env.HTTP2_TEST) { + describe('http2 request', function () { + it('should not indicate body', function (done) { + createBodylessRequest('', function (req) { + assert.strictEqual(typeis.hasBody(req), false) + done() + }) + }) + + it('should indicate body', function (done) { + createRequest('', function (req) { + assert.strictEqual(typeis.hasBody(req), true) + done() + }) + }) }) - }) + } }) -function createRequest (type) { +function createRequest (type, callback) { if (process.env.HTTP2_TEST) { - return { - headers: { - 'content-type': type || '' - }, - stream: { - _readableState: { - ended: false - } - }, - httpVersionMajor: 2 - } + var server = http2.createServer(function (req, res) { + callback(req) + }) + + server = server.listen(function () { + request.post(`localhost:${server.address().port}/`) + .set('content-type', type || '') + .send('buffer') + .end() + }) } else { - return { + var req = { headers: { 'content-type': type || '', 'transfer-encoding': 'chunked' } } + callback(req) + } +} + +function createBodylessRequest (type, callback) { + if (process.env.HTTP2_TEST) { + var server = http2.createServer(function (req, res) { + callback(req) + }) + + server = server.listen(function () { + request.get(`localhost:${server.address().port}/`) + .set('content-type', type || '') + .end() + }) + } else { + var req = { + headers: { + 'content-type': type || '' + } + } + callback(req) } } From 70d00dead8626ef415a8c2718b1367db8e33e598 Mon Sep 17 00:00:00 2001 From: sogaani Date: Tue, 7 Aug 2018 23:17:35 +0900 Subject: [PATCH 06/16] Fix travis tests --- test/test.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/test.js b/test/test.js index 6464763..fa2bd2f 100644 --- a/test/test.js +++ b/test/test.js @@ -1,12 +1,13 @@ var assert = require('assert') var typeis = require('..') -var request = require('superagent') +var request var http2 if (process.env.HTTP2_TEST) { - request.http2 = true http2 = require('http2') + request = require('superagent') + request.http2 = true } describe('typeis(req, type)', function () { From e6da05974020c9f0217be6bdd0f2d971a7380c99 Mon Sep 17 00:00:00 2001 From: sogaani Date: Tue, 7 Aug 2018 23:27:08 +0900 Subject: [PATCH 07/16] Fix travis tests again --- .travis.yml | 1 + package.json | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8081e80..40c9cb8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,7 @@ before_install: - "test $TRAVIS_NODE_VERSION != '0.6' || npm rm --save-dev istanbul" - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" - "test $(echo $TRAVIS_NODE_VERSION | cut -d. -f1) -ge 4 || npm rm --save-dev $(grep -E '\"eslint\\S*\"' package.json | cut -d'\"' -f2)" + - "test -z $(echo $HTTP2_TEST) || npm install --only=dev https://github.com/visionmedia/superagent.git" # Update Node.js modules - "test ! -d node_modules || npm prune" diff --git a/package.json b/package.json index 0803066..5b8e207 100644 --- a/package.json +++ b/package.json @@ -21,8 +21,7 @@ "eslint-plugin-promise": "3.6.0", "eslint-plugin-standard": "3.0.1", "istanbul": "0.4.5", - "mocha": "1.21.5", - "superagent": "git+https://github.com/visionmedia/superagent.git" + "mocha": "1.21.5" }, "engines": { "node": ">= 0.6" From 765a02489d2fd2cc3c5fa8cdd502d1cb1b1646b1 Mon Sep 17 00:00:00 2001 From: sogaani Date: Tue, 7 Aug 2018 23:47:17 +0900 Subject: [PATCH 08/16] Enable no content type test --- test/test.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/test/test.js b/test/test.js index fa2bd2f..a9269cf 100644 --- a/test/test.js +++ b/test/test.js @@ -59,16 +59,14 @@ describe('typeis(req, type)', function () { }) describe('when no content type is given', function () { - if (!process.env.HTTP2_TEST) { - it('should return false', function (done) { - createRequest('', function (req) { - assert.strictEqual(typeis(req), false) - assert.strictEqual(typeis(req, ['image/*']), false) - assert.strictEqual(typeis(req, ['text/*', 'image/*']), false) - done() - }) + it('should return false', function (done) { + createRequest('', function (req) { + assert.strictEqual(typeis(req), false) + assert.strictEqual(typeis(req, ['image/*']), false) + assert.strictEqual(typeis(req, ['text/*', 'image/*']), false) + done() }) - } + }) }) describe('give no types', function () { @@ -261,8 +259,8 @@ function createRequest (type, callback) { server = server.listen(function () { request.post(`localhost:${server.address().port}/`) - .set('content-type', type || '') - .send('buffer') + .send('hello') + .set('content-type', type || undefined) .end() }) } else { @@ -284,7 +282,7 @@ function createBodylessRequest (type, callback) { server = server.listen(function () { request.get(`localhost:${server.address().port}/`) - .set('content-type', type || '') + .set('content-type', type || undefined) .end() }) } else { From 09e012d729285d9eddd914b492489b2bdaf10217 Mon Sep 17 00:00:00 2001 From: sogaani Date: Tue, 7 Aug 2018 23:49:26 +0900 Subject: [PATCH 09/16] Fix travis tests again --- test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.js b/test/test.js index a9269cf..99125ed 100644 --- a/test/test.js +++ b/test/test.js @@ -258,7 +258,7 @@ function createRequest (type, callback) { }) server = server.listen(function () { - request.post(`localhost:${server.address().port}/`) + request.post('localhost:' + server.address().port + '/') .send('hello') .set('content-type', type || undefined) .end() From 9bb739fc92d448904f0f2f77c32ffa5852d4ab8c Mon Sep 17 00:00:00 2001 From: sogaani Date: Tue, 7 Aug 2018 23:54:51 +0900 Subject: [PATCH 10/16] Fix travis tests again --- test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.js b/test/test.js index 99125ed..e4da06a 100644 --- a/test/test.js +++ b/test/test.js @@ -281,7 +281,7 @@ function createBodylessRequest (type, callback) { }) server = server.listen(function () { - request.get(`localhost:${server.address().port}/`) + request.get('localhost:' + server.address().port + '/') .set('content-type', type || undefined) .end() }) From 0108d17c56b9ce95405b75e9a2c59da63b1ce44e Mon Sep 17 00:00:00 2001 From: sogaani Date: Wed, 8 Aug 2018 00:00:49 +0900 Subject: [PATCH 11/16] Close server at test ended --- test/test.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/test.js b/test/test.js index e4da06a..59a317a 100644 --- a/test/test.js +++ b/test/test.js @@ -255,6 +255,7 @@ function createRequest (type, callback) { if (process.env.HTTP2_TEST) { var server = http2.createServer(function (req, res) { callback(req) + server.close() }) server = server.listen(function () { @@ -278,6 +279,7 @@ function createBodylessRequest (type, callback) { if (process.env.HTTP2_TEST) { var server = http2.createServer(function (req, res) { callback(req) + server.close() }) server = server.listen(function () { From 395e271730eb93747621747e4d5d710fd2756abc Mon Sep 17 00:00:00 2001 From: sogaani Date: Thu, 9 Aug 2018 21:59:10 +0900 Subject: [PATCH 12/16] hasBody with http2 request should returns true after 'end' event occured --- .travis.yml | 2 +- index.js | 2 +- test/test.js | 26 +++++++++++++++++++++++--- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 40c9cb8..8267130 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,7 @@ before_install: - "test $TRAVIS_NODE_VERSION != '0.6' || npm rm --save-dev istanbul" - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" - "test $(echo $TRAVIS_NODE_VERSION | cut -d. -f1) -ge 4 || npm rm --save-dev $(grep -E '\"eslint\\S*\"' package.json | cut -d'\"' -f2)" - - "test -z $(echo $HTTP2_TEST) || npm install --only=dev https://github.com/visionmedia/superagent.git" + - "test -z $(echo $HTTP2_TEST) || npm install https://github.com/visionmedia/superagent.git" # Update Node.js modules - "test ! -d node_modules || npm prune" diff --git a/index.js b/index.js index 22fe5af..5f6d250 100644 --- a/index.js +++ b/index.js @@ -97,7 +97,7 @@ function typeis (value, types_) { */ function hasbody (req) { - return (ishttp2(req) && !req.stream._readableState.ended) || + return (ishttp2(req) && (req.stream.readable || req.stream._readableState.endEmitted)) || req.headers['transfer-encoding'] !== undefined || !isNaN(req.headers['content-length']) } diff --git a/test/test.js b/test/test.js index 59a317a..f88bcb1 100644 --- a/test/test.js +++ b/test/test.js @@ -3,11 +3,13 @@ var assert = require('assert') var typeis = require('..') var request var http2 +var readable if (process.env.HTTP2_TEST) { http2 = require('http2') request = require('superagent') request.http2 = true + readable = require('stream').Readable; } describe('typeis(req, type)', function () { @@ -247,6 +249,22 @@ describe('typeis.hasBody(req)', function () { done() }) }) + + it('should indicate body after end event occurred', function (done) { + createRequest('', function (req) { + var data = ''; + req.on('data', function(chunk) { + data += chunk + }) + req.on('end', function(chunk) { + process.nextTick( function(){ + assert.strictEqual(data, 'hello') + assert.strictEqual(typeis.hasBody(req), true) + done() + }) + }) + }) + }) }) } }) @@ -259,10 +277,12 @@ function createRequest (type, callback) { }) server = server.listen(function () { - request.post('localhost:' + server.address().port + '/') - .send('hello') + var s = new readable() + s.push('hello') + s.push(null) + var req = request.post('localhost:' + server.address().port + '/') .set('content-type', type || undefined) - .end() + s.pipe(req) }) } else { var req = { From 9efda35122c7e6039f3513d4392986d1623aabc1 Mon Sep 17 00:00:00 2001 From: sogaani Date: Thu, 9 Aug 2018 22:05:17 +0900 Subject: [PATCH 13/16] Lint --- test/test.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/test.js b/test/test.js index f88bcb1..0f335bf 100644 --- a/test/test.js +++ b/test/test.js @@ -3,13 +3,13 @@ var assert = require('assert') var typeis = require('..') var request var http2 -var readable +var Readable if (process.env.HTTP2_TEST) { http2 = require('http2') request = require('superagent') request.http2 = true - readable = require('stream').Readable; + Readable = require('stream').Readable } describe('typeis(req, type)', function () { @@ -252,12 +252,12 @@ describe('typeis.hasBody(req)', function () { it('should indicate body after end event occurred', function (done) { createRequest('', function (req) { - var data = ''; - req.on('data', function(chunk) { + var data = '' + req.on('data', function (chunk) { data += chunk }) - req.on('end', function(chunk) { - process.nextTick( function(){ + req.on('end', function (chunk) { + process.nextTick(function () { assert.strictEqual(data, 'hello') assert.strictEqual(typeis.hasBody(req), true) done() @@ -277,7 +277,7 @@ function createRequest (type, callback) { }) server = server.listen(function () { - var s = new readable() + var s = new Readable() s.push('hello') s.push(null) var req = request.post('localhost:' + server.address().port + '/') From 97c0d7ac0988fb7ca897829be92b80272d709422 Mon Sep 17 00:00:00 2001 From: sogaani Date: Fri, 10 Aug 2018 00:40:33 +0900 Subject: [PATCH 14/16] Fix hasBody with http2 request while or after 'end' event --- index.js | 2 +- test/test.js | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 5f6d250..62e409d 100644 --- a/index.js +++ b/index.js @@ -97,7 +97,7 @@ function typeis (value, types_) { */ function hasbody (req) { - return (ishttp2(req) && (req.stream.readable || req.stream._readableState.endEmitted)) || + return (ishttp2(req) && (req.stream.readable || !req.stream._readableState.sync)) || req.headers['transfer-encoding'] !== undefined || !isNaN(req.headers['content-length']) } diff --git a/test/test.js b/test/test.js index 0f335bf..52773eb 100644 --- a/test/test.js +++ b/test/test.js @@ -243,6 +243,36 @@ describe('typeis.hasBody(req)', function () { }) }) + it('should not indicate body after end event occurred', function (done) { + createBodylessRequest('', function (req) { + var data = '' + req.on('data', function (chunk) { + data += chunk + }) + req.on('end', function (chunk) { + process.nextTick(function () { + assert.strictEqual(data, '') + assert.strictEqual(typeis.hasBody(req), false) + done() + }) + }) + }) + }) + + it('should not indicate body while end event occurred', function (done) { + createBodylessRequest('', function (req) { + var data = '' + req.on('data', function (chunk) { + data += chunk + }) + req.on('end', function (chunk) { + assert.strictEqual(data, '') + assert.strictEqual(typeis.hasBody(req), false) + done() + }) + }) + }) + it('should indicate body', function (done) { createRequest('', function (req) { assert.strictEqual(typeis.hasBody(req), true) @@ -265,6 +295,29 @@ describe('typeis.hasBody(req)', function () { }) }) }) + + it('should indicate body while end event occurred', function (done) { + createRequest('', function (req) { + var data = '' + req.on('data', function (chunk) { + data += chunk + }) + req.on('end', function (chunk) { + assert.strictEqual(data, 'hello') + assert.strictEqual(typeis.hasBody(req), true) + done() + }) + }) + }) + + it('should indicate body while data event', function (done) { + createRequest('', function (req) { + req.on('data', function (chunk) { + assert.strictEqual(typeis.hasBody(req), true) + done() + }) + }) + }) }) } }) From e5b45d49ecaf5fae3bc5d0fb399a30a7c10e2ab9 Mon Sep 17 00:00:00 2001 From: sogaani Date: Fri, 21 Sep 2018 23:43:12 +0900 Subject: [PATCH 15/16] use endAfterHeaders --- .travis.yml | 5 +---- index.js | 2 +- package.json | 1 + test/test.js | 63 +++++++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 55 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8267130..ff253a7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,6 @@ before_install: - "test $TRAVIS_NODE_VERSION != '0.6' || npm rm --save-dev istanbul" - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" - "test $(echo $TRAVIS_NODE_VERSION | cut -d. -f1) -ge 4 || npm rm --save-dev $(grep -E '\"eslint\\S*\"' package.json | cut -d'\"' -f2)" - - "test -z $(echo $HTTP2_TEST) || npm install https://github.com/visionmedia/superagent.git" # Update Node.js modules - "test ! -d node_modules || npm prune" @@ -40,7 +39,5 @@ after_script: - "test -e ./coverage/lcov.info && npm install coveralls@2 && cat ./coverage/lcov.info | coveralls" matrix: include: - - node_js: "9.5" - env: HTTP2_TEST=1 - - node_js: "8.9" + - node_js: "10.11" env: HTTP2_TEST=1 diff --git a/index.js b/index.js index 62e409d..5e685a7 100644 --- a/index.js +++ b/index.js @@ -97,7 +97,7 @@ function typeis (value, types_) { */ function hasbody (req) { - return (ishttp2(req) && (req.stream.readable || !req.stream._readableState.sync)) || + return (ishttp2(req) && !req.stream.endAfterHeaders) || req.headers['transfer-encoding'] !== undefined || !isNaN(req.headers['content-length']) } diff --git a/package.json b/package.json index 5b8e207..32aebcf 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "scripts": { "lint": "eslint --plugin markdown --ext js,md .", "test": "mocha --reporter spec --check-leaks --bail test/", + "test-http2": "HTTP2_TEST=1 mocha --reporter spec --check-leaks --bail test/", "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/", "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/" }, diff --git a/test/test.js b/test/test.js index 52773eb..ab28bc9 100644 --- a/test/test.js +++ b/test/test.js @@ -7,8 +7,6 @@ var Readable if (process.env.HTTP2_TEST) { http2 = require('http2') - request = require('superagent') - request.http2 = true Readable = require('stream').Readable } @@ -216,9 +214,11 @@ describe('typeis.hasBody(req)', function () { assert.strictEqual(typeis.hasBody(req), true) }) - it('should be true when 0', function () { - var req = {headers: {'content-length': '0'}} - assert.strictEqual(typeis.hasBody(req), true) + it('should be true when 0', function (done) { + createZeroLengthBodyRequest('', function (req) { + assert.strictEqual(typeis.hasBody(req), true) + done() + }) }) it('should be false when bogus', function () { @@ -333,9 +333,15 @@ function createRequest (type, callback) { var s = new Readable() s.push('hello') s.push(null) - var req = request.post('localhost:' + server.address().port + '/') - .set('content-type', type || undefined) - s.pipe(req) + + var session = http2.connect('http://localhost:' + server.address().port) + var headers = { + ':path': '/', + ':method': 'post', + 'content-type': type || undefined + } + var request = session.request(headers) + s.pipe(request) }) } else { var req = { @@ -356,9 +362,16 @@ function createBodylessRequest (type, callback) { }) server = server.listen(function () { - request.get('localhost:' + server.address().port + '/') - .set('content-type', type || undefined) - .end() + var session = http2.connect('http://localhost:' + server.address().port) + var headers = { + ':path': '/', + ':method': 'get', + 'content-type': type || '' + } + var option = { + endStream: true + } + session.request(headers, option) }) } else { var req = { @@ -369,3 +382,31 @@ function createBodylessRequest (type, callback) { callback(req) } } + +function createZeroLengthBodyRequest (type, callback) { + if (process.env.HTTP2_TEST) { + var server = http2.createServer(function (req, res) { + callback(req) + server.close() + }) + + server = server.listen(function () { + var session = http2.connect('http://localhost:' + server.address().port) + var headers = { + ':path': '/', + ':method': 'get', + 'content-type': type || '' + } + var request = session.request(headers) + request.end() + }) + } else { + var req = { + headers: { + 'content-type': type || '', + 'content-length': 0 + } + } + callback(req) + } +} From a18f5a6d4d85a2a3b22d1b62e40daef27c854dfd Mon Sep 17 00:00:00 2001 From: sogaani Date: Sat, 22 Sep 2018 00:15:22 +0900 Subject: [PATCH 16/16] lint --- test/test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test.js b/test/test.js index ab28bc9..58830d9 100644 --- a/test/test.js +++ b/test/test.js @@ -1,7 +1,6 @@ var assert = require('assert') var typeis = require('..') -var request var http2 var Readable