OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of dart.io; | 5 part of dart.io; |
6 | 6 |
7 class _HttpHeaders implements HttpHeaders { | 7 class _HttpHeaders implements HttpHeaders { |
8 final Map<String, List<String>> _headers; | 8 final Map<String, List<String>> _headers; |
9 final String protocolVersion; | 9 final String protocolVersion; |
10 | 10 |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
241 } else { | 241 } else { |
242 return null; | 242 return null; |
243 } | 243 } |
244 } | 244 } |
245 | 245 |
246 void set contentType(ContentType contentType) { | 246 void set contentType(ContentType contentType) { |
247 _checkMutable(); | 247 _checkMutable(); |
248 _set(HttpHeaders.CONTENT_TYPE, contentType.toString()); | 248 _set(HttpHeaders.CONTENT_TYPE, contentType.toString()); |
249 } | 249 } |
250 | 250 |
251 static void _addContentLength(_HttpHeaders headers, String name, value) { | 251 // [name] must be a lower-case version of the name. |
252 void _add(String name, value) { | |
253 assert(name == name.toLowerCase()); | |
254 // Use the length as index on what method to call. This is notable | |
255 // faster than computing hash and looking up in a hash-map. | |
256 switch (name.length) { | |
257 case 4: | |
258 if (HttpHeaders.DATE == name) { | |
259 _addDate(name, value); | |
260 return; | |
261 } | |
262 if (HttpHeaders.HOST == name) { | |
263 _addHost(name, value); | |
264 return; | |
265 } | |
266 break; | |
267 case 7: | |
268 if (HttpHeaders.EXPIRES == name) { | |
269 _addExpires(name, value); | |
270 return; | |
271 } | |
272 break; | |
273 case 10: | |
274 if (HttpHeaders.CONNECTION == name) { | |
275 _addConnection(name, value); | |
276 return; | |
277 } | |
278 break; | |
279 case 12: | |
280 if (HttpHeaders.CONTENT_TYPE == name) { | |
281 _addContentType(name, value); | |
282 return; | |
283 } | |
284 break; | |
285 case 14: | |
286 if (HttpHeaders.CONTENT_LENGTH == name) { | |
287 _addContentLength(name, value); | |
288 return; | |
289 } | |
290 break; | |
291 case 17: | |
292 if (HttpHeaders.TRANSFER_ENCODING == name) { | |
293 _addTransferEncoding(name, value); | |
294 return; | |
295 } | |
296 if (HttpHeaders.IF_MODIFIED_SINCE == name) { | |
297 _addIfModifiedSince(name, value); | |
298 return; | |
299 } | |
300 } | |
301 _addValue(name, value); | |
302 } | |
303 | |
304 void _addContentLength(String name, value) { | |
Lasse Reichstein Nielsen
2014/04/23 12:31:06
Do you need to pass the name?
It should always be
Anders Johnsen
2014/04/23 12:33:00
Yes, but as we use it a lot (see exception), it's
| |
252 if (value is int) { | 305 if (value is int) { |
253 headers.contentLength = value; | 306 contentLength = value; |
254 } else if (value is String) { | 307 } else if (value is String) { |
255 headers.contentLength = int.parse(value); | 308 contentLength = int.parse(value); |
256 } else { | 309 } else { |
257 throw new HttpException("Unexpected type for header named $name"); | 310 throw new HttpException("Unexpected type for header named $name"); |
258 } | 311 } |
259 } | 312 } |
260 | 313 |
261 static void _addTransferEncoding(_HttpHeaders headers, String name, value) { | 314 void _addTransferEncoding(String name, value) { |
Lasse Reichstein Nielsen
2014/04/23 12:31:06
Consider sorting functions by name?
| |
262 if (value == "chunked") { | 315 if (value == "chunked") { |
263 headers.chunkedTransferEncoding = true; | 316 chunkedTransferEncoding = true; |
264 } else { | 317 } else { |
265 headers._addValue(HttpHeaders.TRANSFER_ENCODING, value); | 318 _addValue(HttpHeaders.TRANSFER_ENCODING, value); |
266 } | 319 } |
267 } | 320 } |
268 | 321 |
269 static void _addDate(_HttpHeaders headers, String name, value) { | 322 void _addDate(String name, value) { |
270 if (value is DateTime) { | 323 if (value is DateTime) { |
271 headers.date = value; | 324 date = value; |
272 } else if (value is String) { | 325 } else if (value is String) { |
273 headers._set(HttpHeaders.DATE, value); | 326 _set(HttpHeaders.DATE, value); |
274 } else { | 327 } else { |
275 throw new HttpException("Unexpected type for header named $name"); | 328 throw new HttpException("Unexpected type for header named $name"); |
276 } | 329 } |
277 } | 330 } |
278 | 331 |
279 static void _addExpires(_HttpHeaders headers, String name, value) { | 332 void _addExpires(String name, value) { |
280 if (value is DateTime) { | 333 if (value is DateTime) { |
281 headers.expires = value; | 334 expires = value; |
282 } else if (value is String) { | 335 } else if (value is String) { |
283 headers._set(HttpHeaders.EXPIRES, value); | 336 _set(HttpHeaders.EXPIRES, value); |
284 } else { | 337 } else { |
285 throw new HttpException("Unexpected type for header named $name"); | 338 throw new HttpException("Unexpected type for header named $name"); |
286 } | 339 } |
287 } | 340 } |
288 | 341 |
289 static void _addIfModifiedSince(_HttpHeaders headers, String name, value) { | 342 void _addIfModifiedSince(String name, value) { |
290 if (value is DateTime) { | 343 if (value is DateTime) { |
291 headers.ifModifiedSince = value; | 344 ifModifiedSince = value; |
292 } else if (value is String) { | 345 } else if (value is String) { |
293 headers._set(HttpHeaders.IF_MODIFIED_SINCE, value); | 346 _set(HttpHeaders.IF_MODIFIED_SINCE, value); |
294 } else { | 347 } else { |
295 throw new HttpException("Unexpected type for header named $name"); | 348 throw new HttpException("Unexpected type for header named $name"); |
296 } | 349 } |
297 } | 350 } |
298 | 351 |
299 static void _addHost(_HttpHeaders headers, String name, value) { | 352 void _addHost(String name, value) { |
300 if (value is String) { | 353 if (value is String) { |
301 int pos = value.indexOf(":"); | 354 int pos = value.indexOf(":"); |
302 if (pos == -1) { | 355 if (pos == -1) { |
303 headers._host = value; | 356 _host = value; |
304 headers._port = HttpClient.DEFAULT_HTTP_PORT; | 357 _port = HttpClient.DEFAULT_HTTP_PORT; |
305 } else { | 358 } else { |
306 if (pos > 0) { | 359 if (pos > 0) { |
307 headers._host = value.substring(0, pos); | 360 _host = value.substring(0, pos); |
308 } else { | 361 } else { |
309 headers._host = null; | 362 _host = null; |
310 } | 363 } |
311 if (pos + 1 == value.length) { | 364 if (pos + 1 == value.length) { |
312 headers._port = HttpClient.DEFAULT_HTTP_PORT; | 365 _port = HttpClient.DEFAULT_HTTP_PORT; |
313 } else { | 366 } else { |
314 try { | 367 try { |
315 headers._port = int.parse(value.substring(pos + 1)); | 368 _port = int.parse(value.substring(pos + 1)); |
316 } on FormatException catch (e) { | 369 } on FormatException catch (e) { |
317 headers._port = null; | 370 _port = null; |
318 } | 371 } |
319 } | 372 } |
320 } | 373 } |
321 headers._set(HttpHeaders.HOST, value); | 374 _set(HttpHeaders.HOST, value); |
322 } else { | 375 } else { |
323 throw new HttpException("Unexpected type for header named $name"); | 376 throw new HttpException("Unexpected type for header named $name"); |
324 } | 377 } |
325 } | 378 } |
326 | 379 |
327 static void _addConnection(_HttpHeaders headers, String name, value) { | 380 void _addConnection(String name, value) { |
328 var lowerCaseValue = value.toLowerCase(); | 381 var lowerCaseValue = value.toLowerCase(); |
329 if (lowerCaseValue == 'close') { | 382 if (lowerCaseValue == 'close') { |
330 headers._persistentConnection = false; | 383 _persistentConnection = false; |
331 } else if (lowerCaseValue == 'keep-alive') { | 384 } else if (lowerCaseValue == 'keep-alive') { |
332 headers._persistentConnection = true; | 385 _persistentConnection = true; |
333 } | |
334 headers._addValue(name, value); | |
335 } | |
336 | |
337 static void _addContentType(_HttpHeaders headers, String name, value) { | |
338 headers._set(HttpHeaders.CONTENT_TYPE, value); | |
339 } | |
340 | |
341 // TODO(ajohnsen): Change to const map, once const maps are faster. | |
342 static final _addMap = { | |
343 HttpHeaders.CONTENT_LENGTH: _addContentLength, | |
344 HttpHeaders.TRANSFER_ENCODING: _addTransferEncoding, | |
345 HttpHeaders.DATE: _addDate, | |
346 HttpHeaders.EXPIRES: _addExpires, | |
347 HttpHeaders.IF_MODIFIED_SINCE: _addIfModifiedSince, | |
348 HttpHeaders.HOST: _addHost, | |
349 HttpHeaders.CONNECTION: _addConnection, | |
350 HttpHeaders.CONTENT_TYPE: _addContentType | |
351 }; | |
352 | |
353 // [name] must be a lower-case version of the name. | |
354 void _add(String name, value) { | |
355 assert(name == name.toLowerCase()); | |
356 var method = _addMap[name]; | |
357 if (method != null) { | |
358 method(this, name, value); | |
359 return; | |
360 } | 386 } |
361 _addValue(name, value); | 387 _addValue(name, value); |
362 } | 388 } |
363 | 389 |
390 void _addContentType(String name, value) { | |
391 _set(HttpHeaders.CONTENT_TYPE, value); | |
392 } | |
393 | |
364 void _addValue(String name, Object value) { | 394 void _addValue(String name, Object value) { |
365 List<String> values = _headers[name]; | 395 List<String> values = _headers[name]; |
366 if (values == null) { | 396 if (values == null) { |
367 values = new List<String>(); | 397 values = new List<String>(); |
368 _headers[name] = values; | 398 _headers[name] = values; |
369 } | 399 } |
370 if (value is DateTime) { | 400 if (value is DateTime) { |
371 values.add(HttpDate.format(value)); | 401 values.add(HttpDate.format(value)); |
372 } else { | 402 } else { |
373 values.add(value.toString()); | 403 values.add(value.toString()); |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
906 void clear() { | 936 void clear() { |
907 throw new UnsupportedError("Cannot modify an unmodifiable map"); | 937 throw new UnsupportedError("Cannot modify an unmodifiable map"); |
908 } | 938 } |
909 void forEach(void f(K key, V value)) => _map.forEach(f); | 939 void forEach(void f(K key, V value)) => _map.forEach(f); |
910 Iterable<K> get keys => _map.keys; | 940 Iterable<K> get keys => _map.keys; |
911 Iterable<V> get values => _map.values; | 941 Iterable<V> get values => _map.values; |
912 int get length => _map.length; | 942 int get length => _map.length; |
913 bool get isEmpty => _map.isEmpty; | 943 bool get isEmpty => _map.isEmpty; |
914 bool get isNotEmpty => _map.isNotEmpty; | 944 bool get isNotEmpty => _map.isNotEmpty; |
915 } | 945 } |
OLD | NEW |