From 4eb3bd496b5338fa3792fbaf8322c1aaf01ef6c8 Mon Sep 17 00:00:00 2001 From: nakanishi Date: Tue, 4 Dec 2018 15:39:01 +0000 Subject: [PATCH] Add redirectList property in msg of http-request node --- .../@node-red/nodes/core/io/21-httprequest.js | 33 ++++++++---- .../locales/en-US/io/21-httprequest.html | 2 + .../nodes/locales/ja/io/21-httprequest.html | 2 + test/nodes/core/io/21-httprequest_spec.js | 54 +++++++++++++++++++ 4 files changed, 81 insertions(+), 10 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/io/21-httprequest.js b/packages/node_modules/@node-red/nodes/core/io/21-httprequest.js index 594debc2e..adc1afafe 100644 --- a/packages/node_modules/@node-red/nodes/core/io/21-httprequest.js +++ b/packages/node_modules/@node-red/nodes/core/io/21-httprequest.js @@ -131,8 +131,16 @@ module.exports = function(RED) { if (msg.hasOwnProperty('followRedirects')) { opts.followRedirect = msg.followRedirects; } + var redirectList = []; if (!opts.hasOwnProperty('followRedirect') || opts.followRedirect) { opts.followRedirect = function(res) { + var redirectInfo = { + location: res.headers.location, + }; + if (res.headers.hasOwnProperty('set-cookie')) { + redirectInfo.cookies = extractCookies(res.headers['set-cookie']); + } + redirectList.push(redirectInfo); if (this.headers.cookie) { delete this.headers.cookie; } @@ -256,17 +264,9 @@ module.exports = function(RED) { msg.headers = res.headers; msg.responseUrl = res.request.uri.href; msg.payload = body; - + msg.redirectList = redirectList; if (msg.headers.hasOwnProperty('set-cookie')) { - msg.responseCookies = {}; - msg.headers['set-cookie'].forEach(function(c) { - var parsedCookie = cookie.parse(c); - var eq_idx = c.indexOf('='); - var key = c.substr(0, eq_idx).trim() - parsedCookie.value = parsedCookie[key]; - delete parsedCookie[key]; - msg.responseCookies[key] = parsedCookie; - }); + msg.responseCookies = extractCookies(msg.headers['set-cookie']); } msg.headers['x-node-red-request-node'] = hashSum(msg.headers); // msg.url = url; // revert when warning above finally removed @@ -299,6 +299,19 @@ module.exports = function(RED) { this.on("close",function() { node.status({}); }); + + function extractCookies(setCookie) { + var cookies = {}; + setCookie.forEach(function(c) { + var parsedCookie = cookie.parse(c); + var eq_idx = c.indexOf('='); + var key = c.substr(0, eq_idx).trim() + parsedCookie.value = parsedCookie[key]; + delete parsedCookie[key]; + cookies[key] = parsedCookie; + }); + return cookies; + } } RED.nodes.registerType("http request",HTTPRequest,{ diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/io/21-httprequest.html b/packages/node_modules/@node-red/nodes/locales/en-US/io/21-httprequest.html index e981f43b2..aa027da2e 100644 --- a/packages/node_modules/@node-red/nodes/locales/en-US/io/21-httprequest.html +++ b/packages/node_modules/@node-red/nodes/locales/en-US/io/21-httprequest.html @@ -53,6 +53,8 @@ Otherwise, the url of the original request.
responseCookies object
If the response includes cookies, this propery is an object of name/value pairs for each cookie.
+
redirectList array
+
If the request was redirected one or more times, the accumulated information will be added to this property. `location` is the next redirect destination. `cookies` is the cookies returned from the redirect source.

Details

When configured within the node, the URL property can contain mustache-style tags. These allow the diff --git a/packages/node_modules/@node-red/nodes/locales/ja/io/21-httprequest.html b/packages/node_modules/@node-red/nodes/locales/ja/io/21-httprequest.html index 5c98b8be1..d5b072aef 100644 --- a/packages/node_modules/@node-red/nodes/locales/ja/io/21-httprequest.html +++ b/packages/node_modules/@node-red/nodes/locales/ja/io/21-httprequest.html @@ -46,6 +46,8 @@

リクエストの処理時にリダイレクトが発生した場合、このプロパティが最後にリダイレクトされたURLを表します。リダイレクトが起こらなかった場合、最初リクエストのURLを表します。
responseCookies オブジェクト
レスポンスがクッキーを含む場合、このプロパティは各クッキーの名前/値を含むオブジェクトを表します。
+
redirectList 配列
+
リクエストが一回以上リダイレクトされた場合は、このプロパティに情報が蓄積されます。`location`は、リダイレクト先を示します。`cookies`は、リダイレクト元から返されたクッキー情報です。

詳細

ノードの設定でurlプロパティを指定する場合、mustache形式のタグを含めることができます。これにより、URLを入力メッセージの値から構成することができます。例えば、urlがexample.com/{{{topic}}}の場合、msg.topicの値による置き換えを自動的に行います。{{{...}}}表記を使うと、/、&といった文字をmustacheがエスケープするのを抑止できます。

diff --git a/test/nodes/core/io/21-httprequest_spec.js b/test/nodes/core/io/21-httprequest_spec.js index a9ac49c99..1490b8363 100644 --- a/test/nodes/core/io/21-httprequest_spec.js +++ b/test/nodes/core/io/21-httprequest_spec.js @@ -207,6 +207,12 @@ describe('HTTP Request Node', function() { res.cookie('redirectToDifferentDomain','different1'); res.redirect(getDifferentTestURL('/redirectReturn')); }); + testApp.get('/redirectMultipleTimes', function(req, res) { + var key = req.headers.host + req.url; + receivedCookies[key] = req.cookies; + res.cookie('redirectMultipleTimes','multiple1'); + res.redirect(getTestURL('/redirectToDifferentDomain')); + }); testApp.get('/redirectReturn', function(req, res) { var key = req.headers.host + req.url; receivedCookies[key] = req.cookies; @@ -277,6 +283,7 @@ describe('HTTP Request Node', function() { 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.redirectList.length.should.equal(0); done(); } catch(err) { done(err); @@ -1510,6 +1517,10 @@ describe('HTTP Request Node', function() { done(new Error('Invalid cookie(path:/rediectReurn)')); return; } + var redirect1 = msg.redirectList[0]; + redirect1.location.should.equal('http://localhost:'+testPort+'/redirectReturn'); + redirect1.cookies.redirectToSameDomainCookie.Path.should.equals('/'); + redirect1.cookies.redirectToSameDomainCookie.value.should.equals('same1'); done(); }); n1.receive({}); @@ -1533,6 +1544,10 @@ describe('HTTP Request Node', function() { done(new Error('Invalid cookie(path:/rediectReurn)')); return; } + var redirect1 = msg.redirectList[0]; + redirect1.location.should.equal('http://127.0.0.1:'+testPort+'/redirectReturn'); + redirect1.cookies.redirectToDifferentDomain.Path.should.equals('/'); + redirect1.cookies.redirectToDifferentDomain.value.should.equals('different1'); done(); }); n1.receive({}); @@ -1559,6 +1574,10 @@ describe('HTTP Request Node', function() { done(new Error('Invalid cookie(path:/rediectReurn)')); return; } + var redirect1 = msg.redirectList[0]; + redirect1.location.should.equal('http://localhost:'+testPort+'/redirectReturn'); + redirect1.cookies.redirectToSameDomainCookie.Path.should.equals('/'); + redirect1.cookies.redirectToSameDomainCookie.value.should.equals('same1'); done(); }); n1.receive({ @@ -1585,6 +1604,10 @@ describe('HTTP Request Node', function() { done(new Error('Invalid cookie(path:/rediectReurn)')); return; } + var redirect1 = msg.redirectList[0]; + redirect1.location.should.equal('http://127.0.0.1:'+testPort+'/redirectReturn'); + redirect1.cookies.redirectToDifferentDomain.Path.should.equals('/'); + redirect1.cookies.redirectToDifferentDomain.value.should.equals('different1'); done(); }); n1.receive({ @@ -1613,6 +1636,10 @@ describe('HTTP Request Node', function() { done(new Error('Invalid cookie(path:/rediectReurn)')); return; } + var redirect1 = msg.redirectList[0]; + redirect1.location.should.equal('http://localhost:'+testPort+'/redirectReturn'); + redirect1.cookies.redirectToSameDomainCookie.Path.should.equals('/'); + redirect1.cookies.redirectToSameDomainCookie.value.should.equals('same1'); done(); }); n1.receive({ @@ -1639,6 +1666,33 @@ describe('HTTP Request Node', function() { done(new Error('Invalid cookie(path:/rediectReurn)')); return; } + var redirect1 = msg.redirectList[0]; + redirect1.location.should.equal('http://127.0.0.1:'+testPort+'/redirectReturn'); + redirect1.cookies.redirectToDifferentDomain.Path.should.equals('/'); + redirect1.cookies.redirectToDifferentDomain.value.should.equals('different1'); + done(); + }); + n1.receive({ + headers: { cookie: 'requestCookie=request1' } + }); + }); + }); + it('should return all redirect information when redirected multiple times', function(done) { + var flow = [{id:'n1',type:'http request',wires:[['n2']],method:'GET',ret:'obj',url:getTestURL('/redirectMultipleTimes')}, + {id:"n2", type:"helper"}]; + receivedCookies = {}; + helper.load(httpRequestNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + var redirect1 = msg.redirectList[0]; + redirect1.location.should.equal('http://localhost:'+testPort+'/redirectToDifferentDomain'); + redirect1.cookies.redirectMultipleTimes.Path.should.equals('/'); + redirect1.cookies.redirectMultipleTimes.value.should.equals('multiple1'); + var redirect2 = msg.redirectList[1]; + redirect2.location.should.equal('http://127.0.0.1:'+testPort+'/redirectReturn'); + redirect2.cookies.redirectToDifferentDomain.Path.should.equals('/'); + redirect2.cookies.redirectToDifferentDomain.value.should.equals('different1'); done(); }); n1.receive({