From dc873d66e2c649e288190d8aab263085a4ec216f Mon Sep 17 00:00:00 2001 From: Jonathan Ong Date: Tue, 19 Nov 2013 22:40:52 -0800 Subject: [PATCH] docs: add res.lastModified and res.etag among other things --- docs/api/context.md | 23 ++++++++++-------- docs/api/index.md | 19 ++++++++++----- docs/api/request.md | 57 ++++++++++++++++---------------------------- docs/api/response.md | 37 +++++++++++++++++++++------- 4 files changed, 75 insertions(+), 61 deletions(-) diff --git a/docs/api/context.md b/docs/api/context.md index 7efde3e..2f83fc0 100644 --- a/docs/api/context.md +++ b/docs/api/context.md @@ -12,7 +12,7 @@ that they are added at this level, instead of a higher level framework, which would force middlware to re-implement this common functionality. - A `Context` is created _per_ request, and is referenced in middleware + A `Context` is created _per_ request, and is referenced in middleware as the receiver, or the `this` identifier. ## Request aliases @@ -72,7 +72,7 @@ Node's `request` object. ### ctx.res - + Node's `response` object. ### ctx.request @@ -80,7 +80,7 @@ A koa `Request` object. ### ctx.response - + A koa `Response` object. ### ctx.app @@ -93,6 +93,8 @@ - `signed` the cookie requested should be signed + Note: koa uses the [cookies](https://github.com/jed/cookies) module where options are simply passed. + ### ctx.cookies.set(name, value, [options]) Set cookie `name` to `value` with `options`: @@ -104,19 +106,21 @@ - `secure` secure cookie - `httpOnly` server-accessible cookie, __true__ by default -### ctx.error(msg, [status]) + Note: koa uses the [cookies](https://github.com/jed/cookies) module where options are simply passed. + +### ctx.throw(msg, [status]) Helper method to throw an error with a `.status` property that will allow Koa to respond appropriately. The following combinations are allowed: ```js -this.error(403) -this.error('name required', 400) -this.error('something exploded') +this.throw(403) +this.throw('name required', 400) +this.throw('something exploded') ``` - For example `this.error('name required', 400)` is requivalent to: + For example `this.throw('name required', 400)` is requivalent to: ```js var err = new Error('name required'); @@ -125,8 +129,7 @@ throw err; ``` Note that these are user-level errors and are flagged with - `err.expose` meaning the messages are appropriate for + `err.expose` meaning the messages are appropriate for client responses, which is typically not the case for error messages since you do not want to leak failure details. - \ No newline at end of file diff --git a/docs/api/index.md b/docs/api/index.md index 96d071a..2f2d4a1 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -53,6 +53,8 @@ http.createServer(app.callback()).listen(3001); Return a callback function suitable for the `http.createServer()` method to handle a request. + You may also use this callback function to mount your koa app in a + Connect/Express app. ### app.use(function) @@ -62,12 +64,12 @@ http.createServer(app.callback()).listen(3001); ### app.keys= Set signed cookie keys. - + These are passed to [KeyGrip](https://github.com/jed/keygrip), however you may also pass your own `KeyGrip` instance. For example the following are acceptable: -```js +```js app.keys = ['im a newer secret', 'i like turtle']; app.keys = new KeyGrip(['im a newer secret', 'i like turtle'], 'sha256'); ``` @@ -101,14 +103,14 @@ app.on('error', function(err){ If an error in the req/res cycle and it is _not_ possible to respond to the client, the `Context` instance is also passed: ```js -app.on('error', function(err){ - log.error('server error', err); +app.on('error', function(err, ctx){ + log.error('server error', err, ctx); }); ``` When an error occurs _and_ it is still possible to respond to the client, aka no data has been written to the socket, Koa will respond appropriately with a 500 "Internal Server Error". In either case - an app-level "error" is emitted for logging purposes. + an app-level "error" is emitted for logging purposes. ## Notes @@ -118,7 +120,12 @@ app.on('error', function(err){ however expensive requests would benefit from custom handling. For example instead of reading a file into memory and piping it to the client, you may wish to `stat()` and set the `Content-*` header fields - appropriately to bypass the read. + appropriately to bypass the read. + + On a valid __HEAD__ request, you should either set the status code + to anything but `200` or set `this.body = ''`, + otherwise koa will not consider the request "handled" and instead + respond with a 404. ### Socket Errors diff --git a/docs/api/request.md b/docs/api/request.md index c0553c9..eebcfaf 100644 --- a/docs/api/request.md +++ b/docs/api/request.md @@ -22,7 +22,7 @@ ### req.length - Return request Content-Length as a number when present, or undefined. + Return request Content-Length as a number when present, or `undefined`. ### req.type @@ -31,7 +31,7 @@ ```js var ct = this.type; // => "image/png" -``` +``` ### req.url @@ -50,7 +50,7 @@ var ct = this.type; Set request pathname and retain query-string when present. ### req.query - + Get parsed query-string, returning an empty object when no query-string is present. Note that this getter does _not_ support nested parsing. @@ -81,6 +81,14 @@ this.query = { next: '/login' }; Set raw query string. +### req.search + + Get raw query string with the `?`. + +### req.search= + + Set raw query string. + ### req.host Get host void of port number when present. Supports `X-Forwarded-Host` @@ -98,7 +106,7 @@ this.set('ETag', '123'); if (this.fresh) { this.status = 304; return; -} +} // cache is stale // fetch new data @@ -133,21 +141,21 @@ this.body = yield db.find('something'); ### req.subdomains Return subdomains as an array. - + Subdomains are the dot-separated parts of the host before the main domain of the app. By default, the domain of the app is assumed to be the last two parts of the host. This can be changed by setting `app.subdomainOffset`. - + For example, if the domain is "tobi.ferrets.example.com": If `app.subdomainOffset` is not set, this.subdomains is `["ferrets", "tobi"]`. If `app.subdomainOffset` is 3, this.subdomains is `["tobi"]`. ### req.is(type) - + Check if the incoming request contains the `Content-Type` header field, and it contains the give mime `type`. - -```js + +```js // With Content-Type: text/html; charset=utf-8 this.is('html'); this.is('.html'); @@ -171,12 +179,12 @@ this.is('html'); Check if the given `type(s)` is acceptable, returning the best match when true, otherwise `undefined`, in which case you should respond with 406 "Not Acceptable". - + The `type` value may be one or more mime type string such as "application/json", the extension name such as "json", or an array `["json", "html", "text/plain"]`. When a list or array is given the _best_ match, if any is returned. - -```js + +```js // Accept: text/html this.accepts('html'); // => "html" @@ -282,28 +290,3 @@ this.acceptsLanguages(); // => ["es", "pt", "en"] ``` -### req.error(msg, [status]) - - Helper method to throw an error with a `.status` property - that will allow Koa to respond appropriately. The following - combinations are allowed: - -```js -this.error(403) -this.error('name required', 400) -this.error('something exploded') -``` - - For example `this.error('name required', 400)` is requivalent to: - -```js -var err = new Error('name required'); -err.status = 400; -throw err; -``` - - Note that these are user-level errors and are flagged with - `err.expose` meaning the messages are appropriate for - client responses, which is typically not the case for - error messages since you do not want to leak failure - details. diff --git a/docs/api/response.md b/docs/api/response.md index d588a67..450ea4b 100644 --- a/docs/api/response.md +++ b/docs/api/response.md @@ -87,7 +87,7 @@ ### res.length Return response Content-Length as a number when present, or deduce - from `res.body` when possible, or undefined. + from `res.body` when possible, or `undefined`. ### res.body @@ -166,7 +166,7 @@ this.set({ ```js var ct = this.type; // => "image/png" -``` +``` ### res.type= @@ -186,13 +186,13 @@ this.type = 'png'; ### res.redirect(url, [alt]) - Perform a 302 redirect to `url`. - + Perform a [302] redirect to `url`. + The string "back" is special-cased to provide Referrer support, when Referrer is not present `alt` or "/" is used. - -```js + +```js this.redirect('back'); this.redirect('back', '/index.html'); this.redirect('/login'); @@ -200,11 +200,11 @@ this.redirect('http://google.com'); ``` To alter the default status of `302` or the response - body simply re-assign after this call: + body simply assign before and re-assign after this call: ```js -this.redirect('/cart'); this.status = 301; +this.redirect('/cart'); this.body = 'Redirecting to shopping cart'; ``` @@ -219,3 +219,24 @@ this.body = 'Redirecting to shopping cart'; Check if a response header has already been sent. Useful for seeing if the client may be notified on error. +### res.lastModified + + Return the `Last-Modified` header as a `Date`, if it exists. + +### res.lastModified= + + Set the `Last-Modified` header as an appropriate UTC string. + You can either set it as a `Date` or date string. + +```js +this.response.lastModified = new Date(); +``` + +### res.etag= + + Set the ETag of a response including the wrapped `"`s. + Note that there is no corresponding `res.etag` getter. + +```js +this.response.etag = crypto.createHash('md5').update(this.body).digest('hex'); +``` \ No newline at end of file