Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
http: add res.req and res.redirect()
Add `res.req` and `res.redirect()` in http server for convenience.

Fixes: #28673
  • Loading branch information
XadillaX committed May 28, 2020
commit 902f5417258ac5adcacb5c03a76b6c9b09e30419
28 changes: 28 additions & 0 deletions doc/api/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -1350,6 +1350,13 @@ deprecated: v13.0.0

See [`response.socket`][].

### `response.req`

* {IncomingMessage|undefined}

If it's a response object in an HTTP request, this object will be it's
`request` object.

### `response.cork()`
<!-- YAML
added:
Expand Down Expand Up @@ -1383,6 +1390,27 @@ If `data` is specified, it is similar in effect to calling
If `callback` is specified, it will be called when the response stream
is finished.

### `response.send()`

This is an alias for `response.end()`.

### `response.redirect(url[, statusCode][, body][, callback])`

* `url` {string}
* `statusCode` {number}
* `body` {string|Buffer}
* `callback` {Function}

Do `30x` redirection for current response.

If no `statusCode` is specified, the redirection status code will be leaved for
302.

if no `body` is specified, the response body will be empty.

If `callback` is specified, it will be called when the response stream is
finished.

### `response.finished`
<!-- YAML
added: v0.0.2
Expand Down
20 changes: 20 additions & 0 deletions lib/_http_outgoing.js
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,26 @@ OutgoingMessage.prototype.end = function end(chunk, encoding, callback) {

return this;
};
OutgoingMessage.prototype.send = OutgoingMessage.prototype.end;

OutgoingMessage.prototype.redirect = function redirect(url, statusCode, body, callback) {
statusCode = 302;
body = '';
callback = undefined;

for (let i = 1; i < arguments.length; i++) {
switch (typeof arguments[i]) {
case 'number': statusCode = arguments[i]; break;
case 'string': body = arguments[i]; break;
case 'function': callback = arguments[i]; break;
default: break;
}
}

this.setHeader('Location', url);
this.statusCode = statusCode;
this.end(body, callback);
};


OutgoingMessage.prototype._finish = function _finish() {
Expand Down
1 change: 1 addition & 0 deletions lib/_http_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,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
62 changes: 62 additions & 0 deletions test/parallel/test-http-response-redirect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const http = require('http');

const server = http.Server(common.mustCall(function(req, res) {
const time = req.url[req.url.length - 1];
switch (time) {
case '0': res.redirect('https://google.com/', 307, 'foo'); break;
case '1': res.redirect('https://alipay.com/', 301); break;
case '2': res.redirect('https://nodejs.org/'); break;
case '3': res.redirect('https://foo.bar/', common.mustCall(function() {}));
}
}, 4));

const finished = [];
server.listen(0, function() {
for (let i = 0; i < 4; i++) {
const time = i.toString();
http.get({ port: this.address().port, path: `/?time=${time}` }, function(res) {
finished.push(res);

let data = '';

res.on('data', function(chunk) {
data += chunk;
});

res.on('end', () => {
switch (time) {
case '0':
assert.strictEqual(data, 'foo');
assert.strictEqual(res.statusCode, 307);
assert.strictEqual(res.headers.location, 'https://google.com/');
break;

case '1':
assert.strictEqual(data, '');
assert.strictEqual(res.statusCode, 301);
assert.strictEqual(res.headers.location, 'https://alipay.com/');
break;

case '2':
assert.strictEqual(data, '');
assert.strictEqual(res.statusCode, 302);
assert.strictEqual(res.headers.location, 'https://nodejs.org/');
break;

case '3':
assert.strictEqual(data, '');
assert.strictEqual(res.statusCode, 302);
assert.strictEqual(res.headers.location, 'https://foo.bar/');
break;

default: break;
}
});

if (finished.length >= 4) server.close();
});
}
});
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