forked from deployd/deployd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontext.js
112 lines (99 loc) · 2.98 KB
/
context.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
var internalClient = require('./internal-client')
, debug = require('debug')('context')
, respond = require('doh').createResponder();
/**
* A `Context` gives access to a `req` and `res` object when passed to `resource.handle()`,
* as well as several utility functions and properties.
*
* Properties:
* - **req** `ServerRequest` req
* - **res** `ServerResponse` res
* - **url** `String` The url of the request, stripped of the resource's base path
* - **body** `Object` The body of the request, if the body is JSON or url encoded
* - **query** `Object` The query of the request
*
* @param {Resource} resource
* @param {HttpRequest} req
* @param {HttpResponse} res
* @param {Server} server
*/
function Context(resource, req, res, server) {
var ctx = this;
this.url = req.url.slice(resource.path.length).split('?')[0];
if (this.url.indexOf('/') !== 0) this.url = '/' + this.url;
this.req = req;
this.res = res;
this.body = req.body;
this.query = req.query || {};
this.server = server;
this.session = req.session;
this.method = req && req.method;
// always bind done to this
var done = this.done;
this.done = function() {
done.apply(ctx, arguments);
};
if ((this.query && typeof this.query.$limitRecursion !== 'undefined') || (this.body && typeof this.body.$limitRecursion !== 'undefined')) {
var recursionLimit = this.query.$limitRecursion || this.body.$limitRecursion || 0;
req.stack = req.stack || [];
req.stack.recursionLimit = recursionLimit;
}
this.dpd = internalClient.build(server, req.session, req.stack);
}
/**
* Alias for `ctx.res.end()`
*/
Context.prototype.end = function() {
return this.res.end.apply(this.res, arguments);
};
/**
* Continuous callback sugar for easily calling res.end().
*
* Example:
*
* // instead of
* store.find({foo: 'bar'}, function(err, res) {
* if(err) return res.end(JSON.stringify(err));
* res.end(JSON.stringify(res));
* })
*
* // you can just do
* store.find({foo: 'bar'}, ctx.done);
*
* @param {Error} err
* @param {Object} response
*/
Context.prototype.done = function(err, res) {
var body = res
, type = 'application/json';
// default response
var status = this.res.statusCode = this.res.statusCode || 200;
if(err) {
debug('%j', err);
if(status < 400) this.res.statusCode = 400;
if(err.statusCode) this.res.statusCode = err.statusCode;
respond(err, this.req, this.res);
} else {
if(typeof body == 'object') {
body = JSON.stringify(body);
} else {
type = 'text/html; charset=utf-8';
}
try {
if(status != 204 && status != 304) {
if(body) {
this.res.setHeader('Content-Length', Buffer.isBuffer(body)
? body.length
: Buffer.byteLength(body));
}
this.res.setHeader('Content-Type', type);
this.res.end(body);
} else {
this.res.end();
}
} catch(e) {
console.error(e);
}
}
};
module.exports = Context;