| 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 // [name] must be a lower-case version of the name. | 251 static void _addContentLength(_HttpHeaders headers, String name, value) { |
| 252 void _add(String name, value) { | 252 if (value is int) { |
| 253 // TODO(sgjesse): Add immutable state throw HttpException is immutable. | 253 headers.contentLength = value; |
| 254 switch (name) { | 254 } else if (value is String) { |
| 255 case HttpHeaders.CONTENT_LENGTH: | 255 headers.contentLength = int.parse(value); |
| 256 if (value is int) { | 256 } else { |
| 257 contentLength = value; | 257 throw new HttpException("Unexpected type for header named $name"); |
| 258 } else if (value is String) { | |
| 259 contentLength = int.parse(value); | |
| 260 } else { | |
| 261 throw new HttpException("Unexpected type for header named $name"); | |
| 262 } | |
| 263 break; | |
| 264 | |
| 265 case HttpHeaders.TRANSFER_ENCODING: | |
| 266 if (value == "chunked") { | |
| 267 chunkedTransferEncoding = true; | |
| 268 } else { | |
| 269 _addValue(name, value); | |
| 270 } | |
| 271 break; | |
| 272 | |
| 273 case HttpHeaders.DATE: | |
| 274 if (value is DateTime) { | |
| 275 date = value; | |
| 276 } else if (value is String) { | |
| 277 _set(HttpHeaders.DATE, value); | |
| 278 } else { | |
| 279 throw new HttpException("Unexpected type for header named $name"); | |
| 280 } | |
| 281 break; | |
| 282 | |
| 283 case HttpHeaders.EXPIRES: | |
| 284 if (value is DateTime) { | |
| 285 expires = value; | |
| 286 } else if (value is String) { | |
| 287 _set(HttpHeaders.EXPIRES, value); | |
| 288 } else { | |
| 289 throw new HttpException("Unexpected type for header named $name"); | |
| 290 } | |
| 291 break; | |
| 292 | |
| 293 case HttpHeaders.IF_MODIFIED_SINCE: | |
| 294 if (value is DateTime) { | |
| 295 ifModifiedSince = value; | |
| 296 } else if (value is String) { | |
| 297 _set(HttpHeaders.IF_MODIFIED_SINCE, value); | |
| 298 } else { | |
| 299 throw new HttpException("Unexpected type for header named $name"); | |
| 300 } | |
| 301 break; | |
| 302 | |
| 303 case HttpHeaders.HOST: | |
| 304 if (value is String) { | |
| 305 int pos = value.indexOf(":"); | |
| 306 if (pos == -1) { | |
| 307 _host = value; | |
| 308 _port = HttpClient.DEFAULT_HTTP_PORT; | |
| 309 } else { | |
| 310 if (pos > 0) { | |
| 311 _host = value.substring(0, pos); | |
| 312 } else { | |
| 313 _host = null; | |
| 314 } | |
| 315 if (pos + 1 == value.length) { | |
| 316 _port = HttpClient.DEFAULT_HTTP_PORT; | |
| 317 } else { | |
| 318 try { | |
| 319 _port = int.parse(value.substring(pos + 1)); | |
| 320 } on FormatException catch (e) { | |
| 321 _port = null; | |
| 322 } | |
| 323 } | |
| 324 } | |
| 325 _set(HttpHeaders.HOST, value); | |
| 326 } else { | |
| 327 throw new HttpException("Unexpected type for header named $name"); | |
| 328 } | |
| 329 break; | |
| 330 | |
| 331 case HttpHeaders.CONNECTION: | |
| 332 var lowerCaseValue = value.toLowerCase(); | |
| 333 if (lowerCaseValue == 'close') { | |
| 334 _persistentConnection = false; | |
| 335 } else if (lowerCaseValue == 'keep-alive') { | |
| 336 _persistentConnection = true; | |
| 337 } | |
| 338 _addValue(name, value); | |
| 339 break; | |
| 340 | |
| 341 case HttpHeaders.CONTENT_TYPE: | |
| 342 _set(HttpHeaders.CONTENT_TYPE, value); | |
| 343 break; | |
| 344 | |
| 345 default: | |
| 346 _addValue(name, value); | |
| 347 } | 258 } |
| 348 } | 259 } |
| 349 | 260 |
| 261 static void _addTransferEncoding(_HttpHeaders headers, String name, value) { |
| 262 if (value == "chunked") { |
| 263 headers.chunkedTransferEncoding = true; |
| 264 } else { |
| 265 headers._addValue(HttpHeaders.TRANSFER_ENCODING, value); |
| 266 } |
| 267 } |
| 268 |
| 269 static void _addDate(_HttpHeaders headers, String name, value) { |
| 270 if (value is DateTime) { |
| 271 headers.date = value; |
| 272 } else if (value is String) { |
| 273 headers._set(HttpHeaders.DATE, value); |
| 274 } else { |
| 275 throw new HttpException("Unexpected type for header named $name"); |
| 276 } |
| 277 } |
| 278 |
| 279 static void _addExpires(_HttpHeaders headers, String name, value) { |
| 280 if (value is DateTime) { |
| 281 headers.expires = value; |
| 282 } else if (value is String) { |
| 283 headers._set(HttpHeaders.EXPIRES, value); |
| 284 } else { |
| 285 throw new HttpException("Unexpected type for header named $name"); |
| 286 } |
| 287 } |
| 288 |
| 289 static void _addIfModifiedSince(_HttpHeaders headers, String name, value) { |
| 290 if (value is DateTime) { |
| 291 headers.ifModifiedSince = value; |
| 292 } else if (value is String) { |
| 293 headers._set(HttpHeaders.IF_MODIFIED_SINCE, value); |
| 294 } else { |
| 295 throw new HttpException("Unexpected type for header named $name"); |
| 296 } |
| 297 } |
| 298 |
| 299 static void _addHost(_HttpHeaders headers, String name, value) { |
| 300 if (value is String) { |
| 301 int pos = value.indexOf(":"); |
| 302 if (pos == -1) { |
| 303 headers._host = value; |
| 304 headers._port = HttpClient.DEFAULT_HTTP_PORT; |
| 305 } else { |
| 306 if (pos > 0) { |
| 307 headers._host = value.substring(0, pos); |
| 308 } else { |
| 309 headers._host = null; |
| 310 } |
| 311 if (pos + 1 == value.length) { |
| 312 headers._port = HttpClient.DEFAULT_HTTP_PORT; |
| 313 } else { |
| 314 try { |
| 315 headers._port = int.parse(value.substring(pos + 1)); |
| 316 } on FormatException catch (e) { |
| 317 headers._port = null; |
| 318 } |
| 319 } |
| 320 } |
| 321 headers._set(HttpHeaders.HOST, value); |
| 322 } else { |
| 323 throw new HttpException("Unexpected type for header named $name"); |
| 324 } |
| 325 } |
| 326 |
| 327 static void _addConnection(_HttpHeaders headers, String name, value) { |
| 328 var lowerCaseValue = value.toLowerCase(); |
| 329 if (lowerCaseValue == 'close') { |
| 330 headers._persistentConnection = false; |
| 331 } else if (lowerCaseValue == 'keep-alive') { |
| 332 headers._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 } |
| 361 _addValue(name, value); |
| 362 } |
| 363 |
| 350 void _addValue(String name, Object value) { | 364 void _addValue(String name, Object value) { |
| 351 List<String> values = _headers[name]; | 365 List<String> values = _headers[name]; |
| 352 if (values == null) { | 366 if (values == null) { |
| 353 values = new List<String>(); | 367 values = new List<String>(); |
| 354 _headers[name] = values; | 368 _headers[name] = values; |
| 355 } | 369 } |
| 356 if (value is DateTime) { | 370 if (value is DateTime) { |
| 357 values.add(HttpDate.format(value)); | 371 values.add(HttpDate.format(value)); |
| 358 } else { | 372 } else { |
| 359 values.add(value.toString()); | 373 values.add(value.toString()); |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 892 void clear() { | 906 void clear() { |
| 893 throw new UnsupportedError("Cannot modify an unmodifiable map"); | 907 throw new UnsupportedError("Cannot modify an unmodifiable map"); |
| 894 } | 908 } |
| 895 void forEach(void f(K key, V value)) => _map.forEach(f); | 909 void forEach(void f(K key, V value)) => _map.forEach(f); |
| 896 Iterable<K> get keys => _map.keys; | 910 Iterable<K> get keys => _map.keys; |
| 897 Iterable<V> get values => _map.values; | 911 Iterable<V> get values => _map.values; |
| 898 int get length => _map.length; | 912 int get length => _map.length; |
| 899 bool get isEmpty => _map.isEmpty; | 913 bool get isEmpty => _map.isEmpty; |
| 900 bool get isNotEmpty => _map.isNotEmpty; | 914 bool get isNotEmpty => _map.isNotEmpty; |
| 901 } | 915 } |
| OLD | NEW |