OLD | NEW |
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 |
11 * version 2 of the License, or (at your option) any later version. | 11 * version 2 of the License, or (at your option) any later version. |
12 * | 12 * |
13 * This library is distributed in the hope that it will be useful, | 13 * This library is distributed in the hope that it will be useful, |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 * Lesser General Public License for more details. | 16 * Lesser General Public License for more details. |
17 * | 17 * |
18 * You should have received a copy of the GNU Lesser General Public | 18 * You should have received a copy of the GNU Lesser General Public |
19 * License along with this library; if not, write to the Free Software | 19 * License along with this library; if not, write to the Free Software |
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 U
SA | 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 U
SA |
21 */ | 21 */ |
22 | 22 |
23 #include "config.h" | 23 #include "config.h" |
24 #include "core/xml/XMLHttpRequest.h" | 24 #include "core/xml/XMLHttpRequest.h" |
25 | 25 |
26 #include "FetchInitiatorTypeNames.h" | 26 #include "FetchInitiatorTypeNames.h" |
| 27 #include "bindings/v8/ExceptionMessages.h" |
27 #include "bindings/v8/ExceptionState.h" | 28 #include "bindings/v8/ExceptionState.h" |
28 #include "core/dom/ContextFeatures.h" | 29 #include "core/dom/ContextFeatures.h" |
29 #include "core/dom/DOMImplementation.h" | 30 #include "core/dom/DOMImplementation.h" |
30 #include "core/dom/Event.h" | 31 #include "core/dom/Event.h" |
31 #include "core/dom/EventListener.h" | 32 #include "core/dom/EventListener.h" |
32 #include "core/dom/EventNames.h" | 33 #include "core/dom/EventNames.h" |
33 #include "core/dom/ExceptionCode.h" | 34 #include "core/dom/ExceptionCode.h" |
34 #include "core/editing/markup.h" | 35 #include "core/editing/markup.h" |
35 #include "core/fileapi/Blob.h" | 36 #include "core/fileapi/Blob.h" |
36 #include "core/fileapi/File.h" | 37 #include "core/fileapi/File.h" |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 } | 209 } |
209 | 210 |
210 XMLHttpRequest::State XMLHttpRequest::readyState() const | 211 XMLHttpRequest::State XMLHttpRequest::readyState() const |
211 { | 212 { |
212 return m_state; | 213 return m_state; |
213 } | 214 } |
214 | 215 |
215 ScriptString XMLHttpRequest::responseText(ExceptionState& es) | 216 ScriptString XMLHttpRequest::responseText(ExceptionState& es) |
216 { | 217 { |
217 if (m_responseTypeCode != ResponseTypeDefault && m_responseTypeCode != Respo
nseTypeText) { | 218 if (m_responseTypeCode != ResponseTypeDefault && m_responseTypeCode != Respo
nseTypeText) { |
218 es.throwDOMException(InvalidStateError); | 219 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToGet("
responseText", "XMLHttpRequest", "the value is only accessible if the object's '
responseType' is '' or 'text' (was '" + responseType() + "').")); |
219 return ScriptString(); | 220 return ScriptString(); |
220 } | 221 } |
221 if (m_error || (m_state != LOADING && m_state != DONE)) | 222 if (m_error || (m_state != LOADING && m_state != DONE)) |
222 return ScriptString(); | 223 return ScriptString(); |
223 return m_responseText; | 224 return m_responseText; |
224 } | 225 } |
225 | 226 |
226 Document* XMLHttpRequest::responseXML(ExceptionState& es) | 227 Document* XMLHttpRequest::responseXML(ExceptionState& es) |
227 { | 228 { |
228 if (m_responseTypeCode != ResponseTypeDefault && m_responseTypeCode != Respo
nseTypeDocument) { | 229 if (m_responseTypeCode != ResponseTypeDefault && m_responseTypeCode != Respo
nseTypeDocument) { |
229 es.throwDOMException(InvalidStateError); | 230 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToGet("
responseXML", "XMLHttpRequest", "the value is only accessible if the object's 'r
esponseType' is '' or 'document' (was '" + responseType() + "').")); |
230 return 0; | 231 return 0; |
231 } | 232 } |
232 | 233 |
233 if (m_error || m_state != DONE) | 234 if (m_error || m_state != DONE) |
234 return 0; | 235 return 0; |
235 | 236 |
236 if (!m_createdDocument) { | 237 if (!m_createdDocument) { |
237 bool isHTML = equalIgnoringCase(responseMIMEType(), "text/html"); | 238 bool isHTML = equalIgnoringCase(responseMIMEType(), "text/html"); |
238 | 239 |
239 // The W3C spec requires the final MIME type to be some valid XML type,
or text/html. | 240 // The W3C spec requires the final MIME type to be some valid XML type,
or text/html. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 } | 307 } |
307 | 308 |
308 return m_responseArrayBuffer.get(); | 309 return m_responseArrayBuffer.get(); |
309 } | 310 } |
310 | 311 |
311 void XMLHttpRequest::setTimeout(unsigned long timeout, ExceptionState& es) | 312 void XMLHttpRequest::setTimeout(unsigned long timeout, ExceptionState& es) |
312 { | 313 { |
313 // FIXME: Need to trigger or update the timeout Timer here, if needed. http:
//webkit.org/b/98156 | 314 // FIXME: Need to trigger or update the timeout Timer here, if needed. http:
//webkit.org/b/98156 |
314 // 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." | 315 // 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." |
315 if (scriptExecutionContext()->isDocument() && !m_async) { | 316 if (scriptExecutionContext()->isDocument() && !m_async) { |
316 logConsoleError(scriptExecutionContext(), "XMLHttpRequest.timeout cannot
be set for synchronous HTTP(S) requests made from the window context."); | 317 es.throwDOMException(InvalidAccessError, ExceptionMessages::failedToSet(
"timeout", "XMLHttpRequest", "timeouts cannot be set for synchronous requests ma
de from a document.")); |
317 es.throwDOMException(InvalidAccessError); | |
318 return; | 318 return; |
319 } | 319 } |
320 m_timeoutMilliseconds = timeout; | 320 m_timeoutMilliseconds = timeout; |
321 } | 321 } |
322 | 322 |
323 void XMLHttpRequest::setResponseType(const String& responseType, ExceptionState&
es) | 323 void XMLHttpRequest::setResponseType(const String& responseType, ExceptionState&
es) |
324 { | 324 { |
325 if (m_state >= LOADING) { | 325 if (m_state >= LOADING) { |
326 es.throwDOMException(InvalidStateError); | 326 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToSet("
responseType", "XMLHttpRequest", "the response type cannot be set if the object'
s state is LOADING or DONE.")); |
327 return; | 327 return; |
328 } | 328 } |
329 | 329 |
330 // Newer functionality is not available to synchronous requests in window co
ntexts, as a spec-mandated | 330 // Newer functionality is not available to synchronous requests in window co
ntexts, as a spec-mandated |
331 // attempt to discourage synchronous XHR use. responseType is one such piece
of functionality. | 331 // attempt to discourage synchronous XHR use. responseType is one such piece
of functionality. |
332 // We'll only disable this functionality for HTTP(S) requests since sync req
uests for local protocols | 332 // We'll only disable this functionality for HTTP(S) requests since sync req
uests for local protocols |
333 // such as file: and data: still make sense to allow. | 333 // such as file: and data: still make sense to allow. |
334 if (!m_async && scriptExecutionContext()->isDocument() && m_url.protocolIsIn
HTTPFamily()) { | 334 if (!m_async && scriptExecutionContext()->isDocument() && m_url.protocolIsIn
HTTPFamily()) { |
335 logConsoleError(scriptExecutionContext(), "XMLHttpRequest.responseType c
annot be changed for synchronous HTTP(S) requests made from the window context."
); | 335 es.throwDOMException(InvalidAccessError, ExceptionMessages::failedToSet(
"responseType", "XMLHttpRequest", "the response type can only be changed for asy
nchronous HTTP requests made from a document.")); |
336 es.throwDOMException(InvalidAccessError); | |
337 return; | 336 return; |
338 } | 337 } |
339 | 338 |
340 if (responseType == "") | 339 if (responseType == "") |
341 m_responseTypeCode = ResponseTypeDefault; | 340 m_responseTypeCode = ResponseTypeDefault; |
342 else if (responseType == "text") | 341 else if (responseType == "text") |
343 m_responseTypeCode = ResponseTypeText; | 342 m_responseTypeCode = ResponseTypeText; |
344 else if (responseType == "document") | 343 else if (responseType == "document") |
345 m_responseTypeCode = ResponseTypeDocument; | 344 m_responseTypeCode = ResponseTypeDocument; |
346 else if (responseType == "blob") | 345 else if (responseType == "blob") |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDi
spatchXHRLoadEvent(scriptExecutionContext(), this); | 397 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDi
spatchXHRLoadEvent(scriptExecutionContext(), this); |
399 m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::creat
e(eventNames().loadEvent)); | 398 m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::creat
e(eventNames().loadEvent)); |
400 InspectorInstrumentation::didDispatchXHRLoadEvent(cookie); | 399 InspectorInstrumentation::didDispatchXHRLoadEvent(cookie); |
401 m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::creat
e(eventNames().loadendEvent)); | 400 m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::creat
e(eventNames().loadendEvent)); |
402 } | 401 } |
403 } | 402 } |
404 | 403 |
405 void XMLHttpRequest::setWithCredentials(bool value, ExceptionState& es) | 404 void XMLHttpRequest::setWithCredentials(bool value, ExceptionState& es) |
406 { | 405 { |
407 if (m_state > OPENED || m_loader) { | 406 if (m_state > OPENED || m_loader) { |
408 es.throwDOMException(InvalidStateError); | 407 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToSet("
withCredentials", "XMLHttpRequest", "the value may only be set if the object's s
tate is UNSENT or OPENED.")); |
409 return; | 408 return; |
410 } | 409 } |
411 | 410 |
412 m_includeCredentials = value; | 411 m_includeCredentials = value; |
413 } | 412 } |
414 | 413 |
415 bool XMLHttpRequest::isAllowedHTTPMethod(const String& method) | 414 bool XMLHttpRequest::isAllowedHTTPMethod(const String& method) |
416 { | 415 { |
417 return !equalIgnoringCase(method, "TRACE") | 416 return !equalIgnoringCase(method, "TRACE") |
418 && !equalIgnoringCase(method, "TRACK") | 417 && !equalIgnoringCase(method, "TRACK") |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 m_error = false; | 450 m_error = false; |
452 m_uploadComplete = false; | 451 m_uploadComplete = false; |
453 | 452 |
454 // clear stuff from possible previous load | 453 // clear stuff from possible previous load |
455 clearResponse(); | 454 clearResponse(); |
456 clearRequest(); | 455 clearRequest(); |
457 | 456 |
458 ASSERT(m_state == UNSENT); | 457 ASSERT(m_state == UNSENT); |
459 | 458 |
460 if (!isValidHTTPToken(method)) { | 459 if (!isValidHTTPToken(method)) { |
461 es.throwDOMException(SyntaxError); | 460 es.throwDOMException(SyntaxError, ExceptionMessages::failedToExecute("op
en", "XMLHttpRequest", "'" + method + "' is not a valid HTTP method.")); |
462 return; | 461 return; |
463 } | 462 } |
464 | 463 |
465 if (!isAllowedHTTPMethod(method)) { | 464 if (!isAllowedHTTPMethod(method)) { |
466 es.throwDOMException(SecurityError, "'XMLHttpRequest.open' does not supp
ort the '" + method + "' method."); | 465 es.throwDOMException(SecurityError, ExceptionMessages::failedToExecute("
open", "XMLHttpRequest", "'" + method + "' HTTP method is unsupported.")); |
467 return; | 466 return; |
468 } | 467 } |
469 | 468 |
470 if (!ContentSecurityPolicy::shouldBypassMainWorld(scriptExecutionContext())
&& !scriptExecutionContext()->contentSecurityPolicy()->allowConnectToSource(url)
) { | 469 if (!ContentSecurityPolicy::shouldBypassMainWorld(scriptExecutionContext())
&& !scriptExecutionContext()->contentSecurityPolicy()->allowConnectToSource(url)
) { |
471 es.throwDOMException(SecurityError, "Refused to connect to '" + url.elid
edString() + "' because it violates the document's Content Security Policy."); | 470 es.throwDOMException(SecurityError, "Refused to connect to '" + url.elid
edString() + "' because it violates the document's Content Security Policy."); |
472 return; | 471 return; |
473 } | 472 } |
474 | 473 |
475 if (!async && scriptExecutionContext()->isDocument()) { | 474 if (!async && scriptExecutionContext()->isDocument()) { |
476 if (document()->settings() && !document()->settings()->syncXHRInDocument
sEnabled()) { | 475 if (document()->settings() && !document()->settings()->syncXHRInDocument
sEnabled()) { |
477 logConsoleError(scriptExecutionContext(), "Synchronous XMLHttpReques
ts are disabled for this page."); | 476 es.throwDOMException(InvalidAccessError, ExceptionMessages::failedTo
Execute("open", "XMLHttpRequest", "synchronous requests are disabled for this pa
ge.")); |
478 es.throwDOMException(InvalidAccessError); | |
479 return; | 477 return; |
480 } | 478 } |
481 | 479 |
482 // Newer functionality is not available to synchronous requests in windo
w contexts, as a spec-mandated | 480 // Newer functionality is not available to synchronous requests in windo
w contexts, as a spec-mandated |
483 // attempt to discourage synchronous XHR use. responseType is one such p
iece of functionality. | 481 // attempt to discourage synchronous XHR use. responseType is one such p
iece of functionality. |
484 // We'll only disable this functionality for HTTP(S) requests since sync
requests for local protocols | 482 // We'll only disable this functionality for HTTP(S) requests since sync
requests for local protocols |
485 // such as file: and data: still make sense to allow. | 483 // such as file: and data: still make sense to allow. |
486 if (url.protocolIsInHTTPFamily() && m_responseTypeCode != ResponseTypeDe
fault) { | 484 if (url.protocolIsInHTTPFamily() && m_responseTypeCode != ResponseTypeDe
fault) { |
487 logConsoleError(scriptExecutionContext(), "Synchronous HTTP(S) reque
sts made from the window context cannot have XMLHttpRequest.responseType set."); | 485 es.throwDOMException(InvalidAccessError, ExceptionMessages::failedTo
Execute("open", "XMLHttpRequest", "synchronous HTTP requests from a document mus
t not set a response type.")); |
488 es.throwDOMException(InvalidAccessError); | |
489 return; | 486 return; |
490 } | 487 } |
491 | 488 |
492 // Similarly, timeouts are disabled for synchronous requests as well. | 489 // Similarly, timeouts are disabled for synchronous requests as well. |
493 if (m_timeoutMilliseconds > 0) { | 490 if (m_timeoutMilliseconds > 0) { |
494 logConsoleError(scriptExecutionContext(), "Synchronous XMLHttpReques
ts must not have a timeout value set."); | 491 es.throwDOMException(InvalidAccessError, ExceptionMessages::failedTo
Execute("open", "XMLHttpRequest", "synchronous requests must not set a timeout."
)); |
495 es.throwDOMException(InvalidAccessError); | |
496 return; | 492 return; |
497 } | 493 } |
498 } | 494 } |
499 | 495 |
500 m_method = uppercaseKnownHTTPMethod(method); | 496 m_method = uppercaseKnownHTTPMethod(method); |
501 | 497 |
502 m_url = url; | 498 m_url = url; |
503 | 499 |
504 m_async = async; | 500 m_async = async; |
505 | 501 |
(...skipping 23 matching lines...) Expand all Loading... |
529 | 525 |
530 open(method, urlWithCredentials, async, es); | 526 open(method, urlWithCredentials, async, es); |
531 } | 527 } |
532 | 528 |
533 bool XMLHttpRequest::initSend(ExceptionState& es) | 529 bool XMLHttpRequest::initSend(ExceptionState& es) |
534 { | 530 { |
535 if (!scriptExecutionContext()) | 531 if (!scriptExecutionContext()) |
536 return false; | 532 return false; |
537 | 533 |
538 if (m_state != OPENED || m_loader) { | 534 if (m_state != OPENED || m_loader) { |
539 es.throwDOMException(InvalidStateError); | 535 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("send", "XMLHttpRequest", "the object's state must be OPENED.")); |
540 return false; | 536 return false; |
541 } | 537 } |
542 | 538 |
543 m_error = false; | 539 m_error = false; |
544 return true; | 540 return true; |
545 } | 541 } |
546 | 542 |
547 void XMLHttpRequest::send(ExceptionState& es) | 543 void XMLHttpRequest::send(ExceptionState& es) |
548 { | 544 { |
549 send(String(), es); | 545 send(String(), es); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 { | 680 { |
685 m_requestEntityBody = formData ? formData->deepCopy() : 0; | 681 m_requestEntityBody = formData ? formData->deepCopy() : 0; |
686 createRequest(es); | 682 createRequest(es); |
687 m_exceptionCode = es.code(); | 683 m_exceptionCode = es.code(); |
688 } | 684 } |
689 | 685 |
690 void XMLHttpRequest::createRequest(ExceptionState& es) | 686 void XMLHttpRequest::createRequest(ExceptionState& es) |
691 { | 687 { |
692 // Only GET request is supported for blob URL. | 688 // Only GET request is supported for blob URL. |
693 if (m_url.protocolIs("blob") && m_method != "GET") { | 689 if (m_url.protocolIs("blob") && m_method != "GET") { |
694 es.throwDOMException(NetworkError); | 690 es.throwDOMException(NetworkError, ExceptionMessages::failedToExecute("s
end", "XMLHttpRequest", "'GET' is the only method allowed for 'blob:' URLs.")); |
695 return; | 691 return; |
696 } | 692 } |
697 | 693 |
698 // The presence of upload event listeners forces us to use preflighting beca
use POSTing to an URL that does not | 694 // The presence of upload event listeners forces us to use preflighting beca
use POSTing to an URL that does not |
699 // permit cross origin requests should look exactly like POSTing to an URL t
hat does not respond at all. | 695 // permit cross origin requests should look exactly like POSTing to an URL t
hat does not respond at all. |
700 // Also, only async requests support upload progress events. | 696 // Also, only async requests support upload progress events. |
701 bool uploadEvents = false; | 697 bool uploadEvents = false; |
702 if (m_async) { | 698 if (m_async) { |
703 m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::creat
e(eventNames().loadstartEvent)); | 699 m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::creat
e(eventNames().loadstartEvent)); |
704 if (m_requestEntityBody && m_upload) { | 700 if (m_requestEntityBody && m_upload) { |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
891 } | 887 } |
892 | 888 |
893 void XMLHttpRequest::overrideMimeType(const String& override) | 889 void XMLHttpRequest::overrideMimeType(const String& override) |
894 { | 890 { |
895 m_mimeTypeOverride = override; | 891 m_mimeTypeOverride = override; |
896 } | 892 } |
897 | 893 |
898 void XMLHttpRequest::setRequestHeader(const AtomicString& name, const String& va
lue, ExceptionState& es) | 894 void XMLHttpRequest::setRequestHeader(const AtomicString& name, const String& va
lue, ExceptionState& es) |
899 { | 895 { |
900 if (m_state != OPENED || m_loader) { | 896 if (m_state != OPENED || m_loader) { |
901 es.throwDOMException(InvalidStateError); | 897 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("setRequestHeader", "XMLHttpRequest", "the object's state must be OPENED.")); |
902 return; | 898 return; |
903 } | 899 } |
904 | 900 |
905 if (!isValidHTTPToken(name) || !isValidHTTPHeaderValue(value)) { | 901 if (!isValidHTTPToken(name)) { |
906 es.throwDOMException(SyntaxError); | 902 es.throwDOMException(SyntaxError, ExceptionMessages::failedToExecute("se
tRequestHeader", "XMLHttpRequest", "'" + name + "' is not a valid HTTP header fi
eld name.")); |
907 return; | 903 return; |
908 } | 904 } |
909 | 905 |
| 906 if (!isValidHTTPHeaderValue(value)) { |
| 907 es.throwDOMException(SyntaxError, ExceptionMessages::failedToExecute("se
tRequestHeader", "XMLHttpRequest", "'" + value + "' is not a valid HTTP header f
ield value.")); |
| 908 return; |
| 909 } |
| 910 |
910 // No script (privileged or not) can set unsafe headers. | 911 // No script (privileged or not) can set unsafe headers. |
911 if (!isAllowedHTTPHeader(name)) { | 912 if (!isAllowedHTTPHeader(name)) { |
912 logConsoleError(scriptExecutionContext(), "Refused to set unsafe header
\"" + name + "\""); | 913 logConsoleError(scriptExecutionContext(), "Refused to set unsafe header
\"" + name + "\""); |
913 return; | 914 return; |
914 } | 915 } |
915 | 916 |
916 setRequestHeaderInternal(name, value); | 917 setRequestHeaderInternal(name, value); |
917 } | 918 } |
918 | 919 |
919 void XMLHttpRequest::setRequestHeaderInternal(const AtomicString& name, const St
ring& value) | 920 void XMLHttpRequest::setRequestHeaderInternal(const AtomicString& name, const St
ring& value) |
920 { | 921 { |
921 HTTPHeaderMap::AddResult result = m_requestHeaders.add(name, value); | 922 HTTPHeaderMap::AddResult result = m_requestHeaders.add(name, value); |
922 if (!result.isNewEntry) | 923 if (!result.isNewEntry) |
923 result.iterator->value = result.iterator->value + ", " + value; | 924 result.iterator->value = result.iterator->value + ", " + value; |
924 } | 925 } |
925 | 926 |
926 String XMLHttpRequest::getRequestHeader(const AtomicString& name) const | 927 String XMLHttpRequest::getRequestHeader(const AtomicString& name) const |
927 { | 928 { |
928 return m_requestHeaders.get(name); | 929 return m_requestHeaders.get(name); |
929 } | 930 } |
930 | 931 |
931 String XMLHttpRequest::getAllResponseHeaders(ExceptionState& es) const | 932 String XMLHttpRequest::getAllResponseHeaders(ExceptionState& es) const |
932 { | 933 { |
933 if (m_state < HEADERS_RECEIVED) { | 934 if (m_state < HEADERS_RECEIVED) { |
934 es.throwDOMException(InvalidStateError); | 935 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("getAllResponseHeaders", "XMLHttpRequest", "the object's state must not be UN
SENT or OPENED.")); |
935 return ""; | 936 return ""; |
936 } | 937 } |
937 | 938 |
938 StringBuilder stringBuilder; | 939 StringBuilder stringBuilder; |
939 | 940 |
940 HTTPHeaderSet accessControlExposeHeaderSet; | 941 HTTPHeaderSet accessControlExposeHeaderSet; |
941 parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField("Access-
Control-Expose-Headers"), accessControlExposeHeaderSet); | 942 parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField("Access-
Control-Expose-Headers"), accessControlExposeHeaderSet); |
942 HTTPHeaderMap::const_iterator end = m_response.httpHeaderFields().end(); | 943 HTTPHeaderMap::const_iterator end = m_response.httpHeaderFields().end(); |
943 for (HTTPHeaderMap::const_iterator it = m_response.httpHeaderFields().begin(
); it!= end; ++it) { | 944 for (HTTPHeaderMap::const_iterator it = m_response.httpHeaderFields().begin(
); it!= end; ++it) { |
944 // Hide Set-Cookie header fields from the XMLHttpRequest client for thes
e reasons: | 945 // Hide Set-Cookie header fields from the XMLHttpRequest client for thes
e reasons: |
(...skipping 15 matching lines...) Expand all Loading... |
960 stringBuilder.append('\r'); | 961 stringBuilder.append('\r'); |
961 stringBuilder.append('\n'); | 962 stringBuilder.append('\n'); |
962 } | 963 } |
963 | 964 |
964 return stringBuilder.toString(); | 965 return stringBuilder.toString(); |
965 } | 966 } |
966 | 967 |
967 String XMLHttpRequest::getResponseHeader(const AtomicString& name, ExceptionStat
e& es) const | 968 String XMLHttpRequest::getResponseHeader(const AtomicString& name, ExceptionStat
e& es) const |
968 { | 969 { |
969 if (m_state < HEADERS_RECEIVED) { | 970 if (m_state < HEADERS_RECEIVED) { |
970 es.throwDOMException(InvalidStateError); | 971 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("getResponseHeader", "XMLHttpRequest", "the object's state must not be UNSENT
or OPENED.")); |
971 return String(); | 972 return String(); |
972 } | 973 } |
973 | 974 |
974 // See comment in getAllResponseHeaders above. | 975 // See comment in getAllResponseHeaders above. |
975 if (isSetCookieHeader(name) && !securityOrigin()->canLoadLocalResources()) { | 976 if (isSetCookieHeader(name) && !securityOrigin()->canLoadLocalResources()) { |
976 logConsoleError(scriptExecutionContext(), "Refused to get unsafe header
\"" + name + "\""); | 977 logConsoleError(scriptExecutionContext(), "Refused to get unsafe header
\"" + name + "\""); |
977 return String(); | 978 return String(); |
978 } | 979 } |
979 | 980 |
980 HTTPHeaderSet accessControlExposeHeaderSet; | 981 HTTPHeaderSet accessControlExposeHeaderSet; |
(...skipping 29 matching lines...) Expand all Loading... |
1010 } | 1011 } |
1011 | 1012 |
1012 int XMLHttpRequest::status(ExceptionState& es) const | 1013 int XMLHttpRequest::status(ExceptionState& es) const |
1013 { | 1014 { |
1014 if (m_response.httpStatusCode()) | 1015 if (m_response.httpStatusCode()) |
1015 return m_response.httpStatusCode(); | 1016 return m_response.httpStatusCode(); |
1016 | 1017 |
1017 if (m_state == OPENED) { | 1018 if (m_state == OPENED) { |
1018 // Firefox only raises an exception in this state; we match it. | 1019 // Firefox only raises an exception in this state; we match it. |
1019 // Note the case of local file requests, where we have no HTTP response
code! Firefox never raises an exception for those, but we match HTTP case for co
nsistency. | 1020 // Note the case of local file requests, where we have no HTTP response
code! Firefox never raises an exception for those, but we match HTTP case for co
nsistency. |
1020 es.throwDOMException(InvalidStateError); | 1021 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToGet("
status", "XMLHttpRequest", "the object's state must not be OPENED.")); |
1021 } | 1022 } |
1022 | 1023 |
1023 return 0; | 1024 return 0; |
1024 } | 1025 } |
1025 | 1026 |
1026 String XMLHttpRequest::statusText(ExceptionState& es) const | 1027 String XMLHttpRequest::statusText(ExceptionState& es) const |
1027 { | 1028 { |
1028 if (!m_response.httpStatusText().isNull()) | 1029 if (!m_response.httpStatusText().isNull()) |
1029 return m_response.httpStatusText(); | 1030 return m_response.httpStatusText(); |
1030 | 1031 |
1031 if (m_state == OPENED) { | 1032 if (m_state == OPENED) { |
1032 // See comments in status() above. | 1033 // See comments in status() above. |
1033 es.throwDOMException(InvalidStateError); | 1034 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToGet("
statusText", "XMLHttpRequest", "the object's state must not be OPENED.")); |
1034 } | 1035 } |
1035 | 1036 |
1036 return String(); | 1037 return String(); |
1037 } | 1038 } |
1038 | 1039 |
1039 void XMLHttpRequest::didFail(const ResourceError& error) | 1040 void XMLHttpRequest::didFail(const ResourceError& error) |
1040 { | 1041 { |
1041 | 1042 |
1042 // If we are already in an error state, for instance we called abort(), bail
out early. | 1043 // If we are already in an error state, for instance we called abort(), bail
out early. |
1043 if (m_error) | 1044 if (m_error) |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1245 { | 1246 { |
1246 return &m_eventTargetData; | 1247 return &m_eventTargetData; |
1247 } | 1248 } |
1248 | 1249 |
1249 EventTargetData* XMLHttpRequest::ensureEventTargetData() | 1250 EventTargetData* XMLHttpRequest::ensureEventTargetData() |
1250 { | 1251 { |
1251 return &m_eventTargetData; | 1252 return &m_eventTargetData; |
1252 } | 1253 } |
1253 | 1254 |
1254 } // namespace WebCore | 1255 } // namespace WebCore |
OLD | NEW |