From 3e66157472d100b7c80f25cdf17a6b487fbf7e2c Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Sun, 23 Nov 2014 16:00:17 +0800 Subject: [PATCH] ctx.request.href: get full request url, include `protocol`, `host` and `originalUrl` Useful on those scenes need current full request url, like `OAuth`. --- docs/api/context.md | 1 + docs/api/request.md | 9 +++++++++ lib/context.js | 1 + lib/request.js | 15 ++++++++++++++ test/request/href.js | 48 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 74 insertions(+) create mode 100644 test/request/href.js diff --git a/docs/api/context.md b/docs/api/context.md index 390c862..dbc5098 100644 --- a/docs/api/context.md +++ b/docs/api/context.md @@ -148,6 +148,7 @@ koa uses [http-assert](https://github.com/jshttp/http-assert) for assertions. - `ctx.url` - `ctx.url=` - `ctx.originalUrl` + - `ctx.href` - `ctx.path` - `ctx.path=` - `ctx.query` diff --git a/docs/api/request.md b/docs/api/request.md index b105d48..1d39e61 100644 --- a/docs/api/request.md +++ b/docs/api/request.md @@ -39,6 +39,15 @@ Get request original URL. +### request.href + + Get full request URL, include `protocol`, `host` and `url`. + +```js +this.request.href +// => http://example.com/foo/bar?q=1 +``` + ### request.path Get request pathname. diff --git a/lib/context.js b/lib/context.js index 6fe422c..7fa2eeb 100644 --- a/lib/context.js +++ b/lib/context.js @@ -176,6 +176,7 @@ delegate(proto, 'request') .access('query') .access('path') .access('url') + .getter('href') .getter('subdomains') .getter('protocol') .getter('host') diff --git a/lib/request.js b/lib/request.js index 7b7d4e0..d80ef30 100644 --- a/lib/request.js +++ b/lib/request.js @@ -59,6 +59,21 @@ module.exports = { this.req.url = val; }, + /** + * Get full request URL. + * + * @return {String} + * @api public + */ + + get href() { + // support: `GET http://example.com/foo` + if (/^https?:\/\//i.test(this.originalUrl)) { + return this.originalUrl; + } + return this.protocol + '://' + this.host + this.originalUrl; + }, + /** * Get request method. * diff --git a/test/request/href.js b/test/request/href.js new file mode 100644 index 0000000..f427d80 --- /dev/null +++ b/test/request/href.js @@ -0,0 +1,48 @@ + +var Stream = require('stream'); +var http = require('http'); +var koa = require('../../'); +var context = require('../context'); + +describe('ctx.href', function(){ + it('should return the full request url', function(){ + var socket = new Stream.Duplex(); + var req = { + url: '/users/1?next=/dashboard', + headers: { + host: 'localhost' + }, + socket: socket, + __proto__: Stream.Readable.prototype + }; + var ctx = context(req); + ctx.href.should.equal('http://localhost/users/1?next=/dashboard'); + // change it also work + ctx.url = '/foo/users/1?next=/dashboard'; + ctx.href.should.equal('http://localhost/users/1?next=/dashboard'); + }) + + it('should work with `GET http://example.com/foo`', function(done){ + var app = koa() + app.use(function* (){ + this.body = this.href + }) + app.listen(function(){ + var address = this.address() + http.get({ + host: 'localhost', + path: 'http://example.com/foo', + port: address.port + }, function(res){ + res.statusCode.should.equal(200) + var buf = '' + res.setEncoding('utf8') + res.on('data', function(s){ buf += s }) + res.on('end', function(){ + buf.should.equal('http://example.com/foo') + done() + }) + }) + }) + }) +})