GeezerVison is showing github.com — http: fix error check in `Execute()` · nodejs/node@741c5ef
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: src/node_http_parser.cc +28-2Lines changed: 28 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -605,7 +605,28 @@ class Parser : public AsyncWrap, public StreamListener { | 605 | 605 | size_t nparsed = | 606 | 606 | http_parser_execute(&parser_, &settings, data, len); | 607 | 607 |
| 608 | | - Save(); | | 608 | + enum http_errno err = HTTP_PARSER_ERRNO(&parser_); | | 609 | + | | 610 | + // Finish() | | 611 | + if (data == nullptr) { | | 612 | + // `http_parser_execute()` returns either `0` or `1` when `len` is 0 | | 613 | + // (part of the finishing sequence). | | 614 | + CHECK_EQ(len, 0); | | 615 | + switch (nparsed) { | | 616 | + case 0: | | 617 | + err = HPE_OK; | | 618 | + break; | | 619 | + case 1: | | 620 | + nparsed = 0; | | 621 | + break; | | 622 | + default: | | 623 | + UNREACHABLE(); | | 624 | + } | | 625 | + | | 626 | + // Regular Execute() | | 627 | + } else { | | 628 | + Save(); | | 629 | + } | 609 | 630 |
| 610 | 631 | // Unassign the 'buffer_' variable | 611 | 632 | current_buffer_.Clear(); | @@ -619,7 +640,7 @@ class Parser : public AsyncWrap, public StreamListener { | 619 | 640 | Local<Integer> nparsed_obj = Integer::New(env()->isolate(), nparsed); | 620 | 641 | // If there was a parse error in one of the callbacks | 621 | 642 | // TODO(bnoordhuis) What if there is an error on EOF? | 622 | | - if (!parser_.upgrade && nparsed != len) { | | 643 | + if (!parser_.upgrade && err != HPE_OK) { | 623 | 644 | enum http_errno err = HTTP_PARSER_ERRNO(&parser_); | 624 | 645 |
| 625 | 646 | Local<Value> e = Exception::Error(env()->parse_error_string()); | @@ -631,6 +652,11 @@ class Parser : public AsyncWrap, public StreamListener { | 631 | 652 |
| 632 | 653 | return scope.Escape(e); | 633 | 654 | } | | 655 | + | | 656 | + // No return value is needed for `Finish()` | | 657 | + if (data == nullptr) { | | 658 | + return scope.Escape(Local<Value>()); | | 659 | + } | 634 | 660 | return scope.Escape(nparsed_obj); | 635 | 661 | } | 636 | 662 |
| |
Collapse file Copy file name to clipboard +14-1Lines changed: 14 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 1 | 1 | 'use strict'; | 2 | 2 |
| 3 | | -require('../common'); | | 3 | +const common = require('../common'); | 4 | 4 | const assert = require('assert'); | 5 | 5 | const { spawnSync } = require('child_process'); | 6 | 6 | const http = require('http'); | @@ -9,3 +9,16 @@ assert.strictEqual(http.maxHeaderSize, 8 * 1024); | 9 | 9 | const child = spawnSync(process.execPath, ['--max-http-header-size=10', '-p', | 10 | 10 | 'http.maxHeaderSize']); | 11 | 11 | assert.strictEqual(+child.stdout.toString().trim(), 10); | | 12 | + | | 13 | +{ | | 14 | + const server = http.createServer(common.mustNotCall()); | | 15 | + server.listen(0, common.mustCall(() => { | | 16 | + http.get({ | | 17 | + port: server.address().port, | | 18 | + headers: { foo: 'x'.repeat(http.maxHeaderSize + 1) } | | 19 | + }, common.mustCall((res) => { | | 20 | + assert.strictEqual(res.statusCode, 400); | | 21 | + server.close(); | | 22 | + })); | | 23 | + })); | | 24 | +} |
|