8
8
const invalidTokenRegex = / [ ^ \^ _ ` a - z A - Z \- 0 - 9 ! # $ % & ' * + . | ~ ] / ;
9
9
const invalidHeaderCharRegex = / [ ^ \t \x20 - \x7e \x80 - \xff ] / ;
10
10
11
- function sanitizeName ( name ) {
12
- name += '' ;
11
+ function validateName ( name ) {
12
+ name = ` ${ name } ` ;
13
13
if ( invalidTokenRegex . test ( name ) ) {
14
14
throw new TypeError ( `${ name } is not a legal HTTP header name` ) ;
15
15
}
16
- return name . toLowerCase ( ) ;
17
16
}
18
17
19
- function sanitizeValue ( value ) {
20
- value += '' ;
18
+ function validateValue ( value ) {
19
+ value = ` ${ value } ` ;
21
20
if ( invalidHeaderCharRegex . test ( value ) ) {
22
21
throw new TypeError ( `${ value } is not a legal HTTP header value` ) ;
23
22
}
24
- return value ;
23
+ }
24
+
25
+ /**
26
+ * Find the key in the map object given a header name.
27
+ *
28
+ * Returns undefined if not found.
29
+ *
30
+ * @param String name Header name
31
+ * @return String|Undefined
32
+ */
33
+ function find ( map , name ) {
34
+ name = name . toLowerCase ( ) ;
35
+ for ( const key in map ) {
36
+ if ( key . toLowerCase ( ) === name ) {
37
+ return key ;
38
+ }
39
+ }
40
+ return undefined ;
25
41
}
26
42
27
43
const MAP = Symbol ( 'map' ) ;
@@ -88,18 +104,20 @@ export default class Headers {
88
104
}
89
105
90
106
/**
91
- * Return first header value given name
107
+ * Return combined header value given name
92
108
*
93
109
* @param String name Header name
94
110
* @return Mixed
95
111
*/
96
112
get ( name ) {
97
- const list = this [ MAP ] [ sanitizeName ( name ) ] ;
98
- if ( ! list ) {
113
+ name = `${ name } ` ;
114
+ validateName ( name ) ;
115
+ const key = find ( this [ MAP ] , name ) ;
116
+ if ( key === undefined ) {
99
117
return null ;
100
118
}
101
119
102
- return list . join ( ', ' ) ;
120
+ return this [ MAP ] [ key ] . join ( ', ' ) ;
103
121
}
104
122
105
123
/**
@@ -110,12 +128,12 @@ export default class Headers {
110
128
* @return Void
111
129
*/
112
130
forEach ( callback , thisArg = undefined ) {
113
- let pairs = getHeaderPairs ( this ) ;
131
+ let pairs = getHeaders ( this ) ;
114
132
let i = 0 ;
115
133
while ( i < pairs . length ) {
116
134
const [ name , value ] = pairs [ i ] ;
117
135
callback . call ( thisArg , value , name , this ) ;
118
- pairs = getHeaderPairs ( this ) ;
136
+ pairs = getHeaders ( this ) ;
119
137
i ++ ;
120
138
}
121
139
}
@@ -128,7 +146,12 @@ export default class Headers {
128
146
* @return Void
129
147
*/
130
148
set ( name , value ) {
131
- this [ MAP ] [ sanitizeName ( name ) ] = [ sanitizeValue ( value ) ] ;
149
+ name = `${ name } ` ;
150
+ value = `${ value } ` ;
151
+ validateName ( name ) ;
152
+ validateValue ( value ) ;
153
+ const key = find ( this [ MAP ] , name ) ;
154
+ this [ MAP ] [ key !== undefined ? key : name ] = [ value ] ;
132
155
}
133
156
134
157
/**
@@ -139,12 +162,16 @@ export default class Headers {
139
162
* @return Void
140
163
*/
141
164
append ( name , value ) {
142
- if ( ! this . has ( name ) ) {
143
- this . set ( name , value ) ;
144
- return ;
165
+ name = `${ name } ` ;
166
+ value = `${ value } ` ;
167
+ validateName ( name ) ;
168
+ validateValue ( value ) ;
169
+ const key = find ( this [ MAP ] , name ) ;
170
+ if ( key !== undefined ) {
171
+ this [ MAP ] [ key ] . push ( value ) ;
172
+ } else {
173
+ this [ MAP ] [ name ] = [ value ] ;
145
174
}
146
-
147
- this [ MAP ] [ sanitizeName ( name ) ] . push ( sanitizeValue ( value ) ) ;
148
175
}
149
176
150
177
/**
@@ -154,7 +181,9 @@ export default class Headers {
154
181
* @return Boolean
155
182
*/
156
183
has ( name ) {
157
- return ! ! this [ MAP ] [ sanitizeName ( name ) ] ;
184
+ name = `${ name } ` ;
185
+ validateName ( name ) ;
186
+ return find ( this [ MAP ] , name ) !== undefined ;
158
187
}
159
188
160
189
/**
@@ -164,7 +193,12 @@ export default class Headers {
164
193
* @return Void
165
194
*/
166
195
delete ( name ) {
167
- delete this [ MAP ] [ sanitizeName ( name ) ] ;
196
+ name = `${ name } ` ;
197
+ validateName ( name ) ;
198
+ const key = find ( this [ MAP ] , name ) ;
199
+ if ( key !== undefined ) {
200
+ delete this [ MAP ] [ key ] ;
201
+ }
168
202
} ;
169
203
170
204
/**
@@ -226,12 +260,14 @@ Object.defineProperties(Headers.prototype, {
226
260
entries : { enumerable : true }
227
261
} ) ;
228
262
229
- function getHeaderPairs ( headers , kind ) {
263
+ function getHeaders ( headers , kind = 'key+value' ) {
230
264
const keys = Object . keys ( headers [ MAP ] ) . sort ( ) ;
231
265
return keys . map (
232
266
kind === 'key' ?
233
- k => [ k ] :
234
- k => [ k , headers . get ( k ) ]
267
+ k => k . toLowerCase ( ) :
268
+ kind === 'value' ?
269
+ k => headers [ MAP ] [ k ] . join ( ', ' ) :
270
+ k => [ k . toLowerCase ( ) , headers [ MAP ] [ k ] . join ( ', ' ) ]
235
271
) ;
236
272
}
237
273
@@ -260,7 +296,7 @@ const HeadersIteratorPrototype = Object.setPrototypeOf({
260
296
kind,
261
297
index
262
298
} = this [ INTERNAL ] ;
263
- const values = getHeaderPairs ( target , kind ) ;
299
+ const values = getHeaders ( target , kind ) ;
264
300
const len = values . length ;
265
301
if ( index >= len ) {
266
302
return {
@@ -269,20 +305,10 @@ const HeadersIteratorPrototype = Object.setPrototypeOf({
269
305
} ;
270
306
}
271
307
272
- const pair = values [ index ] ;
273
308
this [ INTERNAL ] . index = index + 1 ;
274
309
275
- let result ;
276
- if ( kind === 'key' ) {
277
- result = pair [ 0 ] ;
278
- } else if ( kind === 'value' ) {
279
- result = pair [ 1 ] ;
280
- } else {
281
- result = pair ;
282
- }
283
-
284
310
return {
285
- value : result ,
311
+ value : values [ index ] ,
286
312
done : false
287
313
} ;
288
314
}
0 commit comments