Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Commit

Permalink
Merge pull request #71 from mulesoft/osprey-security
Browse files Browse the repository at this point in the history
Implement security handler for Osprey
  • Loading branch information
blakeembrey committed Jul 29, 2015
2 parents a6c101b + d6456df commit 39b80a4
Show file tree
Hide file tree
Showing 16 changed files with 1,934 additions and 440 deletions.
345 changes: 315 additions & 30 deletions README.md

Large diffs are not rendered by default.

12 changes: 9 additions & 3 deletions bin/osprey.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env node

var join = require('path').join
var osprey = require('../')

var argv = require('yargs')
Expand All @@ -11,12 +12,17 @@ var argv = require('yargs')
.describe('a', 'Proxy endpoint address')
.describe('f', 'Path to the RAML definition')
.describe('p', 'Port number to bind the proxy')
.describe('docs', 'Serve documentation from a path')
.describe('s', 'Path to a security options file')
.argv

osprey.loadFile(argv.f)
osprey.loadFile(argv.f, {
security: argv.s ? require(join(process.cwd(), argv.s)) : null
})
.then(function (app) {
var proxy = osprey.createProxy(app, argv.a).listen(argv.p)
var proxy = osprey.proxy(app, argv.a).listen(argv.p)

console.log('Osprey is now listening on port ' + proxy.address().port)
})
.catch(function (err) {
console.log(err.stack || err.message || err)
})
88 changes: 42 additions & 46 deletions lib/create-proxy.js → lib/proxy.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
var http = require('http')
var https = require('https')
var router = require('osprey-router')
var arrify = require('arrify')
var querystring = require('querystring')
var is = require('type-is')
var url = require('url')
var FormData = require('form-data')

/**
* Expose `createProxy`.
*/
Expand All @@ -11,28 +20,23 @@ module.exports = createProxy
* @return {Function}
*/
function createProxy (middleware, addresses) {
// Require dependencies inline to avoid overhead when not using the proxy.
var app = require('osprey-router')()
var qs = require('querystring')
var is = require('type-is')
var url = require('url')
var http = require('http')
var https = require('https')
var FormData = require('form-data')

var addrs = array(addresses).map(function (address) {
var app = router()

var addrs = arrify(addresses).map(function (address) {
var addr = url.format(address)

return /^\w+\:/.test(addr) ? addr : 'http://' + addr
return /^\w+\:\/\//.test(addr) ? addr : 'http://' + addr
})

app.use(middleware)

app.use(function proxyAddress (req, res, next) {
var addr = addrs.shift()
var engine = /^https\:/.test(addr) ? https : http
var opts = url.parse(url.resolve(addr, req.url))

// Push the address back onto the array.
addrs.push(addr)

// Proxy request headers (minus now invalid content-length).
opts.method = req.method
opts.headers = req.headers
Expand All @@ -59,19 +63,21 @@ function createProxy (middleware, addresses) {
// Add form data boundary and content length headers.
opts.headers = formData.getHeaders(req.headers)

return formData.pipe(request(opts))
return formData.pipe(proxyRequest(opts, res, next))
})

req.form.on('error', next)

return req.pipe(req.form)
}

var body = ''
var proxy = proxyRequest(opts, res, next)

if (req.body) {
var body = ''

if (is(req, 'urlencoded')) {
body = qs.stringify(req.body)
body = querystring.stringify(req.body)
} else if (is(req, 'json')) {
body = JSON.stringify(req.body)
} else {
Expand All @@ -80,39 +86,35 @@ function createProxy (middleware, addresses) {
}

opts.headers['content-length'] = String(Buffer.byteLength(body))
} else {
body = ''
opts.headers['content-length'] = '0'
proxy.write(body)
proxy.end()
return
}

var proxy = request(opts)
proxy.write(body)
proxy.end()

function request (opts) {
var proxy = engine.request(opts, function (response) {
response.pipe(res)
})

proxy.on('error', next)

return proxy
}

addrs.push(addr)
return req._readableState.ended ? proxy.end() : req.pipe(proxy)
})

return createHttpHandler(app)
}

/**
* To array.
* Create the proxy request.
*
* @param {Array} value
* @return {Array}
* @param {Object} opts
* @param {Stream} writableStream
* @param {Function} cb
* @return {Stream}
*/
function array (value) {
return Array.isArray(value) ? value : [value]
function proxyRequest (opts, writableStream, errCb) {
var engine = opts.protocol === 'https' ? https : http

var proxy = engine.request(opts, function (response) {
response.pipe(writableStream)
})

proxy.on('error', errCb)

return proxy
}

/**
Expand All @@ -124,13 +126,7 @@ function array (value) {
function createHttpHandler (app) {
var finalhandler = require('finalhandler')

function httpHandler (req, res) {
return http.createServer(function (req, res) {
return app(req, res, finalhandler(req, res))
}

httpHandler.listen = function (port, cb) {
return require('http').createServer(httpHandler).listen(port, cb)
}

return httpHandler
})
}
Loading

0 comments on commit 39b80a4

Please sign in to comment.