| OLD | NEW |
| 1 part of angular.core.dom; | 1 part of angular.core.dom; |
| 2 | 2 |
| 3 @NgInjectableService() | 3 @NgInjectableService() |
| 4 class UrlRewriter { | 4 class UrlRewriter { |
| 5 String call(url) => url; | 5 String call(url) => url; |
| 6 } | 6 } |
| 7 | 7 |
| 8 /** | 8 /** |
| 9 * HTTP backend used by the [Http] service that delegates to dart:html's | 9 * HTTP backend used by the [Http] service that delegates to dart:html's |
| 10 * [HttpRequest] and deals with Dart bugs. | 10 * [HttpRequest] and deals with Dart bugs. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 // Complete inside a then to work-around dartbug.com/13051 | 26 // Complete inside a then to work-around dartbug.com/13051 |
| 27 var c = new async.Completer(); | 27 var c = new async.Completer(); |
| 28 | 28 |
| 29 dom.HttpRequest.request(url, | 29 dom.HttpRequest.request(url, |
| 30 method: method, | 30 method: method, |
| 31 withCredentials: withCredentials, | 31 withCredentials: withCredentials, |
| 32 responseType: responseType, | 32 responseType: responseType, |
| 33 mimeType: mimeType, | 33 mimeType: mimeType, |
| 34 requestHeaders: requestHeaders, | 34 requestHeaders: requestHeaders, |
| 35 sendData: sendData, | 35 sendData: sendData, |
| 36 onProgress: onProgress).then((x) => c.complete(x)); | 36 onProgress: onProgress).then((x) => c.complete(x), |
| 37 onError: (e, stackTrace) => c.completeError(e, stackTrace)); |
| 37 return c.future; | 38 return c.future; |
| 38 } | 39 } |
| 39 } | 40 } |
| 40 | 41 |
| 41 @NgInjectableService() | 42 @NgInjectableService() |
| 42 class LocationWrapper { | 43 class LocationWrapper { |
| 43 get location => dom.window.location; | 44 get location => dom.window.location; |
| 44 } | 45 } |
| 45 | 46 |
| 46 typedef RequestInterceptor(HttpResponseConfig); | 47 typedef RequestInterceptor(HttpResponseConfig); |
| 47 typedef RequestErrorInterceptor(dynamic); | 48 typedef RequestErrorInterceptor(dynamic); |
| 48 typedef Response(HttpResponse); | 49 typedef Response(HttpResponse); |
| 49 typedef ResponseError(dynamic); | 50 typedef ResponseError(dynamic); |
| 50 | 51 |
| 51 /** | 52 /** |
| 52 * HttpInterceptors are used to modify the Http request. They can be added to | 53 * HttpInterceptors are used to modify the Http request. They can be added to |
| 53 * [HttpInterceptors] or passed into [Http.call]. | 54 * [HttpInterceptors] or passed into [Http.call]. |
| 54 */ | 55 */ |
| 55 class HttpInterceptor { | 56 class HttpInterceptor { |
| 56 RequestInterceptor request; | 57 RequestInterceptor request; |
| 57 Response response; | 58 Response response; |
| 58 RequestErrorInterceptor requestError; | 59 RequestErrorInterceptor requestError; |
| 59 ResponseError responseError; | 60 ResponseError responseError; |
| 60 | 61 |
| 61 /** | 62 /** |
| 62 * All parameters are optional. | 63 * All parameters are optional. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 93 d = d.replaceFirst(_PROTECTION_PREFIX, ''); | 94 d = d.replaceFirst(_PROTECTION_PREFIX, ''); |
| 94 if (d.contains(_JSON_START) && d.contains(_JSON_END)) { | 95 if (d.contains(_JSON_START) && d.contains(_JSON_END)) { |
| 95 d = JSON.decode(d); | 96 d = JSON.decode(d); |
| 96 } | 97 } |
| 97 return new HttpResponse.copy(r, data: d); | 98 return new HttpResponse.copy(r, data: d); |
| 98 } | 99 } |
| 99 return r; | 100 return r; |
| 100 }; | 101 }; |
| 101 | 102 |
| 102 Function requestError, responseError; | 103 Function requestError, responseError; |
| 103 | |
| 104 } | 104 } |
| 105 | 105 |
| 106 /** | 106 /** |
| 107 * A list of [HttpInterceptor]s. | 107 * A list of [HttpInterceptor]s. |
| 108 */ | 108 */ |
| 109 @NgInjectableService() | 109 @NgInjectableService() |
| 110 class HttpInterceptors { | 110 class HttpInterceptors { |
| 111 List<HttpInterceptor> _interceptors = [new DefaultTransformDataHttpInterceptor
()]; | 111 List<HttpInterceptor> _interceptors = [new DefaultTransformDataHttpInterceptor
()]; |
| 112 | 112 |
| 113 add(HttpInterceptor x) => _interceptors.add(x); | 113 add(HttpInterceptor x) => _interceptors.add(x); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 * The request params as a Map | 156 * The request params as a Map |
| 157 */ | 157 */ |
| 158 Map params; | 158 Map params; |
| 159 | 159 |
| 160 /** | 160 /** |
| 161 * The header map without mangled keys | 161 * The header map without mangled keys |
| 162 */ | 162 */ |
| 163 Map headers; | 163 Map headers; |
| 164 | 164 |
| 165 var data; | 165 var data; |
| 166 | |
| 167 | |
| 168 var _headersObj; | 166 var _headersObj; |
| 169 | 167 |
| 170 /** | 168 /** |
| 171 * Header accessor. Given a string, it will return the matching header, | 169 * Header accessor. Given a string, it will return the matching header, |
| 172 * case-insentivitively. Without a string, returns a header object will | 170 * case-insentivitively. Without a string, returns a header object with |
| 173 * upper-case keys. | 171 * lower-case keys. |
| 174 */ | 172 */ |
| 175 header([String name]) { | 173 header([String name]) { |
| 176 if (_headersObj == null) { | 174 if (_headersObj == null) { |
| 177 _headersObj = {}; | 175 _headersObj = {}; |
| 178 headers.forEach((k,v) { | 176 headers.forEach((k,v) => _headersObj[k.toLowerCase()] = v); |
| 179 _headersObj[k.toLowerCase()] = v; | |
| 180 }); | |
| 181 } | 177 } |
| 182 | 178 |
| 183 if (name != null) { | 179 return name != null ? _headersObj[name.toLowerCase()] : _headersObj; |
| 184 name = name.toLowerCase(); | |
| 185 if (!_headersObj.containsKey(name)) return null; | |
| 186 return _headersObj[name]; | |
| 187 } | |
| 188 | |
| 189 return _headersObj; | |
| 190 } | 180 } |
| 191 | 181 |
| 192 /** | 182 /** |
| 193 * Constructor | 183 * Constructor |
| 194 */ | 184 */ |
| 195 HttpResponseConfig({this.url, this.params, this.headers, this.data}); | 185 HttpResponseConfig({this.url, this.params, this.headers, this.data}); |
| 196 } | 186 } |
| 197 | 187 |
| 198 /** | 188 /** |
| 199 * The response for an HTTP request. Returned from the [Http] service. | 189 * The response for an HTTP request. Returned from the [Http] service. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 * The response's data. Either a string or a transformed object. | 225 * The response's data. Either a string or a transformed object. |
| 236 */ | 226 */ |
| 237 get data => responseText; | 227 get data => responseText; |
| 238 | 228 |
| 239 /** | 229 /** |
| 240 * The response's headers. Without parameters, this method will return the | 230 * The response's headers. Without parameters, this method will return the |
| 241 * [Map] of headers. With [key] parameter, this method will return the specif
ic | 231 * [Map] of headers. With [key] parameter, this method will return the specif
ic |
| 242 * header. | 232 * header. |
| 243 */ | 233 */ |
| 244 headers([String key]) { | 234 headers([String key]) { |
| 245 if (key == null) { | 235 return key == null ? _headers : _headers[key]; |
| 246 return _headers; | |
| 247 } | |
| 248 if (_headers.containsKey(key)) { | |
| 249 return _headers[key]; | |
| 250 } | |
| 251 return null; | |
| 252 } | 236 } |
| 253 | 237 |
| 254 /** | 238 /** |
| 255 * Useful for debugging. | 239 * Useful for debugging. |
| 256 */ | 240 */ |
| 257 toString() => 'HTTP $status: $data'; | 241 toString() => 'HTTP $status: $data'; |
| 258 } | 242 } |
| 259 | 243 |
| 260 /** | 244 /** |
| 261 * Default header configuration. | 245 * Default header configuration. |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 if (v is Function) { | 482 if (v is Function) { |
| 499 headers[k] = v(); | 483 headers[k] = v(); |
| 500 } | 484 } |
| 501 }); | 485 }); |
| 502 | 486 |
| 503 var serverRequest = (HttpResponseConfig config) { | 487 var serverRequest = (HttpResponseConfig config) { |
| 504 assert(config.data == null || config.data is String || config.data is dom.
File); | 488 assert(config.data == null || config.data is String || config.data is dom.
File); |
| 505 | 489 |
| 506 // Strip content-type if data is undefined | 490 // Strip content-type if data is undefined |
| 507 if (config.data == null) { | 491 if (config.data == null) { |
| 508 List<String> toRemove = []; | 492 new List.from(headers.keys) |
| 509 headers.forEach((h, _) { | 493 .where((h) => h.toUpperCase() == 'CONTENT-TYPE') |
| 510 if (h.toUpperCase() == 'CONTENT-TYPE') { | 494 .forEach((h) => headers.remove(h)); |
| 511 toRemove.add(h); | |
| 512 }; | |
| 513 }); | |
| 514 toRemove.forEach((x) => headers.remove(x)); | |
| 515 } | 495 } |
| 516 | 496 |
| 517 | |
| 518 return request( | 497 return request( |
| 519 null, | 498 null, |
| 520 config: config, | 499 config: config, |
| 521 method: method, | 500 method: method, |
| 522 sendData: config.data, | 501 sendData: config.data, |
| 523 requestHeaders: config.headers, | 502 requestHeaders: config.headers, |
| 524 cache: cache); | 503 cache: cache); |
| 525 }; | 504 }; |
| 526 | 505 |
| 527 var chain = [[serverRequest, null]]; | 506 var chain = [[serverRequest, null]]; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 xsrfHeaderName: xsrfHeaderName, xsrfCookieName: xsrfCookieName, | 633 xsrfHeaderName: xsrfHeaderName, xsrfCookieName: xsrfCookieName, |
| 655 interceptors: interceptors, | 634 interceptors: interceptors, |
| 656 cache: cache, timeout: timeout); | 635 cache: cache, timeout: timeout); |
| 657 | 636 |
| 658 /** | 637 /** |
| 659 * Parse raw headers into key-value object | 638 * Parse raw headers into key-value object |
| 660 */ | 639 */ |
| 661 static Map<String, String> parseHeaders(dom.HttpRequest value) { | 640 static Map<String, String> parseHeaders(dom.HttpRequest value) { |
| 662 var headers = value.getAllResponseHeaders(); | 641 var headers = value.getAllResponseHeaders(); |
| 663 | 642 |
| 664 var parsed = {}, key, val, i; | 643 var parsed = {}; |
| 665 | 644 |
| 666 if (headers == null) return parsed; | 645 if (headers == null) return parsed; |
| 667 | 646 |
| 668 headers.split('\n').forEach((line) { | 647 headers.split('\n').forEach((line) { |
| 669 i = line.indexOf(':'); | 648 var i = line.indexOf(':'); |
| 670 if (i == -1) return; | 649 if (i == -1) return; |
| 671 key = line.substring(0, i).trim().toLowerCase(); | 650 var key = line.substring(0, i).trim().toLowerCase(); |
| 672 val = line.substring(i + 1).trim(); | 651 var val = line.substring(i + 1).trim(); |
| 673 | 652 |
| 674 if (key != '') { | 653 if (key != '') { |
| 675 if (parsed.containsKey(key)) { | 654 if (parsed.containsKey(key)) { |
| 676 parsed[key] += ', ' + val; | 655 parsed[key] += ', ' + val; |
| 677 } else { | 656 } else { |
| 678 parsed[key] = val; | 657 parsed[key] = val; |
| 679 } | 658 } |
| 680 } | 659 } |
| 681 }); | 660 }); |
| 682 return parsed; | 661 return parsed; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 } | 760 } |
| 782 | 761 |
| 783 _encodeUriQuery(val, {bool pctEncodeSpaces: false}) => | 762 _encodeUriQuery(val, {bool pctEncodeSpaces: false}) => |
| 784 Uri.encodeComponent(val) | 763 Uri.encodeComponent(val) |
| 785 .replaceAll('%40', '@') | 764 .replaceAll('%40', '@') |
| 786 .replaceAll('%3A', ':') | 765 .replaceAll('%3A', ':') |
| 787 .replaceAll('%24', r'$') | 766 .replaceAll('%24', r'$') |
| 788 .replaceAll('%2C', ',') | 767 .replaceAll('%2C', ',') |
| 789 .replaceAll('%20', pctEncodeSpaces ? '%20' : '+'); | 768 .replaceAll('%20', pctEncodeSpaces ? '%20' : '+'); |
| 790 } | 769 } |
| OLD | NEW |