| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 class _HttpHeaders implements HttpHeaders { | 5 class _HttpHeaders implements HttpHeaders { |
| 6 _HttpHeaders() : _headers = new Map<String, List<String>>(); | 6 _HttpHeaders() : _headers = new Map<String, List<String>>(); |
| 7 | 7 |
| 8 List<String> operator[](String name) { | 8 List<String> operator[](String name) { |
| 9 name = name.toLowerCase(); | 9 name = name.toLowerCase(); |
| 10 return _headers[name]; | 10 return _headers[name]; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 if (value is List) { | 25 if (value is List) { |
| 26 for (int i = 0; i < value.length; i++) { | 26 for (int i = 0; i < value.length; i++) { |
| 27 _add(name, value[i]); | 27 _add(name, value[i]); |
| 28 } | 28 } |
| 29 } else { | 29 } else { |
| 30 _add(name, value); | 30 _add(name, value); |
| 31 } | 31 } |
| 32 } | 32 } |
| 33 | 33 |
| 34 void set(String name, Object value) { | 34 void set(String name, Object value) { |
| 35 name = name.toLowerCase(); |
| 35 _checkMutable(); | 36 _checkMutable(); |
| 36 removeAll(name); | 37 removeAll(name); |
| 37 add(name, value); | 38 add(name, value); |
| 38 } | 39 } |
| 39 | 40 |
| 40 void remove(String name, Object value) { | 41 void remove(String name, Object value) { |
| 41 _checkMutable(); | 42 _checkMutable(); |
| 42 name = name.toLowerCase(); | 43 name = name.toLowerCase(); |
| 43 List<String> values = _headers[name]; | 44 List<String> values = _headers[name]; |
| 44 if (values != null) { | 45 if (values != null) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 } | 109 } |
| 109 | 110 |
| 110 void set expires(Date expires) { | 111 void set expires(Date expires) { |
| 111 _checkMutable(); | 112 _checkMutable(); |
| 112 // Format "Expires" header with date in Greenwich Mean Time (GMT). | 113 // Format "Expires" header with date in Greenwich Mean Time (GMT). |
| 113 String formatted = | 114 String formatted = |
| 114 _HttpUtils.formatDate(expires.changeTimeZone(new TimeZone.utc())); | 115 _HttpUtils.formatDate(expires.changeTimeZone(new TimeZone.utc())); |
| 115 _set("expires", formatted); | 116 _set("expires", formatted); |
| 116 } | 117 } |
| 117 | 118 |
| 119 ContentType get contentType() { |
| 120 var values = _headers["content-type"]; |
| 121 if (values != null) { |
| 122 return new ContentType.fromString(values[0]); |
| 123 } else { |
| 124 return new ContentType(); |
| 125 } |
| 126 } |
| 127 |
| 128 void set contentType(ContentType contentType) { |
| 129 _checkMutable(); |
| 130 _set("content-type", contentType.toString()); |
| 131 } |
| 132 |
| 118 void _add(String name, Object value) { | 133 void _add(String name, Object value) { |
| 119 // TODO(sgjesse): Add immutable state throw HttpException is immutable. | 134 // TODO(sgjesse): Add immutable state throw HttpException is immutable. |
| 120 if (name.toLowerCase() == "date") { | 135 if (name.toLowerCase() == "date") { |
| 121 if (value is Date) { | 136 if (value is Date) { |
| 122 date = value; | 137 date = value; |
| 123 } else if (value is String) { | 138 } else if (value is String) { |
| 124 _set("date", value); | 139 _set("date", value); |
| 125 } else { | 140 } else { |
| 126 throw new HttpException("Unexpected type for header named $name"); | 141 throw new HttpException("Unexpected type for header named $name"); |
| 127 } | 142 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 148 _port = HttpClient.DEFAULT_HTTP_PORT; | 163 _port = HttpClient.DEFAULT_HTTP_PORT; |
| 149 } else { | 164 } else { |
| 150 try { | 165 try { |
| 151 _port = Math.parseInt(value.substring(pos + 1)); | 166 _port = Math.parseInt(value.substring(pos + 1)); |
| 152 } catch (BadNumberFormatException e) { | 167 } catch (BadNumberFormatException e) { |
| 153 _port = null; | 168 _port = null; |
| 154 } | 169 } |
| 155 } | 170 } |
| 156 _set("host", value); | 171 _set("host", value); |
| 157 } | 172 } |
| 173 } else if (name.toLowerCase() == "content-type") { |
| 174 _set("content-type", value); |
| 158 } else { | 175 } else { |
| 159 name = name.toLowerCase(); | 176 name = name.toLowerCase(); |
| 160 List<String> values = _headers[name]; | 177 List<String> values = _headers[name]; |
| 161 if (values == null) { | 178 if (values == null) { |
| 162 values = new List<String>(); | 179 values = new List<String>(); |
| 163 _headers[name] = values; | 180 _headers[name] = values; |
| 164 } | 181 } |
| 165 values.add(value.toString()); | 182 values.add(value.toString()); |
| 166 } | 183 } |
| 167 } | 184 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 } | 239 } |
| 223 | 240 |
| 224 bool _mutable = true; // Are the headers currently mutable? | 241 bool _mutable = true; // Are the headers currently mutable? |
| 225 Map<String, List<String>> _headers; | 242 Map<String, List<String>> _headers; |
| 226 | 243 |
| 227 String _host; | 244 String _host; |
| 228 int _port; | 245 int _port; |
| 229 } | 246 } |
| 230 | 247 |
| 231 | 248 |
| 249 class _HeaderValue implements HeaderValue { |
| 250 _HeaderValue([String this.value = ""]); |
| 251 |
| 252 _HeaderValue.fromString(String value) { |
| 253 // Parse the string. |
| 254 _parse(value); |
| 255 } |
| 256 |
| 257 Map<String, String> get parameters() { |
| 258 if (_parameters == null) _parameters = new Map<String, String>(); |
| 259 return _parameters; |
| 260 } |
| 261 |
| 262 String toString() { |
| 263 StringBuffer sb = new StringBuffer(); |
| 264 sb.add(value); |
| 265 if (parameters != null && parameters.length > 0) { |
| 266 _parameters.forEach((String name, String value) { |
| 267 sb.add("; "); |
| 268 sb.add(name); |
| 269 sb.add("="); |
| 270 sb.add(value); |
| 271 }); |
| 272 } |
| 273 return sb.toString(); |
| 274 } |
| 275 |
| 276 void _parse(String s) { |
| 277 int index = 0; |
| 278 |
| 279 bool done() => index == s.length; |
| 280 |
| 281 void skipWS() { |
| 282 while (!done()) { |
| 283 if (s[index] != " " && s[index] != "\t") return; |
| 284 index++; |
| 285 } |
| 286 } |
| 287 |
| 288 String parseValue() { |
| 289 int start = index; |
| 290 while (!done()) { |
| 291 if (s[index] == " " || s[index] == "\t" || s[index] == ";") break; |
| 292 index++; |
| 293 } |
| 294 return s.substring(start, index).toLowerCase(); |
| 295 } |
| 296 |
| 297 void expect(String expected) { |
| 298 if (done()) throw new HttpException("Failed to parse header value [$s]"); |
| 299 if (s[index] != expected) { |
| 300 throw new HttpException("Failed to parse header value [$s]"); |
| 301 } |
| 302 index++; |
| 303 } |
| 304 |
| 305 void parseParameters() { |
| 306 _parameters = new Map<String, String>(); |
| 307 |
| 308 String parseParameterName() { |
| 309 int start = index; |
| 310 while (!done()) { |
| 311 if (s[index] == " " || s[index] == "\t" || s[index] == "=") break; |
| 312 index++; |
| 313 } |
| 314 return s.substring(start, index).toLowerCase(); |
| 315 } |
| 316 |
| 317 String parseParameterValue() { |
| 318 if (s[index] == "\"") { |
| 319 // Parse quoted value. |
| 320 StringBuffer sb = new StringBuffer(); |
| 321 index++; |
| 322 while (!done()) { |
| 323 if (s[index] == "\\") { |
| 324 if (index + 1 == s.length) { |
| 325 throw new HttpException("Failed to parse header value [$s]"); |
| 326 } |
| 327 index++; |
| 328 } else if (s[index] == "\"") { |
| 329 index++; |
| 330 break; |
| 331 } |
| 332 sb.add(s[index]); |
| 333 index++; |
| 334 } |
| 335 return sb.toString(); |
| 336 } else { |
| 337 // Parse non-quoted value. |
| 338 return parseValue(); |
| 339 } |
| 340 } |
| 341 |
| 342 while (!done()) { |
| 343 skipWS(); |
| 344 if (done()) return; |
| 345 String name = parseParameterName(); |
| 346 skipWS(); |
| 347 expect("="); |
| 348 skipWS(); |
| 349 String value = parseParameterValue(); |
| 350 _parameters[name] = value; |
| 351 skipWS(); |
| 352 if (done()) return; |
| 353 expect(";"); |
| 354 } |
| 355 } |
| 356 |
| 357 skipWS(); |
| 358 value = parseValue(); |
| 359 skipWS(); |
| 360 if (done()) return; |
| 361 expect(";"); |
| 362 parseParameters(); |
| 363 } |
| 364 |
| 365 String value; |
| 366 Map<String, String> _parameters; |
| 367 } |
| 368 |
| 369 |
| 370 class _ContentType extends _HeaderValue implements ContentType { |
| 371 _ContentType([String this._primaryType = "", String this._subType = ""]); |
| 372 |
| 373 _ContentType.fromString(String value) : super.fromString(value); |
| 374 |
| 375 String get value() => "$_primaryType/$_subType"; |
| 376 |
| 377 void set value(String s) { |
| 378 int index = s.indexOf("/"); |
| 379 if (index == -1 || index == (s.length - 1)) { |
| 380 primaryType = s.trim().toLowerCase(); |
| 381 subType = ""; |
| 382 } else { |
| 383 primaryType = s.substring(0, index).trim().toLowerCase(); |
| 384 subType = s.substring(index + 1).trim().toLowerCase(); |
| 385 } |
| 386 } |
| 387 |
| 388 String get primaryType() => _primaryType; |
| 389 |
| 390 void set primaryType(String s) { |
| 391 _primaryType = s; |
| 392 } |
| 393 |
| 394 String get subType() => _subType; |
| 395 |
| 396 void set subType(String s) { |
| 397 _subType = s; |
| 398 } |
| 399 |
| 400 String get charset() => parameters["charset"]; |
| 401 |
| 402 void set charset(String s) { |
| 403 parameters["charset"] = s; |
| 404 } |
| 405 |
| 406 String _primaryType = ""; |
| 407 String _subType = ""; |
| 408 } |
| 409 |
| 410 |
| 232 class _HttpRequestResponseBase { | 411 class _HttpRequestResponseBase { |
| 233 final int START = 0; | 412 final int START = 0; |
| 234 final int HEADER_SENT = 1; | 413 final int HEADER_SENT = 1; |
| 235 final int DONE = 2; | 414 final int DONE = 2; |
| 236 final int UPGRADED = 3; | 415 final int UPGRADED = 3; |
| 237 | 416 |
| 238 _HttpRequestResponseBase(_HttpConnectionBase this._httpConnection) | 417 _HttpRequestResponseBase(_HttpConnectionBase this._httpConnection) |
| 239 : _headers = new _HttpHeaders() { | 418 : _headers = new _HttpHeaders() { |
| 240 _state = START; | 419 _state = START; |
| 241 } | 420 } |
| (...skipping 1405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1647 | 1826 |
| 1648 | 1827 |
| 1649 class _RedirectInfo implements RedirectInfo { | 1828 class _RedirectInfo implements RedirectInfo { |
| 1650 const _RedirectInfo(int this.statusCode, | 1829 const _RedirectInfo(int this.statusCode, |
| 1651 String this.method, | 1830 String this.method, |
| 1652 Uri this.location); | 1831 Uri this.location); |
| 1653 final int statusCode; | 1832 final int statusCode; |
| 1654 final String method; | 1833 final String method; |
| 1655 final Uri location; | 1834 final Uri location; |
| 1656 } | 1835 } |
| OLD | NEW |