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 |