diff --git a/docs/index.md b/docs/index.md index 7c1dd794e..64dc73187 100644 --- a/docs/index.md +++ b/docs/index.md @@ -45,6 +45,16 @@ ES6 promises are supported. Instead of `.end()` you can call `.then()`: .end(function(err, res){ }); + + The __node__ client supports making requests to [Unix Domain Sockets](http://en.wikipedia.org/wiki/Unix_domain_socket): + + // pattern: https?+unix://SOCKET_PATH/REQUEST_PATH + // Use `%2F` as `/` in SOCKET_PATH + request + .get('http+unix://%2Fabsolute%2Fpath%2Fto%2Funix.sock/search') + .end(function(err, res){ + + }); __DELETE__, __HEAD__, __PATCH__, __POST__, and __PUT__ requests can also be used, simply change the method name: diff --git a/lib/node/index.js b/lib/node/index.js index e675aa038..df29d11c6 100644 --- a/lib/node/index.js +++ b/lib/node/index.js @@ -531,6 +531,17 @@ Request.prototype.request = function(){ if (0 != url.indexOf('http')) url = 'http://' + url; url = parse(url); + // support unix sockets + if (/^https?\+unix:/.test(url.protocol) === true) { + // get the protocol + url.protocol = url.protocol.split('+')[0] + ':'; + + // get the socket, path + var unixParts = url.path.match(/^([^/]+)(.+)$/); + options.socketPath = unixParts[1].replace(/%2F/g, '/'); + url.pathname = unixParts[2]; + } + // options options.method = this.method; options.port = url.port; diff --git a/test/node/unix-sockets.js b/test/node/unix-sockets.js new file mode 100644 index 000000000..3f036a2c2 --- /dev/null +++ b/test/node/unix-sockets.js @@ -0,0 +1,112 @@ +var request = require('../../') + , express = require('express') + , assert = require('better-assert') + , app = express() + , url = require('url') + , path = require('path') + , http = require('http') + , https = require('https') + , os = require('os') + , fs = require('fs') + , key = fs.readFileSync(__dirname + '/fixtures/key.pem') + , cert = fs.readFileSync(__dirname + '/fixtures/cert.pem') + , httpSockPath = [os.tmpdir(), 'superagent-http.sock'].join('/') + , httpsSockPath = [os.tmpdir(), 'superagent-https.sock'].join('/') + , httpServer + , httpsServer; + +if (process.platform === 'win32') { + return; +} + +app.get('/', function(req, res) { + res.send('root ok!'); +}); + +app.get('/request/path', function(req, res) { + res.send('request path ok!'); +}); + +describe('[unix-sockets] http', function() { + + before(function(done) { + if (fs.existsSync(httpSockPath) === true) { + // try unlink if sock file exists + fs.unlinkSync(httpSockPath); + } + httpServer = http.createServer(app); + httpServer.listen(httpSockPath, done); + }); + + var base = 'http+unix://' + httpSockPath.replace(/\//g, '%2F'); + + describe('request', function() { + it('path: / (root)', function(done) { + request + .get(base + '/') + .end(function(err, res) { + assert(res.ok); + assert('root ok!' === res.text); + done(); + }); + }); + + it('path: /request/path', function(done) { + request + .get(base + '/request/path') + .end(function(err, res) { + assert(res.ok); + assert('request path ok!' === res.text); + done(); + }); + }); + }); + + after(function(done) { + httpServer.close(done); + }); + +}); + +describe('[unix-sockets] https', function() { + + before(function(done) { + if (fs.existsSync(httpsSockPath) === true) { + // try unlink if sock file exists + fs.unlinkSync(httpsSockPath); + } + httpsServer = https.createServer({ key: key, cert: cert }, app); + httpsServer.listen(httpsSockPath, done); + }); + + var base = 'https+unix://' + httpsSockPath.replace(/\//g, '%2F'); + + describe('request', function() { + it('path: / (root)', function(done) { + request + .get(base + '/') + .ca(cert) + .end(function(err, res) { + assert(res.ok); + assert('root ok!' === res.text); + done(); + }); + }); + + it('path: /request/path', function(done) { + request + .get(base + '/request/path') + .ca(cert) + .end(function(err, res) { + assert(res.ok); + assert('request path ok!' === res.text); + done(); + }); + }); + }); + + after(function(done) { + httpsServer.close(done); + }); + +});