Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(264)

Side by Side Diff: tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate

Issue 2042033002: Add zone task support to http-requests. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/dom/scripts/htmlrenamer.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 part of $LIBRARYNAME; 5 part of $LIBRARYNAME;
6 6
7 /**
8 * A task specification for http requests.
9 *
10 * This specification is not available when an http request is sent through
11 * direct use of [HttpRequest.send]. See [HttpRequestSendTaskSpecification].
12 *
13 * A task created by this specification is a `Future<HttpRequest>`.
14 */
15 class HttpRequestTaskSpecification extends TaskSpecification {
16 final String url;
Lasse Reichstein Nielsen 2016/06/08 09:40:28 Document fields (e.g., by referencing the XmlHttpR
floitsch 2016/06/10 15:46:57 Done.
17 final String method;
18 final bool withCredentials;
19 final String responseType;
20 final String mimeType;
21 final Map<String, String> requestHeaders;
22 final dynamic sendData;
23 /**
24 * The function that is invoked on progress updates. This function is *not*
25 * executed as part of the http-request task, but as an event callback.
Lasse Reichstein Nielsen 2016/06/08 09:40:28 I don't understand what it means to be "part of th
floitsch 2016/06/10 15:46:57 Done.
26 *
27 * Creating an http-request automatically registers the on-progress listener.
28 */
29 final ZoneUnaryCallback<dynamic, ProgressEvent> onProgress;
30
31 HttpRequestTaskSpecification(this.url,
32 {String this.method, bool this.withCredentials, String this.responseType,
33 String this.mimeType, Map<String, String> this.requestHeaders,
34 this.sendData,
35 void this.onProgress(ProgressEvent e)});
36
37 String get name => "dart.html.http-request";
38 bool get isOneShot => true;
39 }
40
41 /**
42 * A task specification for http requests that are initiated through a direct
43 * invocation of [HttpRequest.send].
44 *
45 * This specification serves as signal to zones that an http request has been
Lasse Reichstein Nielsen 2016/06/08 09:40:28 http -> HTTP acronym, dittos below.
floitsch 2016/06/10 15:46:57 Done.
46 * initiated. The created task is the [request] object itself, and
47 * no callback is ever executed in this task. When the http request gets
48 * data event-listeners that have the request object as event target are
Lasse Reichstein Nielsen 2016/06/08 09:40:28 commas in this sentence? I have a hard time parsin
floitsch 2016/06/10 15:46:57 Reworded. Done.
49 * executed.
50 *
51 * Http requests that are initiated through `request` methods don't use
52 * this class but use [HttpRequestTaskSpecification].
53 */
54 class HttpRequestSendTaskSpecification extends TaskSpecification {
55 final HttpRequest request;
56 final dynamic sendData;
57
58 HttpRequestSendTaskSpecification(this.request, this.sendData);
59
60 String get name => "dart.html.http-request-send";
61
62 /**
63 * No callback is ever executed in an http-request send task.
64 */
65 bool get isOneShot => false;
66 }
67
7 /** 68 /**
8 * A client-side XHR request for getting data from a URL, 69 * A client-side XHR request for getting data from a URL,
9 * formally known as XMLHttpRequest. 70 * formally known as XMLHttpRequest.
10 * 71 *
11 * HttpRequest can be used to obtain data from HTTP and FTP protocols, 72 * HttpRequest can be used to obtain data from HTTP and FTP protocols,
12 * and is useful for AJAX-style page updates. 73 * and is useful for AJAX-style page updates.
13 * 74 *
14 * The simplest way to get the contents of a text file, such as a 75 * The simplest way to get the contents of a text file, such as a
15 * JSON-formatted file, is with [getString]. 76 * JSON-formatted file, is with [getString].
16 * For example, the following code gets the contents of a JSON file 77 * For example, the following code gets the contents of a JSON file
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 * with appropriate permissions in their manifest. Requests to file:// URIs 244 * with appropriate permissions in their manifest. Requests to file:// URIs
184 * will also never fail- the Future will always complete successfully, even 245 * will also never fail- the Future will always complete successfully, even
185 * when the file cannot be found. 246 * when the file cannot be found.
186 * 247 *
187 * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access _authentication). 248 * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access _authentication).
188 */ 249 */
189 static Future<HttpRequest> request(String url, 250 static Future<HttpRequest> request(String url,
190 {String method, bool withCredentials, String responseType, 251 {String method, bool withCredentials, String responseType,
191 String mimeType, Map<String, String> requestHeaders, sendData, 252 String mimeType, Map<String, String> requestHeaders, sendData,
192 void onProgress(ProgressEvent e)}) { 253 void onProgress(ProgressEvent e)}) {
254 var spec = new HttpRequestTaskSpecification(
255 url, method: method,
256 withCredentials: withCredentials,
257 responseType: responseType,
258 mimeType: mimeType,
259 requestHeaders: requestHeaders,
260 sendData: sendData,
261 onProgress: onProgress);
262
263 if (identical(Zone.current, Zone.ROOT)) {
264 return _createHttpRequestTask(spec, null);
265 }
266 return Zone.current.createTask(_createHttpRequestTask, spec);
267 }
268
269 static Future<HttpRequest> _createHttpRequestTask(
270 HttpRequestTaskSpecification spec, Zone zone) {
271 String url = spec.url;
272 String method = spec.method;
273 bool withCredentials = spec.withCredentials;
274 String responseType = spec.responseType;
275 String mimeType = spec.mimeType;
276 Map<String, String> requestHeaders = spec.requestHeaders;
277 var sendData = spec.sendData;
278 var onProgress = spec.onProgress;
279
193 var completer = new Completer<HttpRequest>(); 280 var completer = new Completer<HttpRequest>();
281 var task = completer.future;
194 282
195 var xhr = new HttpRequest(); 283 var xhr = new HttpRequest();
196 if (method == null) { 284 if (method == null) {
197 method = 'GET'; 285 method = 'GET';
198 } 286 }
199 xhr.open(method, url, async: true); 287 xhr.open(method, url, async: true);
200 288
201 if (withCredentials != null) { 289 if (withCredentials != null) {
202 xhr.withCredentials = withCredentials; 290 xhr.withCredentials = withCredentials;
203 } 291 }
(...skipping 19 matching lines...) Expand all
223 xhr.onLoad.listen((e) { 311 xhr.onLoad.listen((e) {
224 var accepted = xhr.status >= 200 && xhr.status < 300; 312 var accepted = xhr.status >= 200 && xhr.status < 300;
225 var fileUri = xhr.status == 0; // file:// URIs have status of 0. 313 var fileUri = xhr.status == 0; // file:// URIs have status of 0.
226 var notModified = xhr.status == 304; 314 var notModified = xhr.status == 304;
227 // Redirect status is specified up to 307, but others have been used in 315 // Redirect status is specified up to 307, but others have been used in
228 // practice. Notably Google Drive uses 308 Resume Incomplete for 316 // practice. Notably Google Drive uses 308 Resume Incomplete for
229 // resumable uploads, and it's also been used as a redirect. The 317 // resumable uploads, and it's also been used as a redirect. The
230 // redirect case will be handled by the browser before it gets to us, 318 // redirect case will be handled by the browser before it gets to us,
231 // so if we see it we should pass it through to the user. 319 // so if we see it we should pass it through to the user.
232 var unknownRedirect = xhr.status > 307 && xhr.status < 400; 320 var unknownRedirect = xhr.status > 307 && xhr.status < 400;
233 321
234 if (accepted || fileUri || notModified || unknownRedirect) { 322 var isSuccessful = accepted || fileUri || notModified || unknownRedirect;
323
324 if (zone == null && isSuccessful) {
235 completer.complete(xhr); 325 completer.complete(xhr);
326 } else if (zone == null) {
327 completer.completeError(e);
328 } else if (isSuccessful) {
329 zone.runTask((task, value) {
330 completer.complete(value);
331 }, task, xhr);
236 } else { 332 } else {
237 completer.completeError(e); 333 zone.runTask((task, error) {
334 completer.completeError(error);
335 }, task, e);
238 } 336 }
239 }); 337 });
240 338
241 xhr.onError.listen(completer.completeError); 339 if (zone == null) {
340 xhr.onError.listen(completer.completeError);
341 } else {
342 xhr.onError.listen((error) {
343 zone.runTask((task, error) {
344 completer.completeError(error);
345 }, task, error);
346 });
347 }
242 348
243 if (sendData != null) { 349 if (sendData != null) {
244 xhr.send(sendData); 350 // TODO(floitsch): should we go through 'send()' and have nested tasks?
351 xhr._send(sendData);
245 } else { 352 } else {
246 xhr.send(); 353 xhr._send();
247 } 354 }
248 355
249 return completer.future; 356 return task;
250 } 357 }
251 358
252 /** 359 /**
253 * Checks to see if the Progress event is supported on the current platform. 360 * Checks to see if the Progress event is supported on the current platform.
254 */ 361 */
255 static bool get supportsProgressEvent { 362 static bool get supportsProgressEvent {
256 $if DART2JS 363 $if DART2JS
257 var xhr = new HttpRequest(); 364 var xhr = new HttpRequest();
258 return JS('bool', '("onprogress" in #)', xhr); 365 return JS('bool', '("onprogress" in #)', xhr);
259 $else 366 $else
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 * cross-origin support is not required then [request] should be used instead. 416 * cross-origin support is not required then [request] should be used instead.
310 */ 417 */
311 @Experimental() 418 @Experimental()
312 static Future<String> requestCrossOrigin(String url, 419 static Future<String> requestCrossOrigin(String url,
313 {String method, String sendData}) { 420 {String method, String sendData}) {
314 if (supportsCrossOrigin) { 421 if (supportsCrossOrigin) {
315 return request(url, method: method, sendData: sendData).then((xhr) { 422 return request(url, method: method, sendData: sendData).then((xhr) {
316 return xhr.responseText; 423 return xhr.responseText;
317 }); 424 });
318 } 425 }
426 // TODO(floitsch): the following code doesn't go through task zones.
427 // Since 'XDomainRequest' is an IE9 feature we should probably just remove
428 // it.
319 $if DART2JS 429 $if DART2JS
320 var completer = new Completer<String>(); 430 var completer = new Completer<String>();
321 if (method == null) { 431 if (method == null) {
322 method = 'GET'; 432 method = 'GET';
323 } 433 }
324 var xhr = JS('var', 'new XDomainRequest()'); 434 var xhr = JS('var', 'new XDomainRequest()');
325 JS('', '#.open(#, #)', xhr, method, url); 435 JS('', '#.open(#, #)', xhr, method, url);
326 JS('', '#.onload = #', xhr, convertDartClosureToJS((e) { 436 JS('', '#.onload = #', xhr, convertDartClosureToJS((e) {
327 var response = JS('String', '#.responseText', xhr); 437 var response = JS('String', '#.responseText', xhr);
328 completer.complete(response); 438 completer.complete(response);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 * 499 *
390 * By default the request is done asyncronously, with no user or password 500 * By default the request is done asyncronously, with no user or password
391 * authentication information. If `async` is false, the request will be send 501 * authentication information. If `async` is false, the request will be send
392 * synchronously. 502 * synchronously.
393 * 503 *
394 * Calling `open` again on a currently active request is equivalent to 504 * Calling `open` again on a currently active request is equivalent to
395 * calling `abort`. 505 * calling `abort`.
396 * 506 *
397 * Note: Most simple HTTP requests can be accomplished using the [getString], 507 * Note: Most simple HTTP requests can be accomplished using the [getString],
398 * [request], [requestCrossOrigin], or [postFormData] methods. Use of this 508 * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
399 * `open` method is intended only for more complext HTTP requests where 509 * `open` method is intended only for more complex HTTP requests where
400 * finer-grained control is needed. 510 * finer-grained control is needed.
401 */ 511 */
402 @DomName('XMLHttpRequest.open') 512 @DomName('XMLHttpRequest.open')
403 @DocsEditable() 513 @DocsEditable()
404 $if JSINTEROP 514 $if JSINTEROP
405 void open(String method, String url, {bool async, String user, String password }) { 515 void open(String method, String url, {bool async, String user, String password }) {
406 if (async == null && user == null && password == null) { 516 if (async == null && user == null && password == null) {
407 _blink.BlinkXMLHttpRequest.instance.open_Callback_2_(this, method, url); 517 _blink.BlinkXMLHttpRequest.instance.open_Callback_2_(this, method, url);
408 } else { 518 } else {
409 _blink.BlinkXMLHttpRequest.instance.open_Callback_5_(this, method, url, as ync, user, password); 519 _blink.BlinkXMLHttpRequest.instance.open_Callback_5_(this, method, url, as ync, user, password);
410 } 520 }
411 } 521 }
412 $else 522 $else
413 void open(String method, String url, {bool async, String user, String password }) native; 523 void open(String method, String url, {bool async, String user, String password }) native;
414 $endif 524 $endif
415 525
526 /**
527 * Sends the request with any given `data`.
528 *
529 * Note: Most simple HTTP requests can be accomplished using the [getString],
530 * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
531 * `send` method is intended only for more complex HTTP requests where
532 * finer-grained control is needed.
533 *
534 * ## Other resources
535 *
536 * * [XMLHttpRequest.send](https://developer.mozilla.org/en-US/docs/DOM/XMLHtt pRequest#send%28%29)
537 * from MDN.
538 */
539 @DomName('XMLHttpRequest.send')
540 @DocsEditable()
541 void send([body_OR_data]) {
542 if (identical(Zone.current, Zone.ROOT)) {
543 _send(body_OR_data);
544 } else {
545 Zone.current.createTask(_createHttpRequestSendTask,
546 new HttpRequestSendTaskSpecification(this, body_OR_data));
547 }
548 }
549
550 static HttpRequest _createHttpRequestSendTask(
551 HttpRequestSendTaskSpecification spec, Zone zone) {
552 spec.request._send(spec.sendData);
553 return spec.request;
554 }
555
416 $!MEMBERS 556 $!MEMBERS
417 } 557 }
OLDNEW
« no previous file with comments | « tools/dom/scripts/htmlrenamer.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698