Skip to content

Commit c82ff2c

Browse files
committed
[examples] updated bodyDecoder middleware example
1 parent d7064f2 commit c82ff2c

File tree

3 files changed

+186
-1
lines changed

3 files changed

+186
-1
lines changed

examples/helpers/store.js

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
2+
//
3+
// just to make these example a little bit interesting,
4+
// make a little key value store with an http interface
5+
// (see couchbd for a grown-up version of this)
6+
//
7+
// API:
8+
// GET /
9+
// retrive list of keys
10+
//
11+
// GET /[url]
12+
// retrive object stored at [url]
13+
// will respond with 404 if there is nothing stored at [url]
14+
//
15+
// POST /[url]
16+
//
17+
// JSON.parse the body and store it under [url]
18+
// will respond 400 (bad request) if body is not valid json.
19+
//
20+
// TODO: cached map-reduce views and auto-magic sharding.
21+
//
22+
var Store = module.exports = function Store () {
23+
this.store = {};
24+
};
25+
26+
Store.prototype = {
27+
get: function (key) {
28+
return this.store[key]
29+
},
30+
set: function (key, value) {
31+
return this.store[key] = value
32+
},
33+
handler:function () {
34+
var store = this
35+
return function (req, res) {
36+
function send (obj, status) {
37+
res.writeHead(200 || status,{'Content-Type': 'application/json'})
38+
res.write(JSON.stringify(obj) + '\n')
39+
res.end()
40+
}
41+
var url = req.url.split('?').shift()
42+
if (url === '/') {
43+
console.log('get index')
44+
return send(Object.keys(store.store))
45+
} else if (req.method == 'GET') {
46+
var obj = store.get (url)
47+
send(obj || {error: 'not_found', url: url}, obj ? 200 : 404)
48+
} else {
49+
//post: buffer body, and parse.
50+
var body = '', obj
51+
req.on('data', function (c) { body += c})
52+
req.on('end', function (c) {
53+
try {
54+
obj = JSON.parse(body)
55+
} catch (err) {
56+
return send (err, 400)
57+
}
58+
store.set(url, obj)
59+
send({ok: true})
60+
})
61+
}
62+
}
63+
}
64+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
bodyDecoder-middleware.js: Basic example of `connect.bodyParser()` middleware in node-http-proxy
3+
4+
Copyright (c) Nodejitsu 2013
5+
6+
Permission is hereby granted, free of charge, to any person obtaining
7+
a copy of this software and associated documentation files (the
8+
"Software"), to deal in the Software without restriction, including
9+
without limitation the rights to use, copy, modify, merge, publish,
10+
distribute, sublicense, and/or sell copies of the Software, and to
11+
permit persons to whom the Software is furnished to do so, subject to
12+
the following conditions:
13+
14+
The above copyright notice and this permission notice shall be
15+
included in all copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24+
25+
*/
26+
27+
var http = require('http'),
28+
connect = require('connect'),
29+
request = require('request'),
30+
colors = require('colors'),
31+
util = require('util'),
32+
Store = require('../helpers/store'),
33+
httpProxy = require('../../lib/http-proxy'),
34+
proxy = httpProxy.createProxyServer({});
35+
36+
http.createServer(new Store().handler()).listen(7531, function () {
37+
util.puts('http '.blue + 'greetings '.green + 'server'.blue + ' started '.green.bold + 'on port '.blue + '7531'.yellow);
38+
//try these commands:
39+
// get index:
40+
// curl localhost:7531
41+
// []
42+
//
43+
// get a doc:
44+
// curl localhost:7531/foo
45+
// {"error":"not_found"}
46+
//
47+
// post an doc:
48+
// curl -X POST localhost:7531/foo -d '{"content": "hello", "type": "greeting"}'
49+
// {"ok":true}
50+
//
51+
// get index (now, not empty)
52+
// curl localhost:7531
53+
// ["/foo"]
54+
//
55+
// get doc
56+
// curl localhost:7531/foo
57+
// {"content": "hello", "type": "greeting"}
58+
59+
//
60+
// now, suppose we wanted to direct all objects where type == "greeting" to a different store
61+
// than where type == "insult"
62+
//
63+
// we can use connect connect-bodyDecoder and some custom logic to send insults to another Store.
64+
65+
//insult server:
66+
67+
http.createServer(new Store().handler()).listen(2600, function () {
68+
util.puts('http '.blue + 'insults '.red + 'server'.blue + ' started '.green.bold + 'on port '.blue + '2600'.yellow);
69+
70+
//greetings -> 7531, insults-> 2600
71+
72+
// now, start a proxy server.
73+
74+
//don't worry about incoming contont type
75+
//bodyParser.parse[''] = JSON.parse
76+
77+
connect.createServer(
78+
//refactor the body parser and re-streamer into a separate package
79+
connect.bodyParser(),
80+
//body parser absorbs the data and end events before passing control to the next
81+
// middleware. if we want to proxy it, we'll need to re-emit these events after
82+
//passing control to the middleware.
83+
require('connect-restreamer')(),
84+
function (req, res) {
85+
//if your posting an obect which contains type: "insult"
86+
//it will get redirected to port 2600.
87+
//normal get requests will go to 7531 nad will not return insults.
88+
var port = (req.body && req.body.type === 'insult' ? 2600 : 7531)
89+
proxy.web(req, res, { target: { host: 'localhost', port: port }});
90+
}
91+
).listen(1337, function () {
92+
util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '1337'.yellow);
93+
//bodyParser needs content-type set to application/json
94+
//if we use request, it will set automatically if we use the 'json:' field.
95+
function post (greeting, type) {
96+
request.post({
97+
url: 'http://localhost:1337/' + greeting,
98+
json: {content: greeting, type: type || "greeting"}
99+
})
100+
}
101+
post("hello")
102+
post("g'day")
103+
post("kiora")
104+
post("houdy")
105+
post("java", "insult")
106+
107+
//now, the insult should have been proxied to 2600
108+
109+
//curl localhost:2600
110+
//["/java"]
111+
112+
//but the greetings will be sent to 7531
113+
114+
//curl localhost:7531
115+
//["/hello","/g%27day","/kiora","/houdy"]
116+
117+
})
118+
})
119+
});

examples/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
"colors": "~0.6.2",
77
"socket.io": "~0.9.16",
88
"socket.io-client": "~0.9.16",
9-
"connect": "~2.11.0"
9+
"connect": "~2.11.0",
10+
"request": "~2.27.0",
11+
"connect-restreamer": "~1.0.0"
1012
}
1113
}

0 commit comments

Comments
 (0)