Skip to content

Commit 86e7b0e

Browse files
authored
fix: regression in header case-insensitivity (#188)
1 parent dc08d83 commit 86e7b0e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+157
-50
lines changed

src/helpers/headers.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
module.exports = {
2+
/**
3+
* Given a headers object retrieve the contents of a header out of it via a case-insensitive key.
4+
*
5+
* @param {object} headers
6+
* @param {string} name
7+
* @return {string}
8+
*/
9+
getHeader: (headers, name) => {
10+
return headers[Object.keys(headers).find(k => k.toLowerCase() === name.toLowerCase())]
11+
},
12+
13+
/**
14+
* Given a headers object retrieve a specific header out of it via a case-insensitive key.
15+
*
16+
* @param {object} headers
17+
* @param {string} name
18+
* @return {string}
19+
*/
20+
getHeaderName: (headers, name) => {
21+
return Object.keys(headers).find(k => {
22+
if (k.toLowerCase() === name.toLowerCase()) {
23+
return k
24+
}
25+
})
26+
},
27+
28+
/**
29+
* Determine if a given case-insensitive header exists within a header object.
30+
*
31+
* @param {object} headers
32+
* @param {string} name
33+
* @return {(integer|boolean)}
34+
*/
35+
hasHeader: (headers, name) => {
36+
return Boolean(Object.keys(headers).find(k => k.toLowerCase() === name.toLowerCase()))
37+
}
38+
}

src/index.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ var es = require('event-stream')
77
var MultiPartForm = require('form-data')
88
var qs = require('querystring')
99
var reducer = require('./helpers/reducer')
10+
var helpers = require('./helpers/headers')
1011
var targets = require('./targets')
1112
var url = require('url')
1213
var validate = require('har-validator/lib/async')
@@ -165,7 +166,14 @@ HTTPSnippet.prototype.prepare = function (request) {
165166
}
166167

167168
request.postData.boundary = boundary
168-
request.headersObj['content-type'] = 'multipart/form-data; boundary=' + boundary
169+
170+
// Since headers are case-sensitive we need to see if there's an existing `Content-Type` header that we can
171+
// override.
172+
const contentTypeHeader = helpers.hasHeader(request.headersObj, 'content-type')
173+
? helpers.getHeaderName(request.headersObj, 'content-type')
174+
: 'content-type'
175+
176+
request.headersObj[contentTypeHeader] = 'multipart/form-data; boundary=' + boundary
169177
}
170178
break
171179

src/targets/clojure/clj_http.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
'use strict'
1212

1313
var CodeBuilder = require('../../helpers/code-builder')
14+
var helpers = require('../../helpers/headers')
1415

1516
var Keyword = function (name) {
1617
this.name = name
@@ -101,15 +102,15 @@ module.exports = function (source, options) {
101102
case 'application/json':
102103
params['content-type'] = new Keyword('json')
103104
params['form-params'] = source.postData.jsonObj
104-
delete params.headers['content-type']
105+
delete params.headers[helpers.getHeaderName(params.headers, 'content-type')]
105106
break
106107
case 'application/x-www-form-urlencoded':
107108
params['form-params'] = source.postData.paramsObj
108-
delete params.headers['content-type']
109+
delete params.headers[helpers.getHeaderName(params.headers, 'content-type')]
109110
break
110111
case 'text/plain':
111112
params.body = source.postData.text
112-
delete params.headers['content-type']
113+
delete params.headers[helpers.getHeaderName(params.headers, 'content-type')]
113114
break
114115
case 'multipart/form-data':
115116
params.multipart = source.postData.params.map(function (x) {
@@ -121,14 +122,14 @@ module.exports = function (source, options) {
121122
content: x.value}
122123
}
123124
})
124-
delete params.headers['content-type']
125+
delete params.headers[helpers.getHeaderName(params.headers, 'content-type')]
125126
break
126127
}
127128

128-
switch (params.headers.accept) {
129+
switch (helpers.getHeader(params.headers, 'accept')) {
129130
case 'application/json':
130131
params.accept = new Keyword('json')
131-
delete params.headers.accept
132+
delete params.headers[helpers.getHeaderName(params.headers, 'accept')]
132133
break
133134
}
134135

src/targets/csharp/httpclient.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
'use strict'
22

33
var CodeBuilder = require('../../helpers/code-builder')
4+
var helpers = require('../../helpers/headers')
45

56
function getDecompressionMethods (source) {
6-
var acceptEncoding = source.allHeaders['accept-encoding']
7+
var acceptEncoding = helpers.getHeader(source.allHeaders, 'accept-encoding')
78
if (!acceptEncoding) {
89
return [] // no decompression
910
}
@@ -67,7 +68,7 @@ module.exports = function (source, options) {
6768
code.push(1, 'RequestUri = new Uri("%s"),', source.fullUrl)
6869

6970
var headers = Object.keys(source.allHeaders).filter(function (header) {
70-
switch (header) {
71+
switch (header.toLowerCase()) {
7172
case 'content-type':
7273
case 'content-length':
7374
case 'accept-encoding':

src/targets/csharp/restsharp.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
22

33
var CodeBuilder = require('../../helpers/code-builder')
4+
var helpers = require('../../helpers/headers')
45

56
module.exports = function (source, options) {
67
var code = new CodeBuilder()
@@ -31,7 +32,11 @@ module.exports = function (source, options) {
3132
}
3233

3334
if (source.postData.text) {
34-
code.push('request.AddParameter("%s", %s, ParameterType.RequestBody);', source.allHeaders['content-type'], JSON.stringify(source.postData.text))
35+
code.push(
36+
'request.AddParameter("%s", %s, ParameterType.RequestBody);',
37+
helpers.getHeader(source.allHeaders, 'content-type'),
38+
JSON.stringify(source.postData.text)
39+
)
3540
}
3641

3742
code.push('IRestResponse response = client.Execute(request);')

src/targets/javascript/jquery.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
'use strict'
1212

1313
var CodeBuilder = require('../../helpers/code-builder')
14+
var helpers = require('../../helpers/headers')
1415

1516
module.exports = function (source, options) {
1617
var opts = Object.assign({
@@ -50,9 +51,12 @@ module.exports = function (source, options) {
5051
settings.data = '[form]'
5152

5253
// remove the contentType header
53-
if (~settings.headers['content-type'].indexOf('boundary')) {
54-
delete settings.headers['content-type']
54+
if (helpers.hasHeader(settings.headers, 'content-type')) {
55+
if (helpers.getHeader(settings.headers, 'content-type').indexOf('boundary')) {
56+
delete settings.headers[helpers.getHeaderName(settings.headers, 'content-type')]
57+
}
5558
}
59+
5660
code.blank()
5761
break
5862

src/targets/javascript/xhr.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
'use strict'
1212

1313
var CodeBuilder = require('../../helpers/code-builder')
14+
var helpers = require('../../helpers/headers')
1415

1516
module.exports = function (source, options) {
1617
var opts = Object.assign({
@@ -34,8 +35,10 @@ module.exports = function (source, options) {
3435
})
3536

3637
// remove the contentType header
37-
if (source.allHeaders['content-type'].indexOf('boundary')) {
38-
delete source.allHeaders['content-type']
38+
if (helpers.hasHeader(source.allHeaders, 'content-type')) {
39+
if (helpers.getHeader(source.allHeaders, 'content-type').indexOf('boundary')) {
40+
delete source.allHeaders[helpers.getHeaderName(source.allHeaders, 'content-type')]
41+
}
3942
}
4043

4144
code.blank()

src/targets/php/http2.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
'use strict'
1212

1313
var helpers = require('./helpers')
14+
var headerHelpers = require('../../helpers/headers')
1415
var CodeBuilder = require('../../helpers/code-builder')
1516

1617
module.exports = function (source, options) {
@@ -65,8 +66,10 @@ module.exports = function (source, options) {
6566
)
6667

6768
// remove the contentType header
68-
if (~source.headersObj['content-type'].indexOf('boundary')) {
69-
delete source.headersObj['content-type']
69+
if (headerHelpers.hasHeader(source.headersObj, 'content-type')) {
70+
if (headerHelpers.getHeader(source.headersObj, 'content-type').indexOf('boundary')) {
71+
delete source.headersObj[headerHelpers.getHeaderName(source.headersObj, 'content-type')]
72+
}
7073
}
7174

7275
code.blank()

src/targets/powershell/common.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
22

33
var CodeBuilder = require('../../helpers/code-builder')
4+
var helpers = require('../../helpers/headers')
45

56
module.exports = function (command) {
67
return function (source, options) {
@@ -44,7 +45,7 @@ module.exports = function (command) {
4445
}
4546

4647
if (source.postData.text) {
47-
commandOptions.push("-ContentType '" + source.allHeaders['content-type'] + "'")
48+
commandOptions.push("-ContentType '" + helpers.getHeader(source.allHeaders, 'content-type') + "'")
4849
commandOptions.push("-Body '" + source.postData.text + "'")
4950
}
5051

src/targets/r/httr.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,13 @@ module.exports = function (source, options) {
9393
var accept
9494

9595
for (head in headers) {
96-
if (head === 'accept') {
96+
if (head.toLowerCase() === 'accept') {
9797
accept = ', accept("' + headers[head] + '")'
9898
headerCount = headerCount - 1
99-
} else if (head === 'cookie') {
99+
} else if (head.toLowerCase() === 'cookie') {
100100
cookies = ', set_cookies(`' + headers[head].replace(/;/g, '", `').replace(/` /g, '`').replace(/=/g, '` = "') + '")'
101101
headerCount = headerCount - 1
102-
} else if (head !== 'content-type') {
102+
} else if (head.toLowerCase() !== 'content-type') {
103103
header = header + head.replace('-', '_') + " = '" + headers[head]
104104
if (headerCount > 1) { header = header + "', " }
105105
}

0 commit comments

Comments
 (0)