From c9e2fce94d1e0cdd1208c97d1fac4fe84f25a171 Mon Sep 17 00:00:00 2001 From: KatsuyaHoshii Date: Tue, 27 Mar 2018 16:09:04 +0900 Subject: [PATCH 1/3] test for httprequest node --- package.json | 3 + test/nodes/core/io/21-httprequest_spec.js | 1502 +++++++++++++++------ 2 files changed, 1122 insertions(+), 383 deletions(-) diff --git a/package.json b/package.json index 2c816569a..8e48f074c 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,7 @@ "bcrypt": "~1.0.3" }, "devDependencies": { + "basic-auth": "^2.0.0", "chromedriver": "^2.33.2", "grunt": "~1.0.1", "grunt-chmod": "~1.1.1", @@ -98,6 +99,8 @@ "grunt-sass": "~2.0.0", "grunt-simple-mocha": "~0.4.1", "grunt-webdriver": "^2.0.3", + "hoek": "^4.2.1", + "http-proxy": "^1.16.2", "istanbul": "0.4.5", "mocha": "~3.4.2", "should": "^8.4.0", diff --git a/test/nodes/core/io/21-httprequest_spec.js b/test/nodes/core/io/21-httprequest_spec.js index 060e8fcad..6387d21a4 100644 --- a/test/nodes/core/io/21-httprequest_spec.js +++ b/test/nodes/core/io/21-httprequest_spec.js @@ -16,17 +16,32 @@ var when = require("when"); var http = require("http"); +var https = require("https"); var should = require("should"); var express = require("express"); var bodyParser = require('body-parser'); var helper = require("../../helper.js"); var httpRequestNode = require("../../../../nodes/core/io/21-httprequest.js"); +var tlsNode = require("../../../../nodes/core/io/05-tls.js"); var hashSum = require("hash-sum"); +var httpProxy = require('http-proxy'); +var cookieParser = require('cookie-parser'); +var RED = require("../../../../red/red.js"); +var fs = require('fs-extra'); +var hoek = require('hoek'); +var auth = require('basic-auth'); describe('HTTP Request Node', function() { var testApp; var testServer; var testPort = 9000; + var testSslServer; + var testSslPort = 9100; + var testProxyServer; + var testProxyPort = 9200; + + //save environment variables + var preEnv; function startServer(done) { testPort += 1; @@ -35,21 +50,101 @@ describe('HTTP Request Node', function() { startServer(done); }); testServer.listen(testPort,function(err) { + testSslPort += 1; + var sslOptions = { + key: fs.readFileSync('test/resources/ssl/server.key'), + cert: fs.readFileSync('test/resources/ssl/server.crt') + /* + Country Name (2 letter code) [AU]: + State or Province Name (full name) [Some-State]: + Locality Name (eg, city) []: + Organization Name (eg, company) [Internet Widgits Pty Ltd]: + Organizational Unit Name (eg, section) []: + Common Name (e.g. server FQDN or YOUR name) []:localhost + Email Address []: + + Please enter the following 'extra' attributes to be sent with your certificate request + A challenge password []: + An optional company name []: + */ + }; + testSslServer = https.createServer(sslOptions,testApp); + testSslServer.listen(testSslPort); + + testProxyPort += 1; + testProxyServer = httpProxy.createProxyServer({target:'http://localhost:' + testPort}); + testProxyServer.on('proxyReq', function(proxyReq, req, res, options) { + proxyReq.setHeader('x-testproxy-header', 'foobar'); + }); + testProxyServer.on('proxyRes', function (proxyRes, req, res, options) { + if (req.url == getTestURL('/proxyAuthenticate')){ + var user = auth.parse(req.headers['proxy-authorization']); + if (!(user.name == "foouser" && user.pass == "barpassword")){ + proxyRes.headers['proxy-authenticate'] = 'BASIC realm="test"'; + proxyRes.statusCode = 407; + } + } + }); + testProxyServer.listen(testProxyPort); done(); - }) + }); } function getTestURL(url) { return "http://localhost:"+testPort+url; } + function getSslTestURL(url) { + return "https://localhost:"+testSslPort+url; + } + + function getSslTestURLWithoutProtocol(url) { + return "localhost:"+testSslPort+url; + } + before(function(done) { + //save environment variables + preEnv = hoek.clone(process.env); + testApp = express(); testApp.use(bodyParser.raw({type:"*/*"})); + testApp.use(cookieParser()); testApp.get('/statusCode204', function(req,res) { res.status(204).end();}) testApp.get('/text', function(req, res){ res.send('hello'); }); + testApp.get('/redirectToText', function(req, res){ res.status(302).set('Location', getTestURL('/text')).end(); }); testApp.get('/json-valid', function(req, res){ res.json({a:1}); }); testApp.get('/json-invalid', function(req, res){ res.set('Content-Type', 'application/json').send("{a:1"); }); + testApp.get('/headersInspect', function(req, res){ res.set('x-test-header', 'bar').send("a"); }); + testApp.get('/timeout', function(req, res){ + setTimeout(function() { + res.send('hello'); + }, 10000); + }); + testApp.get('/checkCookie', function(req, res){ + var value = req.cookies.data; + res.send(value); + }); + testApp.get('/setCookie', function(req, res){ + res.cookie('data','hello'); + res.send(""); + }); + testApp.get('/authenticate', function(req, res){ + var user = auth.parse(req.headers['authorization']); + var result = { + user: user.name, + pass: user.pass, + } + res.json(result); + }); + testApp.get('/proxyAuthenticate', function(req, res){ + var user = auth.parse(req.headers['proxy-authorization']); + var result = { + user: user.name, + pass: user.pass, + headers: req.headers + } + res.json(result); + }); testApp.post('/postInspect', function(req,res) { var result = { body: req.body.toString(), @@ -57,413 +152,1054 @@ describe('HTTP Request Node', function() { } res.json(result); }); + testApp.put('/putInspect', function(req,res) { + var result = { + body: req.body.toString(), + headers: req.headers + } + res.json(result); + }); + testApp.delete('/deleteInspect', function(req,res) { res.status(204).end();}); + testApp.head('/headInspect', function(req,res) { res.status(204).end();}); + testApp.patch('/patchInspect', function(req,res) { + var result = { + body: req.body.toString(), + headers: req.headers + } + res.json(result); + }); + testApp.trace('/traceInspect', function(req,res) { + var result = { + body: req.body.toString(), + headers: req.headers + } + res.json(result); + }); + testApp.options('/*', function(req,res) { + res.status(200).end(); + }); startServer(function() { helper.startServer(done); }); }); after(function() { + //delete environment variables that were not set + if (!preEnv.http_proxy){ + delete process.env.http_proxy; + } + if (!preEnv.HTTP_PROXY){ + delete process.env.HTTP_PROXY; + } + if (!preEnv.no_proxy){ + delete process.env.no_proxy; + } + if (!preEnv.NO_PROXY){ + delete process.env.NO_PROXY; + } + //compare with saved environment variables + process.env.should.be.deepEqual(preEnv); + testServer.close(); + testProxyServer.close(); }); + afterEach(function() { helper.unload(); }); - it('get plain text content', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/text')}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - try { - msg.should.have.property('payload','hello'); - msg.should.have.property('statusCode',200); - msg.should.have.property('headers'); - msg.headers.should.have.property('content-length',''+('hello'.length)); - msg.headers.should.have.property('content-type').which.startWith('text/html'); - done(); - } catch(err) { - done(err); - } + describe('request', function() { + it('should get plain text content', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-length',''+('hello'.length)); + msg.headers.should.have.property('content-type').which.startWith('text/html'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should get JSON content', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/json-valid')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload',{a:1}); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-type').which.startWith('application/json'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should send the payload as the body of a POST as application/json', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.body.should.eql('{"foo":"abcde"}'); + msg.payload.headers.should.have.property('content-type').which.startWith('application/json'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-type').which.startWith('application/json'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:{foo:"abcde"}}); + }); + }); + + it('should send a payload of 0 as the body of a POST as text/plain', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.body.should.eql('0'); + msg.payload.headers.should.have.property('content-length','1'); + msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:0, headers: { 'content-type': 'text/plain'}}); + }); + }); + + it('should send an Object payload as the body of a POST', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.body.should.eql('{"foo":"abcde"}'); + msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-type').which.startWith('application/json'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:{foo:"abcde"}, headers: { 'content-type': 'text/plain'}}); + }); + }); + + it('should send a Buffer as the body of a POST', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.body.should.eql('hello'); + msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-type').which.startWith('application/json'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:new Buffer('hello'), headers: { 'content-type': 'text/plain'}}); + }); + }); + + it('should send form-based request', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.payload.body.should.equal("foo=1%202%203&bar="); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.have.property('content-type','application/x-www-form-urlencoded'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:{foo:'1 2 3', bar:''}, headers: { 'content-type': 'application/x-www-form-urlencoded'}}); + }); + }); + + it('should send PUT request', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"PUT",ret:"obj",url:getTestURL('/putInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.body.should.eql('foo'); + msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-type').which.startWith('application/json'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", headers: { 'content-type': 'text/plain'}}); + }); + }); + + it('should send DELETE request', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"DELETE",ret:"obj",url:getTestURL('/deleteInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload',''); + msg.should.have.property('statusCode',204); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:{foo:"abcde"}}); + }); + }); + + it('should send HEAD request', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"use",ret:"txt",url:getTestURL('/headInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload',''); + msg.should.have.property('statusCode',204); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", method:"head"}); + }); + }); + + it('should send PATCH request', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"PATCH",ret:"obj",url:getTestURL('/patchInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.body.should.eql('foo'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('etag'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", headers: { 'content-type': 'text/plain'}}); + }); + }); + + it('should send OPTIONS request', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"use",ret:"obj",url:getTestURL('/*')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", method:"options"}); + }); + }); + + it('should send TRACE request', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"use",ret:"obj",url:getTestURL('/traceInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + msg.payload.body.should.eql('foo'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", method:"trace", headers: { 'content-type': 'text/plain'}}); + }); + }); + + it('should get Buffer content', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"bin",url:getTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload'); + Buffer.isBuffer(msg.payload).should.be.true(); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-type'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should return plain text when JSON fails to parse', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/json-invalid')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload',"{a:1"); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-type').which.startWith('application/json'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should return the status code', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/statusCode204')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload',''); + msg.should.have.property('statusCode',204); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should use msg.url', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", url:"/foo"}); + }); + }); + + it('should output an error when URL is not provided', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:""}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var inError = false; + n2.on("input", function(msg) { + inError = true; + }); + n1.receive({payload:"foo"}); + setTimeout(function() { + if (inError) { + done(new Error("no url allowed though")) + } else { + done(); + } + },20) + }); + }); + + it('should allow the message to provide the url', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt"}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-length',''+('hello'.length)); + msg.headers.should.have.property('content-type').which.startWith('text/html'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo",url:getTestURL('/text')}); + }); + }); + + it('should allow the url to contain mustache placeholders', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/te{{placeholder}}')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-length',''+('hello'.length)); + msg.headers.should.have.property('content-type').which.startWith('text/html'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo",placeholder:"xt"}); + }); + }); + + it('should allow the url to be missing the http:// prefix', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/text').substring("http://".length)}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-length',''+('hello'.length)); + msg.headers.should.have.property('content-type').which.startWith('text/html'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should reject non http:// schemes - node config', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:"ftp://foo"}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var inError = false; + n2.on("input", function(msg) { + inError = true; + }); + n1.receive({payload:"foo"}); + setTimeout(function() { + if (inError) { + done(new Error("non http(s):// scheme allowed through")) + } else { + done(); + } + },20) + }); + }); + + it('should reject non http:// schemes - msg.url', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt"}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var inError = false; + n2.on("input", function(msg) { + inError = true; + }); + n1.receive({payload:"foo",url:"ftp://foo"}); + setTimeout(function() { + if (inError) { + done(new Error("non http(s):// scheme allowed through")) + } else { + done(); + } + },20) + }); + }); + + it('should use msg.method', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", method:"POST"}); + }); + }); + + it('should allow the message to provide the method', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"use",ret:"txt",url:getTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-length',''+('hello'.length)); + msg.headers.should.have.property('content-type').which.startWith('text/html'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo",method:"get"}); + }); + }); + + it('should receive msg.responseUrl', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.should.have.property('responseUrl', getTestURL('/text')); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should receive msg.responseUrl when redirected', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/redirectToText')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + msg.should.have.property('responseUrl', getTestURL('/text')); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('shuold output an error when request timeout occurred', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/timeout')}, + {id:"n2", type:"helper"}]; + var timeout = RED.settings.httpRequestTimeout; + RED.settings.httpRequestTimeout = 50; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode','ECONNRESET'); + done(); + } catch(err) { + done(err); + } finally { + RED.settings.httpRequestTimeout = timeout; + } + }); + n1.receive({payload:"foo"}); }); - n1.receive({payload:"foo"}); }); }); - it('get JSON content', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/json-valid')}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - try { - msg.should.have.property('payload',{a:1}); - msg.should.have.property('statusCode',200); - msg.should.have.property('headers'); - msg.headers.should.have.property('content-type').which.startWith('application/json'); - done(); - } catch(err) { - done(err); - } + describe('HTTP header', function() { + it('should receive cookie', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/setCookie')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.responseCookies.should.have.property('data'); + msg.responseCookies.data.should.have.property('value','hello'); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should send cookie with string', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/checkCookie')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','abc'); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", cookies:{data:'abc'}}); + }); + }); + + it('should send cookie with obejct data', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/checkCookie')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','abc'); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", cookies:{data:{value:'abc'}}}); + }); + }); + + it('should send cookie by msg.headers', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/checkCookie')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','abc'); + msg.should.have.property('statusCode',200); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", cookies:{boo:'123'}, headers:{'cookie':'data=abc'}}); + }); + }); + + it('should convert all HTTP headers into lower case', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); + msg.payload.headers.should.have.property('content-length', "3"); + msg.payload.headers.should.have.property('if-modified-since','Sun, 01 Jun 2000 00:00:00 GMT'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", headers: { 'Content-Type':'text/plain', 'Content-Length': "3", 'If-Modified-Since':'Sun, 01 Jun 2000 00:00:00 GMT'}}); + }); + }); + + it('should receive HTTP header', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/headersInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.headers.should.have.property('x-test-header','bar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should ignore unmodified x-node-red-request-node header', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.payload.headers.should.have.property('content-type').which.startWith('application/json'); + msg.payload.headers.should.not.have.property('x-node-red-request-node'); + done(); + } catch(err) { + done(err); + } + }); + // Pass in a headers property with an unmodified x-node-red-request-node hash + // This should cause the node to ignore the headers + n1.receive({payload:{foo:"bar"}, headers: { 'content-type': 'text/plain', "x-node-red-request-node":"67690139"}}); + }); + }); + + it('should use modified msg.headers property', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); + msg.payload.headers.should.not.have.property('x-node-red-request-node'); + done(); + } catch(err) { + done(err); + } + }); + // Pass in a headers property with a x-node-red-request-node hash that doesn't match the contents + // This should cause the node to use the headers + n1.receive({payload:{foo:"bar"}, headers: { 'content-type': 'text/plain', "x-node-red-request-node":"INVALID_SUM"}}); }); - n1.receive({payload:"foo"}); }); }); - it('get Buffer content', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"bin",url:getTestURL('/text')}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - try { - msg.should.have.property('payload'); - Buffer.isBuffer(msg.payload).should.be.true(); - msg.should.have.property('statusCode',200); - msg.should.have.property('headers'); - msg.headers.should.have.property('content-type'); - done(); - } catch(err) { - done(err); - } + describe('protocol', function() { + it('should use msg.rejectUnauthorized', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getSslTestURL('/text')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n2 = helper.getNode("n2"); + var n1 = helper.getNode("n1"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-length',''+('hello'.length)); + msg.headers.should.have.property('content-type').which.startWith('text/html'); + msg.should.have.property('responseUrl').which.startWith('https://'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", rejectUnauthorized: false}); + }); + }); + + it('should use tls-config', function(done) { + var flow = [ + {id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getSslTestURLWithoutProtocol('/text'),tls:"n3"}, + {id:"n2", type:"helper"}, + {id:"n3", type:"tls-config", cert:"test/resources/ssl/server.crt", key:"test/resources/ssl/server.key", ca:""}]; + var testNodes = [httpRequestNode, tlsNode]; + helper.load(testNodes, flow, function() { + var n3 = helper.getNode("n3"); + var n2 = helper.getNode("n2"); + var n1 = helper.getNode("n1"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload','hello'); + msg.should.have.property('statusCode',200); + msg.should.have.property('headers'); + msg.headers.should.have.property('content-length',''+('hello'.length)); + msg.headers.should.have.property('content-type').which.startWith('text/html'); + msg.should.have.property('responseUrl').which.startWith('https://'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should use http_proxy', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + var preHttpProxy = process.env.http_proxy; + process.env.http_proxy = "http://localhost:" + testProxyPort; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + process.env.http_proxy = preHttpProxy; + try { + msg.should.have.property('statusCode',200); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should use http_proxy when environment variable is invalid', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + var preHttpProxy = process.env.http_proxy; + process.env.http_proxy = "invalidvalue"; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + process.env.http_proxy = preHttpProxy; + try { + msg.should.have.property('statusCode',200); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.not.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should use HTTP_PROXY', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + var preHttpProxy = process.env.HTTP_PROXY; + process.env.HTTP_PROXY = "http://localhost:" + testProxyPort; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + process.env.HTTP_PROXY = preHttpProxy; + try { + msg.should.have.property('statusCode',200); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should use no_proxy', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + var preHttpProxy = process.env.http_proxy; + var preNoProxy = process.env.no_proxy; + process.env.http_proxy = "http://localhost:" + testProxyPort; + process.env.no_proxy = "foo,localhost"; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + process.env.http_proxy = preHttpProxy; + process.env.no_proxy = preNoProxy; + try { + msg.should.have.property('statusCode',200); + msg.payload.headers.should.not.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should use NO_PROXY', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, + {id:"n2", type:"helper"}]; + var preHttpProxy = process.env.HTTP_PROXY; + var preNoProxy = process.env.NO_PROXY; + process.env.HTTP_PROXY = "http://localhost:" + testProxyPort; + process.env.NO_PROXY = "foo,localhost"; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + process.env.HTTP_PROXY = preHttpProxy; + process.env.NO_PROXY = preNoProxy; + try { + msg.should.have.property('statusCode',200); + msg.payload.headers.should.not.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); }); - n1.receive({payload:"foo"}); }); }); - it('returns plain text when JSON fails to parse', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/json-invalid')}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - try { - msg.should.have.property('payload',"{a:1"); - msg.should.have.property('statusCode',200); - msg.should.have.property('headers'); - msg.headers.should.have.property('content-type').which.startWith('application/json'); - done(); - } catch(err) { - done(err); - } + describe('authentication', function() { + it('should authenticate on server', function(done) { + var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/authenticate')}, + {id:"n2", type:"helper"}]; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.credentials = {user:'userfoo', password:'passwordfoo'} + n2.on("input", function(msg) { + try { + msg.should.have.property('statusCode',200); + msg.payload.should.have.property('user', 'userfoo'); + msg.payload.should.have.property('pass', 'passwordfoo'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }) + + it('should authenticate on proxy server', function(done) { + var flow = [{id:"n1",type:"http request", wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/proxyAuthenticate')}, + {id:"n2", type:"helper"}]; + var preHttpProxy = process.env.http_proxy; + process.env.http_proxy = "http://foouser:barpassword@localhost:" + testProxyPort; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + process.env.http_proxy = preHttpProxy; + try { + msg.should.have.property('statusCode',200); + msg.payload.should.have.property('user', 'foouser'); + msg.payload.should.have.property('pass', 'barpassword'); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); + }); + }); + + it('should output an error when proxy authentication was failed', function(done) { + var flow = [{id:"n1",type:"http request", wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/proxyAuthenticate')}, + {id:"n2", type:"helper"}]; + var preHttpProxy = process.env.http_proxy; + process.env.http_proxy = "http://xxxuser:barpassword@localhost:" + testProxyPort; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + process.env.http_proxy = preHttpProxy; + try { + msg.should.have.property('statusCode',407); + msg.headers.should.have.property('proxy-authenticate', 'BASIC realm="test"'); + msg.payload.should.have.property('headers'); + msg.payload.headers.should.have.property('x-testproxy-header','foobar'); + done(); + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo"}); }); - n1.receive({payload:"foo"}); }); }); - - - it('return the status code', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/statusCode204')}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - try { - msg.should.have.property('payload',''); - msg.should.have.property('statusCode',204); - done(); - } catch(err) { - done(err); - } - }); - n1.receive({payload:"foo"}); - }); - }); - - it('allow the url to be missing the http:// prefix', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/text').substring("http://".length)}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - try { - msg.should.have.property('payload','hello'); - msg.should.have.property('statusCode',200); - msg.should.have.property('headers'); - msg.headers.should.have.property('content-length',''+('hello'.length)); - msg.headers.should.have.property('content-type').which.startWith('text/html'); - done(); - } catch(err) { - done(err); - } - }); - n1.receive({payload:"foo"}); - }); - }); - - it('reject non http:// schemes - node config', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:"ftp://foo"}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - var inError = false; - n2.on("input", function(msg) { - inError = true; - }); - n1.receive({payload:"foo"}); - setTimeout(function() { - if (inError) { - done(new Error("non http(s):// scheme allowed through")) - } else { - done(); - } - },20) - }); - }); - - it('reject non http:// schemes - msg.url', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt"}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - var inError = false; - n2.on("input", function(msg) { - inError = true; - }); - n1.receive({payload:"foo",url:"ftp://foo"}); - setTimeout(function() { - if (inError) { - done(new Error("non http(s):// scheme allowed through")) - } else { - done(); - } - },20) - }); - }); - it('allow the message to provide the url', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt"}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - try { - msg.should.have.property('payload','hello'); - msg.should.have.property('statusCode',200); - msg.should.have.property('headers'); - msg.headers.should.have.property('content-length',''+('hello'.length)); - msg.headers.should.have.property('content-type').which.startWith('text/html'); - done(); - } catch(err) { - done(err); - } - }); - n1.receive({payload:"foo",url:getTestURL('/text')}); - }); - }); - - it('allow the message to provide the method', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"use",ret:"txt",url:getTestURL('/text')}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - try { - msg.should.have.property('payload','hello'); - msg.should.have.property('statusCode',200); - msg.should.have.property('headers'); - msg.headers.should.have.property('content-length',''+('hello'.length)); - msg.headers.should.have.property('content-type').which.startWith('text/html'); - done(); - } catch(err) { - done(err); - } - }); - n1.receive({payload:"foo",method:"get"}); - }); - }); - - it('allow the url to contain mustache placeholders', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getTestURL('/te{{placeholder}}')}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - try { - msg.should.have.property('payload','hello'); - msg.should.have.property('statusCode',200); - msg.should.have.property('headers'); - msg.headers.should.have.property('content-length',''+('hello'.length)); - msg.headers.should.have.property('content-type').which.startWith('text/html'); - done(); - } catch(err) { - done(err); - } - }); - n1.receive({payload:"foo",placeholder:"xt"}); - }); - }); - - it('send the payload as the body of a POST as application/json', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - try { - msg.should.have.property('payload'); - msg.payload.body.should.eql('{"foo":"abcde"}'); - msg.payload.headers.should.have.property('content-type').which.startWith('application/json'); - - msg.should.have.property('statusCode',200); - msg.should.have.property('headers'); - msg.headers.should.have.property('content-type').which.startWith('application/json'); - done(); - } catch(err) { - done(err); - } - }); - n1.receive({payload:{foo:"abcde"}}); - }); - }); - - it('send a payload of 0 as the body of a POST as text/plain', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - try { - msg.should.have.property('payload'); - msg.payload.body.should.eql('0'); - msg.payload.headers.should.have.property('content-length','1'); - msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); - - msg.should.have.property('statusCode',200); - msg.should.have.property('headers'); - done(); - } catch(err) { - done(err); - } - }); - n1.receive({payload:0, headers: { 'content-type': 'text/plain'}}); - }); - }); - - it('send an Object payload as the body of a POST', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - try { - msg.should.have.property('payload'); - msg.payload.body.should.eql('{"foo":"abcde"}'); - msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); - - msg.should.have.property('statusCode',200); - msg.should.have.property('headers'); - msg.headers.should.have.property('content-type').which.startWith('application/json'); - done(); - } catch(err) { - done(err); - } - }); - n1.receive({payload:{foo:"abcde"}, headers: { 'content-type': 'text/plain'}}); - }); - }) - - it('send a Buffer as the body of a POST', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - try { - msg.should.have.property('payload'); - msg.payload.body.should.eql('hello'); - msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); - - msg.should.have.property('statusCode',200); - msg.should.have.property('headers'); - msg.headers.should.have.property('content-type').which.startWith('application/json'); - done(); - } catch(err) { - done(err); - } - }); - n1.receive({payload:new Buffer('hello'), headers: { 'content-type': 'text/plain'}}); - }); - }) - - it('send a Buffer as the body of a POST', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - try { - msg.should.have.property('payload'); - msg.payload.body.should.eql('hello'); - msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); - - msg.should.have.property('statusCode',200); - msg.should.have.property('headers'); - msg.headers.should.have.property('content-type').which.startWith('application/json'); - done(); - } catch(err) { - done(err); - } - }); - n1.receive({payload:new Buffer('hello'), headers: { 'content-type': 'text/plain'}}); - }); - }) - - it('ignores unmodified msg.headers property', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - try { - msg.payload.headers.should.have.property('content-type').which.startWith('application/json'); - msg.payload.headers.should.not.have.property('x-node-red-request-node'); - done(); - } catch(err) { - done(err); - } - }); - // Pass in a headers property with an unmodified x-node-red-request-node hash - // This should cause the node to ignore the headers - n1.receive({payload:{foo:"bar"}, headers: { 'content-type': 'text/plain', "x-node-red-request-node":"67690139"}}); - }); - }) - - it('uses modified msg.headers property', function(done) { - var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, - {id:"n2", type:"helper"}]; - helper.load(httpRequestNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - try { - msg.payload.headers.should.have.property('content-type').which.startWith('text/plain'); - msg.payload.headers.should.not.have.property('x-node-red-request-node'); - done(); - } catch(err) { - done(err); - } - }); - // Pass in a headers property with a x-node-red-request-node hash that doesn't match the contents - // This should cause the node to use the headers - n1.receive({payload:{foo:"bar"}, headers: { 'content-type': 'text/plain', "x-node-red-request-node":"INVALID_SUM"}}); - }); - }) - }); From d2aa3d1868af2f7449b7454e190a0bf103000490 Mon Sep 17 00:00:00 2001 From: KatsuyaHoshii Date: Tue, 27 Mar 2018 17:07:29 +0900 Subject: [PATCH 2/3] Add SSL server certificate --- test/resources/ssl/server.crt | 20 ++++++++++++++++++++ test/resources/ssl/server.key | 27 +++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 test/resources/ssl/server.crt create mode 100644 test/resources/ssl/server.key diff --git a/test/resources/ssl/server.crt b/test/resources/ssl/server.crt new file mode 100644 index 000000000..493afc252 --- /dev/null +++ b/test/resources/ssl/server.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDMDCCAhgCCQDPGPyu5M6ZaDANBgkqhkiG9w0BAQsFADBZMQswCQYDVQQGEwJB +VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 +cyBQdHkgTHRkMRIwEAYDVQQDDAlsb2NhbGhvc3QwIBcNMTgwMzE2MDY0ODU1WhgP +MjExODAyMjAwNjQ4NTVaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0 +YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMM +CWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMifGelM +k/b3HeIj98y9P5jS+Qblqpq7+gsCaL+qglMFmG0QXe6Ordkrh3xeY0uTkaFatwLM +WMzoX60nNdaVjC9U9RlQLK/3nncCveexxRUGtI8VpxN04ivBE/ULhtJeStQFrfyt +LWr1WWf8o8P/EWzZnh0Y1oHc0XqhOPHu9Nfd9kn5nfHNd/xbY8KXa4DkVSJ1lLFK +3t/nSWttchF8zKgNpoQznNGqUTjT28l0sS8fyH76DyRj3Ke6xdNxX2NRUU0PnGFI +RMsBG4Qrzo5xY7lQP7uVVgZUlxryw+NuZuC1PBXaUKJOf6CGwrTq5WB9zF1iBZCs +wD68NvtLd0kHEgECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAfqNOg2v90r5x4lFo +SYmPUoX24gdwHd/mfCzDJksB8n98X1eULYZqqRF2Q7LMkYu/twxfR3EKQX1HZxQY +LpGUYX4ubJdVTy13opJs8B4NkhvRuOAP0+b7RVt4RfuxLX9tYOB98tEbf7Mj0ccq +F4sHi+PMCh64K7rNWECHar0F51yNtNXcxJPMuHZVmj0/U7h6ZxNf+GzdTi8YKmVy +5OHI7xol/II/v3QOi1L+BaEIUkqYODKuQouJVIzu4zX6JRfAaxwjJmliYoJm7OEY +dFMEQUw1Ggsos+KbkGi9mCDbveYpWcZTR8nfPwmx+oJtt47DTHUC3KSdRxgtfjGs +otmVSw== +-----END CERTIFICATE----- diff --git a/test/resources/ssl/server.key b/test/resources/ssl/server.key new file mode 100644 index 000000000..4b8d6a1a5 --- /dev/null +++ b/test/resources/ssl/server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAyJ8Z6UyT9vcd4iP3zL0/mNL5BuWqmrv6CwJov6qCUwWYbRBd +7o6t2SuHfF5jS5ORoVq3AsxYzOhfrSc11pWML1T1GVAsr/eedwK957HFFQa0jxWn +E3TiK8ET9QuG0l5K1AWt/K0tavVZZ/yjw/8RbNmeHRjWgdzReqE48e701932Sfmd +8c13/FtjwpdrgORVInWUsUre3+dJa21yEXzMqA2mhDOc0apRONPbyXSxLx/IfvoP +JGPcp7rF03FfY1FRTQ+cYUhEywEbhCvOjnFjuVA/u5VWBlSXGvLD425m4LU8FdpQ +ok5/oIbCtOrlYH3MXWIFkKzAPrw2+0t3SQcSAQIDAQABAoIBAGmbryUrpZxU24tG +idRiLw9Ax8yEq7lGiMqw2vlCRdZ0VJfdDMVeoE945ZpniXeoV/oLadl0Pq6nCG56 +/JFYKfJkk51eoheDjwxxCgzkfK2j2PqVWF0ao1CLE/ljtvYYouVXlA42D3mFbCoc +SQ0MwVx+dgg1If48gp0+L17T/ll/VOOQumts5UzoKC8YABLL00g5ZL9/jZlVipgl +HfENMPWOfy3q5kSgQqvTWTMdSE6644ryV890mrwcC/RzqQBSNgRh1Lqx3jcXQSdN +x5C19gEK60hZqcvzBkKYudMHUC6I0lcuao1xwBnHUQIVKmLFPZBUIQq3tVar/YUc +d65cJpECgYEA5D9QilQpHxv875wBvBOEbyt9TqDBBN/5JpGQ9sBKpA0eNp3UzrOr ++n0TlyoDZYjkxgNJScS4TpeKde1Hk5j2kkMngjS69dn4G6wmOI79gAOGrCiJd1/I +AWb09KxUKlWBbfKuLHdl1wSMCYQornDdXxYCxhv9sMZKbEJ//tsI420CgYEA4QPf +n/dRAm+6zwNQTWOYWlj5jsG1TilBBCtoRqUqVlrAgR6rS1lgOleHkVrWH0g0Lkmh +9DxWiWuNNXxdU/5zx9AQn/JuHuL8EjDLN5r7idcg2LtEElCkr12y0I9nzS2OOZnj +MTioIh+hghzNuk09NlVJrHi48bJUVL/6Ws7ruGUCgYBT9UJAD+MscVQiI2Wz9A30 +ArBOOu2lSGnSmRsU2PjbzYN+naIJAqhRNK7/HNIxCCD3AYB05SrSpgWliUmZ7ltM +w+0FhTX8d1g/fZx1k4uGCkYAj8y5H39nnKKgWb9/7wH0Gp+c9bJ9XEvSuE1qlVOo +xWTx0JwJ6Xa4yeFhMtrbJQKBgF/FfErjwvEciRBPQsCNoWzi7eUbAYYw/OE/cHSR +HAIBQmoymYnKkrCCTMtLNFPAMaV55ZrEi7iVtFaNhlOXu8PSBSFu1/wBdHRxnC0g +o+s5S1uz6Pc6p72UTeWDBBVKTHyryQ1MJhPQDrgIdm/TLDiR+HeWMnF9C3O++lno +NGAZAoGBAKhsmatxVD9B3jvUDd/CWhXVDSZQECrfJ+Uy1q6b5NO5yMibpIZv14Nj +VT+b2qXoO1wL6htTRJXXNPmrB/JtrLiLg/vxVuA7CPSgot8SDA+/lbRhf1n/SKnD +ECXrEUmq28SgBItbY4vcy5PVEHRvlzqO/LpD6Y7iGNpR7zw9Yk3b +-----END RSA PRIVATE KEY----- From 6cd9ccc37c4194f655494e5fc0ad1c7eef4dbc74 Mon Sep 17 00:00:00 2001 From: KatsuyaHoshii Date: Mon, 23 Apr 2018 14:31:37 +0900 Subject: [PATCH 3/3] Refactor test cases --- package.json | 1 - test/nodes/core/io/21-httprequest_spec.js | 123 ++++++++++++---------- 2 files changed, 67 insertions(+), 57 deletions(-) diff --git a/package.json b/package.json index 8e48f074c..f954e1bc6 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,6 @@ "grunt-sass": "~2.0.0", "grunt-simple-mocha": "~0.4.1", "grunt-webdriver": "^2.0.3", - "hoek": "^4.2.1", "http-proxy": "^1.16.2", "istanbul": "0.4.5", "mocha": "~3.4.2", diff --git a/test/nodes/core/io/21-httprequest_spec.js b/test/nodes/core/io/21-httprequest_spec.js index 6387d21a4..0645f6f42 100644 --- a/test/nodes/core/io/21-httprequest_spec.js +++ b/test/nodes/core/io/21-httprequest_spec.js @@ -28,7 +28,6 @@ var httpProxy = require('http-proxy'); var cookieParser = require('cookie-parser'); var RED = require("../../../../red/red.js"); var fs = require('fs-extra'); -var hoek = require('hoek'); var auth = require('basic-auth'); describe('HTTP Request Node', function() { @@ -41,7 +40,10 @@ describe('HTTP Request Node', function() { var testProxyPort = 9200; //save environment variables - var preEnv; + var preEnvHttpProxyLowerCase; + var preEnvHttpProxyUpperCase; + var preEnvNoProxyLowerCase; + var preEnvNoProxyUpperCase; function startServer(done) { testPort += 1; @@ -102,14 +104,43 @@ describe('HTTP Request Node', function() { return "localhost:"+testSslPort+url; } - before(function(done) { - //save environment variables - preEnv = hoek.clone(process.env); + function saveProxySetting() { + preEnvHttpProxyLowerCase = process.env.http_proxy; + preEnvHttpProxyUpperCase = process.env.HTTP_PROXY; + preEnvNoProxyLowerCase = process.env.no_proxy; + preEnvNoProxyUpperCase = process.env.NO_PROXY; + delete process.env.http_proxy; + delete process.env.HTTP_PROXY; + delete process.env.no_proxy; + delete process.env.NO_PROXY; + } + function restoreProxySetting() { + process.env.http_proxy = preEnvHttpProxyLowerCase; + process.env.HTTP_PROXY = preEnvHttpProxyUpperCase; + // On Windows, if environment variable of NO_PROXY that includes lower cases + // such as No_Proxy is replaced with NO_PROXY. + process.env.no_proxy = preEnvNoProxyLowerCase; + process.env.NO_PROXY = preEnvNoProxyUpperCase; + if (preEnvHttpProxyLowerCase == undefined){ + delete process.env.http_proxy; + } + if (preEnvHttpProxyUpperCase == undefined){ + delete process.env.HTTP_PROXY; + } + if (preEnvNoProxyLowerCase == undefined){ + delete process.env.no_proxy; + } + if (preEnvNoProxyUpperCase == undefined){ + delete process.env.NO_PROXY; + } + } + + before(function(done) { testApp = express(); testApp.use(bodyParser.raw({type:"*/*"})); testApp.use(cookieParser()); - testApp.get('/statusCode204', function(req,res) { res.status(204).end();}) + testApp.get('/statusCode204', function(req,res) { res.status(204).end();}); testApp.get('/text', function(req, res){ res.send('hello'); }); testApp.get('/redirectToText', function(req, res){ res.status(302).set('Location', getTestURL('/text')).end(); }); testApp.get('/json-valid', function(req, res){ res.json({a:1}); }); @@ -133,7 +164,7 @@ describe('HTTP Request Node', function() { var result = { user: user.name, pass: user.pass, - } + }; res.json(result); }); testApp.get('/proxyAuthenticate', function(req, res){ @@ -142,21 +173,21 @@ describe('HTTP Request Node', function() { user: user.name, pass: user.pass, headers: req.headers - } + }; res.json(result); }); testApp.post('/postInspect', function(req,res) { var result = { body: req.body.toString(), headers: req.headers - } + }; res.json(result); }); testApp.put('/putInspect', function(req,res) { var result = { body: req.body.toString(), headers: req.headers - } + }; res.json(result); }); testApp.delete('/deleteInspect', function(req,res) { res.status(204).end();}); @@ -165,14 +196,14 @@ describe('HTTP Request Node', function() { var result = { body: req.body.toString(), headers: req.headers - } + }; res.json(result); }); testApp.trace('/traceInspect', function(req,res) { var result = { body: req.body.toString(), headers: req.headers - } + }; res.json(result); }); testApp.options('/*', function(req,res) { @@ -184,22 +215,6 @@ describe('HTTP Request Node', function() { }); after(function() { - //delete environment variables that were not set - if (!preEnv.http_proxy){ - delete process.env.http_proxy; - } - if (!preEnv.HTTP_PROXY){ - delete process.env.HTTP_PROXY; - } - if (!preEnv.no_proxy){ - delete process.env.no_proxy; - } - if (!preEnv.NO_PROXY){ - delete process.env.NO_PROXY; - } - //compare with saved environment variables - process.env.should.be.deepEqual(preEnv); - testServer.close(); testProxyServer.close(); }); @@ -579,11 +594,11 @@ describe('HTTP Request Node', function() { n1.receive({payload:"foo"}); setTimeout(function() { if (inError) { - done(new Error("no url allowed though")) + done(new Error("no url allowed though")); } else { done(); } - },20) + },20); }); }); @@ -666,11 +681,11 @@ describe('HTTP Request Node', function() { n1.receive({payload:"foo"}); setTimeout(function() { if (inError) { - done(new Error("non http(s):// scheme allowed through")) + done(new Error("non http(s):// scheme allowed through")); } else { done(); } - },20) + },20); }); }); @@ -687,11 +702,11 @@ describe('HTTP Request Node', function() { n1.receive({payload:"foo",url:"ftp://foo"}); setTimeout(function() { if (inError) { - done(new Error("non http(s):// scheme allowed through")) + done(new Error("non http(s):// scheme allowed through")); } else { done(); } - },20) + },20); }); }); @@ -840,7 +855,7 @@ describe('HTTP Request Node', function() { it('should send cookie with obejct data', function(done) { var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/checkCookie')}, - {id:"n2", type:"helper"}]; + {id:"n2", type:"helper"}]; helper.load(httpRequestNode, flow, function() { var n1 = helper.getNode("n1"); var n2 = helper.getNode("n2"); @@ -988,7 +1003,7 @@ describe('HTTP Request Node', function() { var flow = [ {id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"txt",url:getSslTestURLWithoutProtocol('/text'),tls:"n3"}, {id:"n2", type:"helper"}, - {id:"n3", type:"tls-config", cert:"test/resources/ssl/server.crt", key:"test/resources/ssl/server.key", ca:""}]; + {id:"n3", type:"tls-config", cert:"test/resources/ssl/server.crt", key:"test/resources/ssl/server.key", ca:"", verifyservercert:false}]; var testNodes = [httpRequestNode, tlsNode]; helper.load(testNodes, flow, function() { var n3 = helper.getNode("n3"); @@ -1014,13 +1029,13 @@ describe('HTTP Request Node', function() { it('should use http_proxy', function(done) { var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, {id:"n2", type:"helper"}]; - var preHttpProxy = process.env.http_proxy; + saveProxySetting(); process.env.http_proxy = "http://localhost:" + testProxyPort; helper.load(httpRequestNode, flow, function() { var n1 = helper.getNode("n1"); var n2 = helper.getNode("n2"); n2.on("input", function(msg) { - process.env.http_proxy = preHttpProxy; + restoreProxySetting(); try { msg.should.have.property('statusCode',200); msg.payload.should.have.property('headers'); @@ -1037,13 +1052,13 @@ describe('HTTP Request Node', function() { it('should use http_proxy when environment variable is invalid', function(done) { var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, {id:"n2", type:"helper"}]; - var preHttpProxy = process.env.http_proxy; + saveProxySetting(); process.env.http_proxy = "invalidvalue"; helper.load(httpRequestNode, flow, function() { var n1 = helper.getNode("n1"); var n2 = helper.getNode("n2"); n2.on("input", function(msg) { - process.env.http_proxy = preHttpProxy; + restoreProxySetting(); try { msg.should.have.property('statusCode',200); msg.payload.should.have.property('headers'); @@ -1060,13 +1075,13 @@ describe('HTTP Request Node', function() { it('should use HTTP_PROXY', function(done) { var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, {id:"n2", type:"helper"}]; - var preHttpProxy = process.env.HTTP_PROXY; + saveProxySetting(); process.env.HTTP_PROXY = "http://localhost:" + testProxyPort; helper.load(httpRequestNode, flow, function() { var n1 = helper.getNode("n1"); var n2 = helper.getNode("n2"); n2.on("input", function(msg) { - process.env.HTTP_PROXY = preHttpProxy; + restoreProxySetting(); try { msg.should.have.property('statusCode',200); msg.payload.should.have.property('headers'); @@ -1083,16 +1098,14 @@ describe('HTTP Request Node', function() { it('should use no_proxy', function(done) { var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, {id:"n2", type:"helper"}]; - var preHttpProxy = process.env.http_proxy; - var preNoProxy = process.env.no_proxy; + saveProxySetting(); process.env.http_proxy = "http://localhost:" + testProxyPort; process.env.no_proxy = "foo,localhost"; helper.load(httpRequestNode, flow, function() { var n1 = helper.getNode("n1"); var n2 = helper.getNode("n2"); n2.on("input", function(msg) { - process.env.http_proxy = preHttpProxy; - process.env.no_proxy = preNoProxy; + restoreProxySetting(); try { msg.should.have.property('statusCode',200); msg.payload.headers.should.not.have.property('x-testproxy-header','foobar'); @@ -1108,16 +1121,14 @@ describe('HTTP Request Node', function() { it('should use NO_PROXY', function(done) { var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"POST",ret:"obj",url:getTestURL('/postInspect')}, {id:"n2", type:"helper"}]; - var preHttpProxy = process.env.HTTP_PROXY; - var preNoProxy = process.env.NO_PROXY; + saveProxySetting(); process.env.HTTP_PROXY = "http://localhost:" + testProxyPort; process.env.NO_PROXY = "foo,localhost"; helper.load(httpRequestNode, flow, function() { var n1 = helper.getNode("n1"); var n2 = helper.getNode("n2"); n2.on("input", function(msg) { - process.env.HTTP_PROXY = preHttpProxy; - process.env.NO_PROXY = preNoProxy; + restoreProxySetting(); try { msg.should.have.property('statusCode',200); msg.payload.headers.should.not.have.property('x-testproxy-header','foobar'); @@ -1138,7 +1149,7 @@ describe('HTTP Request Node', function() { helper.load(httpRequestNode, flow, function() { var n1 = helper.getNode("n1"); var n2 = helper.getNode("n2"); - n1.credentials = {user:'userfoo', password:'passwordfoo'} + n1.credentials = {user:'userfoo', password:'passwordfoo'}; n2.on("input", function(msg) { try { msg.should.have.property('statusCode',200); @@ -1151,18 +1162,18 @@ describe('HTTP Request Node', function() { }); n1.receive({payload:"foo"}); }); - }) + }); it('should authenticate on proxy server', function(done) { var flow = [{id:"n1",type:"http request", wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/proxyAuthenticate')}, {id:"n2", type:"helper"}]; - var preHttpProxy = process.env.http_proxy; + saveProxySetting(); process.env.http_proxy = "http://foouser:barpassword@localhost:" + testProxyPort; helper.load(httpRequestNode, flow, function() { var n1 = helper.getNode("n1"); var n2 = helper.getNode("n2"); n2.on("input", function(msg) { - process.env.http_proxy = preHttpProxy; + restoreProxySetting(); try { msg.should.have.property('statusCode',200); msg.payload.should.have.property('user', 'foouser'); @@ -1181,13 +1192,13 @@ describe('HTTP Request Node', function() { it('should output an error when proxy authentication was failed', function(done) { var flow = [{id:"n1",type:"http request", wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/proxyAuthenticate')}, {id:"n2", type:"helper"}]; - var preHttpProxy = process.env.http_proxy; + saveProxySetting(); process.env.http_proxy = "http://xxxuser:barpassword@localhost:" + testProxyPort; helper.load(httpRequestNode, flow, function() { var n1 = helper.getNode("n1"); var n2 = helper.getNode("n2"); n2.on("input", function(msg) { - process.env.http_proxy = preHttpProxy; + restoreProxySetting(); try { msg.should.have.property('statusCode',407); msg.headers.should.have.property('proxy-authenticate', 'BASIC realm="test"');