From 9e57664dc130d46fcc17a47301cf8756da339a55 Mon Sep 17 00:00:00 2001 From: Yuki KAN Date: Sun, 3 Apr 2016 16:31:01 +0900 Subject: [PATCH 1/5] Support unix sockets related: https://github.com/visionmedia/superagent/issues/779 --- lib/node/index.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/node/index.js b/lib/node/index.js index 716756291..33490cc6e 100644 --- a/lib/node/index.js +++ b/lib/node/index.js @@ -520,6 +520,14 @@ Request.prototype.request = function(){ if (0 != url.indexOf('http')) url = 'http://' + url; url = parse(url); + // support unix sockets + if (url.host === 'unix') { + // get the socket, path + var unixParts = url.path.split(':'); + options.socketPath = unixParts[0]; + url.pathname = unixParts[1]; + } + // options options.method = this.method; options.port = url.port; From 7653e69a8be236cbb5f41c7a27f1b1322b6d61a1 Mon Sep 17 00:00:00 2001 From: Yuki KAN Date: Mon, 4 Apr 2016 15:00:31 +0900 Subject: [PATCH 2/5] docs for unix sockets support for Node.js related: https://github.com/visionmedia/superagent/issues/779 --- docs/index.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/index.md b/docs/index.md index 57303c363..8a9c3db1b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -45,6 +45,15 @@ 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: http://unix:/SOCKET_PATH:/REQUEST_PATH + request + .get('http://unix:/absolute/path/to/unix.sock:/search') + .end(function(err, res){ + + }); __DELETE__, __HEAD__, __POST__, __PUT__ and other __HTTP__ verbs may also be used, simply change the method name: From 1d022f26e0bc416236d453781e15739b11a15579 Mon Sep 17 00:00:00 2001 From: Yuki KAN Date: Mon, 4 Apr 2016 23:53:05 +0900 Subject: [PATCH 3/5] use https?+unix schema for support unix sockets related: https://github.com/visionmedia/superagent/pull/961 --- lib/node/index.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/node/index.js b/lib/node/index.js index 33490cc6e..b4e0ffcb1 100644 --- a/lib/node/index.js +++ b/lib/node/index.js @@ -521,11 +521,14 @@ Request.prototype.request = function(){ url = parse(url); // support unix sockets - if (url.host === 'unix') { + if (/^https?\+unix:/.test(url.protocol) === true) { + // get the protocol + url.protocol = url.protocol.split('+')[0] + ':'; + // get the socket, path - var unixParts = url.path.split(':'); - options.socketPath = unixParts[0]; - url.pathname = unixParts[1]; + var unixParts = url.path.match(/^([^/]+)(.+)$/); + options.socketPath = unixParts[1].replace(/%2F/g, '/'); + url.pathname = unixParts[2]; } // options From 56afcfc0e022dea1d6a430ab80e76d8cf2cd6a1b Mon Sep 17 00:00:00 2001 From: Yuki KAN Date: Mon, 4 Apr 2016 23:58:34 +0900 Subject: [PATCH 4/5] update docs for unix sockets support for Node.js --- docs/index.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 8a9c3db1b..7c66d81f3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -48,9 +48,10 @@ ES6 promises are supported. Instead of `.end()` you can call `.then()`: The __node__ client supports making requests to [Unix Domain Sockets](http://en.wikipedia.org/wiki/Unix_domain_socket): - // pattern: http://unix:/SOCKET_PATH:/REQUEST_PATH + // pattern: https?+unix://SOCKET_PATH/REQUEST_PATH + // Use `%2F` as `/` in SOCKET_PATH request - .get('http://unix:/absolute/path/to/unix.sock:/search') + .get('http+unix://%2Fabsolute%2Fpath%2Fto%2Funix.sock/search') .end(function(err, res){ }); From 67cb0b38eee00d11c4cab4aba167ef80ea20b7db Mon Sep 17 00:00:00 2001 From: Yuki KAN Date: Tue, 5 Apr 2016 20:53:37 +0900 Subject: [PATCH 5/5] add tests for unix sockets --- test/node/unix-sockets.js | 112 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 test/node/unix-sockets.js 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); + }); + +});