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

Side by Side Diff: Source/core/xml/XMLHttpRequest.cpp

Issue 96793002: Switch custom XMLHttpRequest bindings over to new-style ExceptionState. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Inline local binding in throwTypeError() Created 7 years 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 | « Source/bindings/v8/custom/V8XMLHttpRequestCustom.cpp ('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 /* 1 /*
2 * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2005-2007 Alexey Proskuryakov <ap@webkit.org> 3 * Copyright (C) 2005-2007 Alexey Proskuryakov <ap@webkit.org>
4 * Copyright (C) 2007, 2008 Julien Chaffraix <jchaffraix@webkit.org> 4 * Copyright (C) 2007, 2008 Julien Chaffraix <jchaffraix@webkit.org>
5 * Copyright (C) 2008, 2011 Google Inc. All rights reserved. 5 * Copyright (C) 2008, 2011 Google Inc. All rights reserved.
6 * Copyright (C) 2012 Intel Corporation 6 * Copyright (C) 2012 Intel Corporation
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public 9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 } 208 }
209 209
210 XMLHttpRequest::State XMLHttpRequest::readyState() const 210 XMLHttpRequest::State XMLHttpRequest::readyState() const
211 { 211 {
212 return m_state; 212 return m_state;
213 } 213 }
214 214
215 ScriptString XMLHttpRequest::responseText(ExceptionState& exceptionState) 215 ScriptString XMLHttpRequest::responseText(ExceptionState& exceptionState)
216 { 216 {
217 if (m_responseTypeCode != ResponseTypeDefault && m_responseTypeCode != Respo nseTypeText) { 217 if (m_responseTypeCode != ResponseTypeDefault && m_responseTypeCode != Respo nseTypeText) {
218 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f ailedToGet("responseText", "XMLHttpRequest", "the value is only accessible if th e object's 'responseType' is '' or 'text' (was '" + responseType() + "').")); 218 exceptionState.throwDOMException(InvalidStateError, "The value is only a ccessible if the object's 'responseType' is '' or 'text' (was '" + responseType( ) + "').");
219 return ScriptString(); 219 return ScriptString();
220 } 220 }
221 if (m_error || (m_state != LOADING && m_state != DONE)) 221 if (m_error || (m_state != LOADING && m_state != DONE))
222 return ScriptString(); 222 return ScriptString();
223 return m_responseText; 223 return m_responseText;
224 } 224 }
225 225
226 ScriptString XMLHttpRequest::responseJSONSource() 226 ScriptString XMLHttpRequest::responseJSONSource()
227 { 227 {
228 ASSERT(m_responseTypeCode == ResponseTypeJSON); 228 ASSERT(m_responseTypeCode == ResponseTypeJSON);
229 229
230 if (m_error || m_state != DONE) 230 if (m_error || m_state != DONE)
231 return ScriptString(); 231 return ScriptString();
232 return m_responseText; 232 return m_responseText;
233 } 233 }
234 234
235 Document* XMLHttpRequest::responseXML(ExceptionState& exceptionState) 235 Document* XMLHttpRequest::responseXML(ExceptionState& exceptionState)
236 { 236 {
237 if (m_responseTypeCode != ResponseTypeDefault && m_responseTypeCode != Respo nseTypeDocument) { 237 if (m_responseTypeCode != ResponseTypeDefault && m_responseTypeCode != Respo nseTypeDocument) {
238 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f ailedToGet("responseXML", "XMLHttpRequest", "the value is only accessible if the object's 'responseType' is '' or 'document' (was '" + responseType() + "').")); 238 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f ailedToGet("responseXML", "XMLHttpRequest", "The value is only accessible if the object's 'responseType' is '' or 'document' (was '" + responseType() + "')."));
239 return 0; 239 return 0;
240 } 240 }
241 241
242 if (m_error || m_state != DONE) 242 if (m_error || m_state != DONE)
243 return 0; 243 return 0;
244 244
245 if (!m_createdDocument) { 245 if (!m_createdDocument) {
246 bool isHTML = equalIgnoringCase(responseMIMEType(), "text/html"); 246 bool isHTML = equalIgnoringCase(responseMIMEType(), "text/html");
247 247
248 // The W3C spec requires the final MIME type to be some valid XML type, or text/html. 248 // The W3C spec requires the final MIME type to be some valid XML type, or text/html.
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 return 0; 330 return 0;
331 331
332 return m_responseStream.get(); 332 return m_responseStream.get();
333 } 333 }
334 334
335 void XMLHttpRequest::setTimeout(unsigned long timeout, ExceptionState& exception State) 335 void XMLHttpRequest::setTimeout(unsigned long timeout, ExceptionState& exception State)
336 { 336 {
337 // FIXME: Need to trigger or update the timeout Timer here, if needed. http: //webkit.org/b/98156 337 // FIXME: Need to trigger or update the timeout Timer here, if needed. http: //webkit.org/b/98156
338 // XHR2 spec, 4.7.3. "This implies that the timeout attribute can be set whi le fetching is in progress. If that occurs it will still be measured relative to the start of fetching." 338 // XHR2 spec, 4.7.3. "This implies that the timeout attribute can be set whi le fetching is in progress. If that occurs it will still be measured relative to the start of fetching."
339 if (executionContext()->isDocument() && !m_async) { 339 if (executionContext()->isDocument() && !m_async) {
340 exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages:: failedToSet("timeout", "XMLHttpRequest", "timeouts cannot be set for synchronous requests made from a document.")); 340 exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages:: failedToSet("timeout", "XMLHttpRequest", "Timeouts cannot be set for synchronous requests made from a document."));
341 return; 341 return;
342 } 342 }
343 m_timeoutMilliseconds = timeout; 343 m_timeoutMilliseconds = timeout;
344 } 344 }
345 345
346 void XMLHttpRequest::setResponseType(const String& responseType, ExceptionState& exceptionState) 346 void XMLHttpRequest::setResponseType(const String& responseType, ExceptionState& exceptionState)
347 { 347 {
348 if (m_state >= LOADING) { 348 if (m_state >= LOADING) {
349 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f ailedToSet("responseType", "XMLHttpRequest", "the response type cannot be set if the object's state is LOADING or DONE.")); 349 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f ailedToSet("responseType", "XMLHttpRequest", "The response type cannot be set if the object's state is LOADING or DONE."));
350 return; 350 return;
351 } 351 }
352 352
353 // Newer functionality is not available to synchronous requests in window co ntexts, as a spec-mandated 353 // Newer functionality is not available to synchronous requests in window co ntexts, as a spec-mandated
354 // attempt to discourage synchronous XHR use. responseType is one such piece of functionality. 354 // attempt to discourage synchronous XHR use. responseType is one such piece of functionality.
355 // We'll only disable this functionality for HTTP(S) requests since sync req uests for local protocols 355 // We'll only disable this functionality for HTTP(S) requests since sync req uests for local protocols
356 // such as file: and data: still make sense to allow. 356 // such as file: and data: still make sense to allow.
357 if (!m_async && executionContext()->isDocument() && m_url.protocolIsInHTTPFa mily()) { 357 if (!m_async && executionContext()->isDocument() && m_url.protocolIsInHTTPFa mily()) {
358 exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages:: failedToSet("responseType", "XMLHttpRequest", "the response type can only be cha nged for asynchronous HTTP requests made from a document.")); 358 exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages:: failedToSet("responseType", "XMLHttpRequest", "The response type can only be cha nged for asynchronous HTTP requests made from a document."));
359 return; 359 return;
360 } 360 }
361 361
362 if (responseType == "") { 362 if (responseType == "") {
363 m_responseTypeCode = ResponseTypeDefault; 363 m_responseTypeCode = ResponseTypeDefault;
364 } else if (responseType == "text") { 364 } else if (responseType == "text") {
365 m_responseTypeCode = ResponseTypeText; 365 m_responseTypeCode = ResponseTypeText;
366 } else if (responseType == "json") { 366 } else if (responseType == "json") {
367 m_responseTypeCode = ResponseTypeJSON; 367 m_responseTypeCode = ResponseTypeJSON;
368 } else if (responseType == "document") { 368 } else if (responseType == "document") {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDi spatchXHRLoadEvent(executionContext(), this); 440 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDi spatchXHRLoadEvent(executionContext(), this);
441 dispatchThrottledProgressEventSnapshot(EventTypeNames::load); 441 dispatchThrottledProgressEventSnapshot(EventTypeNames::load);
442 InspectorInstrumentation::didDispatchXHRLoadEvent(cookie); 442 InspectorInstrumentation::didDispatchXHRLoadEvent(cookie);
443 dispatchThrottledProgressEventSnapshot(EventTypeNames::loadend); 443 dispatchThrottledProgressEventSnapshot(EventTypeNames::loadend);
444 } 444 }
445 } 445 }
446 446
447 void XMLHttpRequest::setWithCredentials(bool value, ExceptionState& exceptionSta te) 447 void XMLHttpRequest::setWithCredentials(bool value, ExceptionState& exceptionSta te)
448 { 448 {
449 if (m_state > OPENED || m_loader) { 449 if (m_state > OPENED || m_loader) {
450 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f ailedToSet("withCredentials", "XMLHttpRequest", "the value may only be set if th e object's state is UNSENT or OPENED.")); 450 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f ailedToSet("withCredentials", "XMLHttpRequest", "The value may only be set if th e object's state is UNSENT or OPENED."));
451 return; 451 return;
452 } 452 }
453 453
454 m_includeCredentials = value; 454 m_includeCredentials = value;
455 } 455 }
456 456
457 bool XMLHttpRequest::isAllowedHTTPMethod(const String& method) 457 bool XMLHttpRequest::isAllowedHTTPMethod(const String& method)
458 { 458 {
459 return !equalIgnoringCase(method, "TRACE") 459 return !equalIgnoringCase(method, "TRACE")
460 && !equalIgnoringCase(method, "TRACK") 460 && !equalIgnoringCase(method, "TRACK")
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 m_error = false; 514 m_error = false;
515 m_uploadComplete = false; 515 m_uploadComplete = false;
516 516
517 // clear stuff from possible previous load 517 // clear stuff from possible previous load
518 clearResponse(); 518 clearResponse();
519 clearRequest(); 519 clearRequest();
520 520
521 ASSERT(m_state == UNSENT); 521 ASSERT(m_state == UNSENT);
522 522
523 if (!isValidHTTPToken(method)) { 523 if (!isValidHTTPToken(method)) {
524 exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedT oExecute("open", "XMLHttpRequest", "'" + method + "' is not a valid HTTP method. ")); 524 exceptionState.throwDOMException(SyntaxError, "'" + method + "' is not a valid HTTP method.");
525 return; 525 return;
526 } 526 }
527 527
528 if (!isAllowedHTTPMethod(method)) { 528 if (!isAllowedHTTPMethod(method)) {
529 exceptionState.throwSecurityError(ExceptionMessages::failedToExecute("op en", "XMLHttpRequest", "'" + method + "' HTTP method is unsupported.")); 529 exceptionState.throwSecurityError("'" + method + "' HTTP method is unsup ported.");
530 return; 530 return;
531 } 531 }
532 532
533 if (!ContentSecurityPolicy::shouldBypassMainWorld(executionContext()) && !ex ecutionContext()->contentSecurityPolicy()->allowConnectToSource(url)) { 533 if (!ContentSecurityPolicy::shouldBypassMainWorld(executionContext()) && !ex ecutionContext()->contentSecurityPolicy()->allowConnectToSource(url)) {
534 // We can safely expose the URL to JavaScript, as these checks happen sy nchronously before redirection. JavaScript receives no new information. 534 // We can safely expose the URL to JavaScript, as these checks happen sy nchronously before redirection. JavaScript receives no new information.
535 exceptionState.throwSecurityError("Refused to connect to '" + url.elided String() + "' because it violates the document's Content Security Policy."); 535 exceptionState.throwSecurityError("Refused to connect to '" + url.elided String() + "' because it violates the document's Content Security Policy.");
536 return; 536 return;
537 } 537 }
538 538
539 if (!async && executionContext()->isDocument()) { 539 if (!async && executionContext()->isDocument()) {
540 if (document()->settings() && !document()->settings()->syncXHRInDocument sEnabled()) { 540 if (document()->settings() && !document()->settings()->syncXHRInDocument sEnabled()) {
541 exceptionState.throwDOMException(InvalidAccessError, ExceptionMessag es::failedToExecute("open", "XMLHttpRequest", "synchronous requests are disabled for this page.")); 541 exceptionState.throwDOMException(InvalidAccessError, "Synchronous re quests are disabled for this page.");
542 return; 542 return;
543 } 543 }
544 544
545 // Newer functionality is not available to synchronous requests in windo w contexts, as a spec-mandated 545 // Newer functionality is not available to synchronous requests in windo w contexts, as a spec-mandated
546 // attempt to discourage synchronous XHR use. responseType is one such p iece of functionality. 546 // attempt to discourage synchronous XHR use. responseType is one such p iece of functionality.
547 // We'll only disable this functionality for HTTP(S) requests since sync requests for local protocols 547 // We'll only disable this functionality for HTTP(S) requests since sync requests for local protocols
548 // such as file: and data: still make sense to allow. 548 // such as file: and data: still make sense to allow.
549 if (url.protocolIsInHTTPFamily() && m_responseTypeCode != ResponseTypeDe fault) { 549 if (url.protocolIsInHTTPFamily() && m_responseTypeCode != ResponseTypeDe fault) {
550 exceptionState.throwDOMException(InvalidAccessError, ExceptionMessag es::failedToExecute("open", "XMLHttpRequest", "synchronous HTTP requests from a document must not set a response type.")); 550 exceptionState.throwDOMException(InvalidAccessError, "Synchronous HT TP requests from a document must not set a response type.");
551 return; 551 return;
552 } 552 }
553 553
554 // Similarly, timeouts are disabled for synchronous requests as well. 554 // Similarly, timeouts are disabled for synchronous requests as well.
555 if (m_timeoutMilliseconds > 0) { 555 if (m_timeoutMilliseconds > 0) {
556 exceptionState.throwDOMException(InvalidAccessError, ExceptionMessag es::failedToExecute("open", "XMLHttpRequest", "synchronous requests must not set a timeout.")); 556 exceptionState.throwDOMException(InvalidAccessError, "Synchronous re quests must not set a timeout.");
557 return; 557 return;
558 } 558 }
559 } 559 }
560 560
561 m_method = uppercaseKnownHTTPMethod(method); 561 m_method = uppercaseKnownHTTPMethod(method);
562 562
563 m_url = url; 563 m_url = url;
564 564
565 m_async = async; 565 m_async = async;
566 566
(...skipping 23 matching lines...) Expand all
590 590
591 open(method, urlWithCredentials, async, exceptionState); 591 open(method, urlWithCredentials, async, exceptionState);
592 } 592 }
593 593
594 bool XMLHttpRequest::initSend(ExceptionState& exceptionState) 594 bool XMLHttpRequest::initSend(ExceptionState& exceptionState)
595 { 595 {
596 if (!executionContext()) 596 if (!executionContext())
597 return false; 597 return false;
598 598
599 if (m_state != OPENED || m_loader) { 599 if (m_state != OPENED || m_loader) {
600 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f ailedToExecute("send", "XMLHttpRequest", "the object's state must be OPENED.")); 600 exceptionState.throwDOMException(InvalidStateError, "The object's state must be OPENED.");
601 return false; 601 return false;
602 } 602 }
603 603
604 m_error = false; 604 m_error = false;
605 return true; 605 return true;
606 } 606 }
607 607
608 void XMLHttpRequest::send(ExceptionState& exceptionState) 608 void XMLHttpRequest::send(ExceptionState& exceptionState)
609 { 609 {
610 send(String(), exceptionState); 610 send(String(), exceptionState);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 { 757 {
758 m_requestEntityBody = formData ? formData->deepCopy() : 0; 758 m_requestEntityBody = formData ? formData->deepCopy() : 0;
759 createRequest(exceptionState); 759 createRequest(exceptionState);
760 m_exceptionCode = exceptionState.code(); 760 m_exceptionCode = exceptionState.code();
761 } 761 }
762 762
763 void XMLHttpRequest::createRequest(ExceptionState& exceptionState) 763 void XMLHttpRequest::createRequest(ExceptionState& exceptionState)
764 { 764 {
765 // Only GET request is supported for blob URL. 765 // Only GET request is supported for blob URL.
766 if (m_url.protocolIs("blob") && m_method != "GET") { 766 if (m_url.protocolIs("blob") && m_method != "GET") {
767 exceptionState.throwDOMException(NetworkError, ExceptionMessages::failed ToExecute("send", "XMLHttpRequest", "'GET' is the only method allowed for 'blob: ' URLs.")); 767 exceptionState.throwDOMException(NetworkError, "'GET' is the only method allowed for 'blob:' URLs.");
768 return; 768 return;
769 } 769 }
770 770
771 // The presence of upload event listeners forces us to use preflighting beca use POSTing to an URL that does not 771 // The presence of upload event listeners forces us to use preflighting beca use POSTing to an URL that does not
772 // permit cross origin requests should look exactly like POSTing to an URL t hat does not respond at all. 772 // permit cross origin requests should look exactly like POSTing to an URL t hat does not respond at all.
773 // Also, only async requests support upload progress events. 773 // Also, only async requests support upload progress events.
774 bool uploadEvents = false; 774 bool uploadEvents = false;
775 if (m_async) { 775 if (m_async) {
776 m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::creat e(EventTypeNames::loadstart)); 776 m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::creat e(EventTypeNames::loadstart));
777 if (m_requestEntityBody && m_upload) { 777 if (m_requestEntityBody && m_upload) {
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
1049 } 1049 }
1050 1050
1051 void XMLHttpRequest::overrideMimeType(const String& override) 1051 void XMLHttpRequest::overrideMimeType(const String& override)
1052 { 1052 {
1053 m_mimeTypeOverride = override; 1053 m_mimeTypeOverride = override;
1054 } 1054 }
1055 1055
1056 void XMLHttpRequest::setRequestHeader(const AtomicString& name, const String& va lue, ExceptionState& exceptionState) 1056 void XMLHttpRequest::setRequestHeader(const AtomicString& name, const String& va lue, ExceptionState& exceptionState)
1057 { 1057 {
1058 if (m_state != OPENED || m_loader) { 1058 if (m_state != OPENED || m_loader) {
1059 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f ailedToExecute("setRequestHeader", "XMLHttpRequest", "the object's state must be OPENED.")); 1059 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f ailedToExecute("setRequestHeader", "XMLHttpRequest", "The object's state must be OPENED."));
1060 return; 1060 return;
1061 } 1061 }
1062 1062
1063 if (!isValidHTTPToken(name)) { 1063 if (!isValidHTTPToken(name)) {
1064 exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedT oExecute("setRequestHeader", "XMLHttpRequest", "'" + name + "' is not a valid HT TP header field name.")); 1064 exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedT oExecute("setRequestHeader", "XMLHttpRequest", "'" + name + "' is not a valid HT TP header field name."));
1065 return; 1065 return;
1066 } 1066 }
1067 1067
1068 if (!isValidHTTPHeaderValue(value)) { 1068 if (!isValidHTTPHeaderValue(value)) {
1069 exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedT oExecute("setRequestHeader", "XMLHttpRequest", "'" + value + "' is not a valid H TTP header field value.")); 1069 exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedT oExecute("setRequestHeader", "XMLHttpRequest", "'" + value + "' is not a valid H TTP header field value."));
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 { 1394 {
1395 return EventTargetNames::XMLHttpRequest; 1395 return EventTargetNames::XMLHttpRequest;
1396 } 1396 }
1397 1397
1398 ExecutionContext* XMLHttpRequest::executionContext() const 1398 ExecutionContext* XMLHttpRequest::executionContext() const
1399 { 1399 {
1400 return ActiveDOMObject::executionContext(); 1400 return ActiveDOMObject::executionContext();
1401 } 1401 }
1402 1402
1403 } // namespace WebCore 1403 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/bindings/v8/custom/V8XMLHttpRequestCustom.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698