Skip to content

Commit

Permalink
fix: Invoke missing callback.
Browse files Browse the repository at this point in the history
  • Loading branch information
ShogunPanda committed Sep 13, 2023
1 parent bc758af commit f09752a
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 25 deletions.
58 changes: 33 additions & 25 deletions src/llhttp/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ export class HTTP {
1: this.testFlags(FLAGS.TRAILING, {
1: this.invokePausable('on_chunk_complete',
ERROR.CB_CHUNK_COMPLETE, 'message_done'),
}).otherwise(n('headers_done')),
}).otherwise(this.headersCompleted()),
}, onInvalidHeaderFieldChar),
)
.otherwise(span.headerField.start(n('header_field')));
Expand Down Expand Up @@ -833,13 +833,10 @@ export class HTTP {
}, span.headerValue.start(n('header_value_start'))))
.otherwise(this.setHeaderFlags(onHeaderValueComplete));

// Set `upgrade` if needed
const beforeHeadersComplete = p.invoke(callback.beforeHeadersComplete);

const checkTrailing = this.testFlags(FLAGS.TRAILING, {
1: this.invokePausable('on_chunk_complete',
ERROR.CB_CHUNK_COMPLETE, 'message_done'),
}).otherwise(beforeHeadersComplete);
}).otherwise(this.headersCompleted());

n('headers_almost_done')
.match('\n', checkTrailing)
Expand All @@ -848,26 +845,6 @@ export class HTTP {
1: checkTrailing,
}, p.error(ERROR.STRICT, 'Expected LF after headers')));

/* Here we call the headers_complete callback. This is somewhat
* different than other callbacks because if the user returns 1, we
* will interpret that as saying that this message has no body. This
* is needed for the annoying case of receiving a response to a HEAD
* request.
*
* We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so
* we have to simulate it by handling a change in errno below.
*/
const onHeadersComplete = p.invoke(callback.onHeadersComplete, {
0: n('headers_done'),
1: this.setFlag(FLAGS.SKIPBODY, 'headers_done'),
2: this.update('upgrade', 1,
this.setFlag(FLAGS.SKIPBODY, 'headers_done')),
[ERROR.PAUSED]: this.pause('Paused by on_headers_complete',
'headers_done'),
}, p.error(ERROR.CB_HEADERS_COMPLETE, 'User callback error'));

beforeHeadersComplete.otherwise(onHeadersComplete);

const upgradePause = p.pause(ERROR.PAUSED_UPGRADE,
'Pause on CONNECT/Upgrade');

Expand Down Expand Up @@ -1106,6 +1083,37 @@ export class HTTP {
));
}

private headersCompleted(): Node {
const p = this.llparse;
const callback = this.callback;
const n = (name: string): Match => this.node<Match>(name);

// Set `upgrade` if needed
const beforeHeadersComplete = p.invoke(callback.beforeHeadersComplete);

/* Here we call the headers_complete callback. This is somewhat
* different than other callbacks because if the user returns 1, we
* will interpret that as saying that this message has no body. This
* is needed for the annoying case of receiving a response to a HEAD
* request.
*
* We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so
* we have to simulate it by handling a change in errno below.
*/
const onHeadersComplete = p.invoke(callback.onHeadersComplete, {
0: n('headers_done'),
1: this.setFlag(FLAGS.SKIPBODY, 'headers_done'),
2: this.update('upgrade', 1,
this.setFlag(FLAGS.SKIPBODY, 'headers_done')),
[ERROR.PAUSED]: this.pause('Paused by on_headers_complete',
'headers_done'),
}, p.error(ERROR.CB_HEADERS_COMPLETE, 'User callback error'));

beforeHeadersComplete.otherwise(onHeadersComplete);

return beforeHeadersComplete;
}

private node<T extends Node>(name: string | T): T {
if (name instanceof Node) {
return name;
Expand Down
1 change: 1 addition & 0 deletions test/request/invalid.md
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@ off=66 len=3 span[header_field]="Bar"
off=70 header_field complete
off=71 len=3 span[header_value]="def"
off=75 header_value complete
off=76 headers complete method=3 v=1/1 flags=208 content_length=0
off=78 chunk header len=1
off=78 len=1 span[body]="A"
off=80 chunk complete
Expand Down
2 changes: 2 additions & 0 deletions test/response/invalid.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ off=16 len=14 span[header_field]="Content-Length"
off=31 header_field complete
off=32 len=1 span[header_value]="0"
off=34 header_value complete
off=35 headers complete status=200 v=1/1 flags=20 content_length=0
off=35 message complete
```

Expand Down Expand Up @@ -277,6 +278,7 @@ off=25 len=3 span[header_field]="Bar"
off=29 header_field complete
off=30 len=3 span[header_value]="def"
off=34 header_value complete
off=35 headers complete status=200 v=1/1 flags=0 content_length=0
off=35 len=4 span[body]="BODY"
off=39 len=1 span[body]=lf
off=40 len=1 span[body]="\"
Expand Down
1 change: 1 addition & 0 deletions test/response/sample.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ off=55 len=10 span[header_field]="Connection"
off=66 header_field complete
off=67 len=5 span[header_value]="close"
off=73 header_value complete
off=74 headers complete status=200 v=1/1 flags=2 content_length=0
off=74 len=51 span[body]="these headers are from http://news.ycombinator.com/"
```

Expand Down

0 comments on commit f09752a

Please sign in to comment.