Skip to content

Commit

Permalink
http: attach request as res.req
Browse files Browse the repository at this point in the history
This change makes it possible for userland http-related modules
to pave over edge cases that require referencing the original request
when handling a response--making a "Lodash for HTTP" library possible.
More information and research in #28673

Fixes: #28673

PR-URL: #36505
Reviewed-By: Robert Nagy <[email protected]>
  • Loading branch information
ianstormtaylor authored and ruyadorno committed Jan 25, 2021
1 parent a5ffdae commit 70ee7dc
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 0 deletions.
9 changes: 9 additions & 0 deletions doc/api/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -1584,6 +1584,15 @@ Removes a header that's queued for implicit sending.
response.removeHeader('Content-Encoding');
```

### `response.req`
<!-- YAML
added: REPLACEME
-->

* {http.IncomingMessage}

A reference to the original HTTP `request` object.

### `response.sendDate`
<!-- YAML
added: v0.7.5
Expand Down
9 changes: 9 additions & 0 deletions doc/api/http2.md
Original file line number Diff line number Diff line change
Expand Up @@ -3437,6 +3437,15 @@ Removes a header that has been queued for implicit sending.
response.removeHeader('Content-Encoding');
```

### `response.req`
<!-- YAML
added: REPLACEME
-->

* {http2.Http2ServerRequest}

A reference to the original HTTP2 `request` object.

#### `response.sendDate`
<!-- YAML
added: v8.4.0
Expand Down
1 change: 1 addition & 0 deletions lib/_http_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ function ServerResponse(req) {

if (req.method === 'HEAD') this._hasBody = false;

this.req = req;
this.sendDate = true;
this._sent100 = false;
this._expect_continue = false;
Expand Down
4 changes: 4 additions & 0 deletions lib/internal/http2/compat.js
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,10 @@ class Http2ServerResponse extends Stream {
return this[kStream].headersSent;
}

get req() {
return this[kStream][kRequest];
}

get sendDate() {
return this[kState].sendDate;
}
Expand Down
2 changes: 2 additions & 0 deletions test/parallel/test-http-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ const server = http.createServer(function(req, res) {
res.id = request_number;
req.id = request_number++;

assert.strictEqual(res.req, req);

if (req.id === 0) {
assert.strictEqual(req.method, 'GET');
assert.strictEqual(url.parse(req.url).pathname, '/hello');
Expand Down
40 changes: 40 additions & 0 deletions test/parallel/test-http2-compat-serverresponse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use strict';

const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const assert = require('assert');
const h2 = require('http2');

// Http2ServerResponse should expose convenience properties

const server = h2.createServer();
server.listen(0, common.mustCall(function() {
const port = server.address().port;
server.once('request', common.mustCall(function(request, response) {
assert.strictEqual(response.req, request);

response.on('finish', common.mustCall(function() {
process.nextTick(() => {
server.close();
});
}));
response.end();
}));

const url = `http://localhost:${port}`;
const client = h2.connect(url, common.mustCall(function() {
const headers = {
':path': '/foobar',
':method': 'GET',
':scheme': 'http',
':authority': `localhost:${port}`
};
const request = client.request(headers);
request.on('end', common.mustCall(function() {
client.close();
}));
request.end();
request.resume();
}));
}));

0 comments on commit 70ee7dc

Please sign in to comment.