mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Preserve case of user-provided http headers in request node
Fixes #3081
This commit is contained in:
		| @@ -171,8 +171,23 @@ in your Node-RED user directory (${RED.settings.userDir}). | ||||
|                     opts.timeout = msg.requestTimeout; | ||||
|                 } | ||||
|             } | ||||
|             const originalHeaderMap = {}; | ||||
|  | ||||
|             opts.hooks = { | ||||
|                 beforeRequest: [ | ||||
|                     options => { | ||||
|                         // Whilst HTTP headers are meant to be case-insensitive, | ||||
|                         // in the real world, there are servers that aren't so compliant. | ||||
|                         // GOT will lower case all headers given a chance, so we need | ||||
|                         // to restore the case of any headers the user has set. | ||||
|                         Object.keys(options.headers).forEach(h => { | ||||
|                             if (originalHeaderMap[h] && originalHeaderMap[h] !== h) { | ||||
|                                 options.headers[originalHeaderMap[h]] = options.headers[h]; | ||||
|                                 delete options.headers[h]; | ||||
|                             } | ||||
|                         }) | ||||
|                     } | ||||
|                 ], | ||||
|                 beforeRedirect: [ | ||||
|                     (options, response) => { | ||||
|                         let redirectInfo = { | ||||
| @@ -283,7 +298,7 @@ in your Node-RED user directory (${RED.settings.userDir}). | ||||
|                             }) | ||||
|                             if (normalisedHeaders['www-authenticate']) { | ||||
|                                 let authHeader = buildDigestHeader(digestCreds.user,digestCreds.password, options.method, requestUrl.pathname, normalisedHeaders['www-authenticate']) | ||||
|                                 options.headers.authorization = authHeader; | ||||
|                                 options.headers.Authorization = authHeader; | ||||
|                             } | ||||
|                             sentCreds = true; | ||||
|                             return retry(options); | ||||
| @@ -439,6 +454,14 @@ in your Node-RED user directory (${RED.settings.userDir}). | ||||
|                     opts.https = { rejectUnauthorized: msg.rejectUnauthorized }; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Now we have established all of our own headers, take a snapshot | ||||
|             // of their case so we can restore it prior to the request being sent. | ||||
|             if (opts.headers) { | ||||
|                 Object.keys(opts.headers).forEach(h => { | ||||
|                     originalHeaderMap[h.toLowerCase()] = h | ||||
|                 }) | ||||
|             } | ||||
|             got(url,opts).then(res => { | ||||
|                 msg.statusCode = res.statusCode; | ||||
|                 msg.headers = res.headers; | ||||
|   | ||||
| @@ -270,6 +270,16 @@ describe('HTTP Request Node', function() { | ||||
|         testApp.get('/returnError/:code', function(req,res) { | ||||
|             res.status(parseInt(req.params.code)).json({gotError:req.params.code}); | ||||
|         }) | ||||
|  | ||||
|         testApp.get('/rawHeaders', function(req,res) { | ||||
|             const result = {}; | ||||
|             for (let i=0;i<req.rawHeaders.length;i++) { | ||||
|                 result[req.rawHeaders[i]] = req.rawHeaders[i+1] | ||||
|             } | ||||
|             res.json({ | ||||
|                 headers:result | ||||
|             }); | ||||
|         }) | ||||
|         startServer(function(err) { | ||||
|             if (err) { | ||||
|                 done(err); | ||||
| @@ -1348,6 +1358,8 @@ describe('HTTP Request Node', function() { | ||||
|         }); | ||||
|  | ||||
|         it('should convert all HTTP headers into lower case', function(done) { | ||||
|             // This is a bad test. Express lower-cases headers in the `req.headers` object, | ||||
|             // so this is actually testing express, not the original request. | ||||
|             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() { | ||||
| @@ -1369,6 +1381,26 @@ describe('HTTP Request Node', function() { | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         it('should keep HTTP header case as provided by the user', function(done) { | ||||
|             var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/rawHeaders')}, | ||||
|                 {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('X-Test-HEAD', "foo"); | ||||
|                         done(); | ||||
|                     } catch(err) { | ||||
|                         done(err); | ||||
|                     } | ||||
|                 }); | ||||
|                 n1.receive({payload:"foo", headers: { 'Content-Type':'text/plain', "X-Test-HEAD": "foo"}}); | ||||
|             }); | ||||
|         }); | ||||
|         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"}]; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user