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 |
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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") |
461 && !equalIgnoringCase(method, "CONNECT"); | 461 && !equalIgnoringCase(method, "CONNECT"); |
462 } | 462 } |
463 | 463 |
464 String XMLHttpRequest::uppercaseKnownHTTPMethod(const String& method) | 464 AtomicString XMLHttpRequest::uppercaseKnownHTTPMethod(const AtomicString& method
) |
465 { | 465 { |
466 const char* const methods[] = { | 466 const char* const methods[] = { |
467 "COPY", | 467 "COPY", |
468 "DELETE", | 468 "DELETE", |
469 "GET", | 469 "GET", |
470 "HEAD", | 470 "HEAD", |
471 "INDEX", | 471 "INDEX", |
472 "LOCK", | 472 "LOCK", |
473 "M-POST", | 473 "M-POST", |
474 "MKCOL", | 474 "MKCOL", |
(...skipping 15 matching lines...) Expand all Loading... |
490 return method; | 490 return method; |
491 } | 491 } |
492 | 492 |
493 bool XMLHttpRequest::isAllowedHTTPHeader(const String& name) | 493 bool XMLHttpRequest::isAllowedHTTPHeader(const String& name) |
494 { | 494 { |
495 initializeXMLHttpRequestStaticData(); | 495 initializeXMLHttpRequestStaticData(); |
496 return !staticData->m_forbiddenRequestHeaders.contains(name) && !name.starts
With(staticData->m_proxyHeaderPrefix, false) | 496 return !staticData->m_forbiddenRequestHeaders.contains(name) && !name.starts
With(staticData->m_proxyHeaderPrefix, false) |
497 && !name.startsWith(staticData->m_secHeaderPrefix, false); | 497 && !name.startsWith(staticData->m_secHeaderPrefix, false); |
498 } | 498 } |
499 | 499 |
500 void XMLHttpRequest::open(const String& method, const KURL& url, ExceptionState&
exceptionState) | 500 void XMLHttpRequest::open(const AtomicString& method, const KURL& url, Exception
State& exceptionState) |
501 { | 501 { |
502 open(method, url, true, exceptionState); | 502 open(method, url, true, exceptionState); |
503 } | 503 } |
504 | 504 |
505 void XMLHttpRequest::open(const String& method, const KURL& url, bool async, Exc
eptionState& exceptionState) | 505 void XMLHttpRequest::open(const AtomicString& method, const KURL& url, bool asyn
c, ExceptionState& exceptionState) |
506 { | 506 { |
507 WTF_LOG(Network, "XMLHttpRequest %p open('%s', '%s', %d)", this, method.utf8
().data(), url.elidedString().utf8().data(), async); | 507 WTF_LOG(Network, "XMLHttpRequest %p open('%s', '%s', %d)", this, method.stri
ng().utf8().data(), url.elidedString().utf8().data(), async); |
508 | 508 |
509 if (!internalAbort()) | 509 if (!internalAbort()) |
510 return; | 510 return; |
511 | 511 |
512 State previousState = m_state; | 512 State previousState = m_state; |
513 m_state = UNSENT; | 513 m_state = UNSENT; |
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 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 ASSERT(!m_loader); | 567 ASSERT(!m_loader); |
568 | 568 |
569 // Check previous state to avoid dispatching readyState event | 569 // Check previous state to avoid dispatching readyState event |
570 // when calling open several times in a row. | 570 // when calling open several times in a row. |
571 if (previousState != OPENED) | 571 if (previousState != OPENED) |
572 changeState(OPENED); | 572 changeState(OPENED); |
573 else | 573 else |
574 m_state = OPENED; | 574 m_state = OPENED; |
575 } | 575 } |
576 | 576 |
577 void XMLHttpRequest::open(const String& method, const KURL& url, bool async, con
st String& user, ExceptionState& exceptionState) | 577 void XMLHttpRequest::open(const AtomicString& method, const KURL& url, bool asyn
c, const String& user, ExceptionState& exceptionState) |
578 { | 578 { |
579 KURL urlWithCredentials(url); | 579 KURL urlWithCredentials(url); |
580 urlWithCredentials.setUser(user); | 580 urlWithCredentials.setUser(user); |
581 | 581 |
582 open(method, urlWithCredentials, async, exceptionState); | 582 open(method, urlWithCredentials, async, exceptionState); |
583 } | 583 } |
584 | 584 |
585 void XMLHttpRequest::open(const String& method, const KURL& url, bool async, con
st String& user, const String& password, ExceptionState& exceptionState) | 585 void XMLHttpRequest::open(const AtomicString& method, const KURL& url, bool asyn
c, const String& user, const String& password, ExceptionState& exceptionState) |
586 { | 586 { |
587 KURL urlWithCredentials(url); | 587 KURL urlWithCredentials(url); |
588 urlWithCredentials.setUser(user); | 588 urlWithCredentials.setUser(user); |
589 urlWithCredentials.setPass(password); | 589 urlWithCredentials.setPass(password); |
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 { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 | 650 |
651 if (!initSend(exceptionState)) | 651 if (!initSend(exceptionState)) |
652 return; | 652 return; |
653 | 653 |
654 if (!body.isNull() && areMethodAndURLValidForSend()) { | 654 if (!body.isNull() && areMethodAndURLValidForSend()) { |
655 String contentType = getRequestHeader("Content-Type"); | 655 String contentType = getRequestHeader("Content-Type"); |
656 if (contentType.isEmpty()) { | 656 if (contentType.isEmpty()) { |
657 setRequestHeaderInternal("Content-Type", "text/plain;charset=UTF-8")
; | 657 setRequestHeaderInternal("Content-Type", "text/plain;charset=UTF-8")
; |
658 } else { | 658 } else { |
659 replaceCharsetInMediaType(contentType, "UTF-8"); | 659 replaceCharsetInMediaType(contentType, "UTF-8"); |
660 m_requestHeaders.set("Content-Type", contentType); | 660 m_requestHeaders.set("Content-Type", AtomicString(contentType)); |
661 } | 661 } |
662 | 662 |
663 m_requestEntityBody = FormData::create(UTF8Encoding().encode(body, WTF::
EntitiesForUnencodables)); | 663 m_requestEntityBody = FormData::create(UTF8Encoding().encode(body, WTF::
EntitiesForUnencodables)); |
664 if (m_upload) | 664 if (m_upload) |
665 m_requestEntityBody->setAlwaysStream(true); | 665 m_requestEntityBody->setAlwaysStream(true); |
666 } | 666 } |
667 | 667 |
668 createRequest(exceptionState); | 668 createRequest(exceptionState); |
669 } | 669 } |
670 | 670 |
671 void XMLHttpRequest::send(Blob* body, ExceptionState& exceptionState) | 671 void XMLHttpRequest::send(Blob* body, ExceptionState& exceptionState) |
672 { | 672 { |
673 WTF_LOG(Network, "XMLHttpRequest %p send() Blob '%s'", this, body->uuid().ut
f8().data()); | 673 WTF_LOG(Network, "XMLHttpRequest %p send() Blob '%s'", this, body->uuid().ut
f8().data()); |
674 | 674 |
675 if (!initSend(exceptionState)) | 675 if (!initSend(exceptionState)) |
676 return; | 676 return; |
677 | 677 |
678 if (areMethodAndURLValidForSend()) { | 678 if (areMethodAndURLValidForSend()) { |
679 const String& contentType = getRequestHeader("Content-Type"); | 679 const String& contentType = getRequestHeader("Content-Type"); |
680 if (contentType.isEmpty()) { | 680 if (contentType.isEmpty()) { |
681 const String& blobType = body->type(); | 681 const String& blobType = body->type(); |
682 if (!blobType.isEmpty() && isValidContentType(blobType)) | 682 if (!blobType.isEmpty() && isValidContentType(blobType)) |
683 setRequestHeaderInternal("Content-Type", blobType); | 683 setRequestHeaderInternal("Content-Type", AtomicString(blobType))
; |
684 else { | 684 else { |
685 // From FileAPI spec, whenever media type cannot be determined,
empty string must be returned. | 685 // From FileAPI spec, whenever media type cannot be determined,
empty string must be returned. |
686 setRequestHeaderInternal("Content-Type", ""); | 686 setRequestHeaderInternal("Content-Type", ""); |
687 } | 687 } |
688 } | 688 } |
689 | 689 |
690 // FIXME: add support for uploading bundles. | 690 // FIXME: add support for uploading bundles. |
691 m_requestEntityBody = FormData::create(); | 691 m_requestEntityBody = FormData::create(); |
692 if (body->hasBackingFile()) | 692 if (body->hasBackingFile()) |
693 m_requestEntityBody->appendFile(toFile(body)->path()); | 693 m_requestEntityBody->appendFile(toFile(body)->path()); |
694 else | 694 else |
695 m_requestEntityBody->appendBlob(body->uuid(), body->blobDataHandle()
); | 695 m_requestEntityBody->appendBlob(body->uuid(), body->blobDataHandle()
); |
696 } | 696 } |
697 | 697 |
698 createRequest(exceptionState); | 698 createRequest(exceptionState); |
699 } | 699 } |
700 | 700 |
701 void XMLHttpRequest::send(DOMFormData* body, ExceptionState& exceptionState) | 701 void XMLHttpRequest::send(DOMFormData* body, ExceptionState& exceptionState) |
702 { | 702 { |
703 WTF_LOG(Network, "XMLHttpRequest %p send() DOMFormData %p", this, body); | 703 WTF_LOG(Network, "XMLHttpRequest %p send() DOMFormData %p", this, body); |
704 | 704 |
705 if (!initSend(exceptionState)) | 705 if (!initSend(exceptionState)) |
706 return; | 706 return; |
707 | 707 |
708 if (areMethodAndURLValidForSend()) { | 708 if (areMethodAndURLValidForSend()) { |
709 m_requestEntityBody = body->createMultiPartFormData(body->encoding()); | 709 m_requestEntityBody = body->createMultiPartFormData(body->encoding()); |
710 | 710 |
711 String contentType = getRequestHeader("Content-Type"); | 711 if (getRequestHeader("Content-Type").isEmpty()) { |
712 if (contentType.isEmpty()) { | 712 AtomicString contentType = AtomicString("multipart/form-data; bounda
ry=", AtomicString::ConstructFromLiteral) + m_requestEntityBody->boundary().data
(); |
713 contentType = String("multipart/form-data; boundary=") + m_requestEn
tityBody->boundary().data(); | |
714 setRequestHeaderInternal("Content-Type", contentType); | 713 setRequestHeaderInternal("Content-Type", contentType); |
715 } | 714 } |
716 } | 715 } |
717 | 716 |
718 createRequest(exceptionState); | 717 createRequest(exceptionState); |
719 } | 718 } |
720 | 719 |
721 void XMLHttpRequest::send(ArrayBuffer* body, ExceptionState& exceptionState) | 720 void XMLHttpRequest::send(ArrayBuffer* body, ExceptionState& exceptionState) |
722 { | 721 { |
723 WTF_LOG(Network, "XMLHttpRequest %p send() ArrayBuffer %p", this, body); | 722 WTF_LOG(Network, "XMLHttpRequest %p send() ArrayBuffer %p", this, body); |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1041 void XMLHttpRequest::dropProtectionSoon() | 1040 void XMLHttpRequest::dropProtectionSoon() |
1042 { | 1041 { |
1043 m_dropProtectionRunner.runAsync(); | 1042 m_dropProtectionRunner.runAsync(); |
1044 } | 1043 } |
1045 | 1044 |
1046 void XMLHttpRequest::dropProtection() | 1045 void XMLHttpRequest::dropProtection() |
1047 { | 1046 { |
1048 unsetPendingActivity(this); | 1047 unsetPendingActivity(this); |
1049 } | 1048 } |
1050 | 1049 |
1051 void XMLHttpRequest::overrideMimeType(const String& override) | 1050 void XMLHttpRequest::overrideMimeType(const AtomicString& override) |
1052 { | 1051 { |
1053 m_mimeTypeOverride = override; | 1052 m_mimeTypeOverride = override; |
1054 } | 1053 } |
1055 | 1054 |
1056 void XMLHttpRequest::setRequestHeader(const AtomicString& name, const String& va
lue, ExceptionState& exceptionState) | 1055 void XMLHttpRequest::setRequestHeader(const AtomicString& name, const AtomicStri
ng& value, ExceptionState& exceptionState) |
1057 { | 1056 { |
1058 if (m_state != OPENED || m_loader) { | 1057 if (m_state != OPENED || m_loader) { |
1059 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f
ailedToExecute("setRequestHeader", "XMLHttpRequest", "The object's state must be
OPENED.")); | 1058 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f
ailedToExecute("setRequestHeader", "XMLHttpRequest", "The object's state must be
OPENED.")); |
1060 return; | 1059 return; |
1061 } | 1060 } |
1062 | 1061 |
1063 if (!isValidHTTPToken(name)) { | 1062 if (!isValidHTTPToken(name)) { |
1064 exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedT
oExecute("setRequestHeader", "XMLHttpRequest", "'" + name + "' is not a valid HT
TP header field name.")); | 1063 exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedT
oExecute("setRequestHeader", "XMLHttpRequest", "'" + name + "' is not a valid HT
TP header field name.")); |
1065 return; | 1064 return; |
1066 } | 1065 } |
1067 | 1066 |
1068 if (!isValidHTTPHeaderValue(value)) { | 1067 if (!isValidHTTPHeaderValue(value)) { |
1069 exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedT
oExecute("setRequestHeader", "XMLHttpRequest", "'" + value + "' is not a valid H
TTP header field value.")); | 1068 exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedT
oExecute("setRequestHeader", "XMLHttpRequest", "'" + value + "' is not a valid H
TTP header field value.")); |
1070 return; | 1069 return; |
1071 } | 1070 } |
1072 | 1071 |
1073 // No script (privileged or not) can set unsafe headers. | 1072 // No script (privileged or not) can set unsafe headers. |
1074 if (!isAllowedHTTPHeader(name)) { | 1073 if (!isAllowedHTTPHeader(name)) { |
1075 logConsoleError(executionContext(), "Refused to set unsafe header \"" +
name + "\""); | 1074 logConsoleError(executionContext(), "Refused to set unsafe header \"" +
name + "\""); |
1076 return; | 1075 return; |
1077 } | 1076 } |
1078 | 1077 |
1079 setRequestHeaderInternal(name, value); | 1078 setRequestHeaderInternal(name, value); |
1080 } | 1079 } |
1081 | 1080 |
1082 void XMLHttpRequest::setRequestHeaderInternal(const AtomicString& name, const St
ring& value) | 1081 void XMLHttpRequest::setRequestHeaderInternal(const AtomicString& name, const At
omicString& value) |
1083 { | 1082 { |
1084 HTTPHeaderMap::AddResult result = m_requestHeaders.add(name, value); | 1083 HTTPHeaderMap::AddResult result = m_requestHeaders.add(name, value); |
1085 if (!result.isNewEntry) | 1084 if (!result.isNewEntry) |
1086 result.iterator->value = result.iterator->value + ", " + value; | 1085 result.iterator->value = result.iterator->value + ", " + value; |
1087 } | 1086 } |
1088 | 1087 |
1089 String XMLHttpRequest::getRequestHeader(const AtomicString& name) const | 1088 AtomicString XMLHttpRequest::getRequestHeader(const AtomicString& name) const |
1090 { | 1089 { |
1091 return m_requestHeaders.get(name); | 1090 return m_requestHeaders.get(name); |
1092 } | 1091 } |
1093 | 1092 |
1094 String XMLHttpRequest::getAllResponseHeaders(ExceptionState& exceptionState) con
st | 1093 String XMLHttpRequest::getAllResponseHeaders(ExceptionState& exceptionState) con
st |
1095 { | 1094 { |
1096 if (m_state < HEADERS_RECEIVED || m_error) | 1095 if (m_state < HEADERS_RECEIVED || m_error) |
1097 return ""; | 1096 return ""; |
1098 | 1097 |
1099 StringBuilder stringBuilder; | 1098 StringBuilder stringBuilder; |
(...skipping 18 matching lines...) Expand all Loading... |
1118 stringBuilder.append(':'); | 1117 stringBuilder.append(':'); |
1119 stringBuilder.append(' '); | 1118 stringBuilder.append(' '); |
1120 stringBuilder.append(it->value); | 1119 stringBuilder.append(it->value); |
1121 stringBuilder.append('\r'); | 1120 stringBuilder.append('\r'); |
1122 stringBuilder.append('\n'); | 1121 stringBuilder.append('\n'); |
1123 } | 1122 } |
1124 | 1123 |
1125 return stringBuilder.toString(); | 1124 return stringBuilder.toString(); |
1126 } | 1125 } |
1127 | 1126 |
1128 String XMLHttpRequest::getResponseHeader(const AtomicString& name, ExceptionStat
e& exceptionState) const | 1127 AtomicString XMLHttpRequest::getResponseHeader(const AtomicString& name, Excepti
onState& exceptionState) const |
1129 { | 1128 { |
1130 if (m_state < HEADERS_RECEIVED || m_error) | 1129 if (m_state < HEADERS_RECEIVED || m_error) |
1131 return String(); | 1130 return nullAtom; |
1132 | 1131 |
1133 // See comment in getAllResponseHeaders above. | 1132 // See comment in getAllResponseHeaders above. |
1134 if (isSetCookieHeader(name) && !securityOrigin()->canLoadLocalResources()) { | 1133 if (isSetCookieHeader(name) && !securityOrigin()->canLoadLocalResources()) { |
1135 logConsoleError(executionContext(), "Refused to get unsafe header \"" +
name + "\""); | 1134 logConsoleError(executionContext(), "Refused to get unsafe header \"" +
name + "\""); |
1136 return String(); | 1135 return nullAtom; |
1137 } | 1136 } |
1138 | 1137 |
1139 HTTPHeaderSet accessControlExposeHeaderSet; | 1138 HTTPHeaderSet accessControlExposeHeaderSet; |
1140 parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField("Access-
Control-Expose-Headers"), accessControlExposeHeaderSet); | 1139 parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField("Access-
Control-Expose-Headers"), accessControlExposeHeaderSet); |
1141 | 1140 |
1142 if (!m_sameOriginRequest && !isOnAccessControlResponseHeaderWhitelist(name)
&& !accessControlExposeHeaderSet.contains(name)) { | 1141 if (!m_sameOriginRequest && !isOnAccessControlResponseHeaderWhitelist(name)
&& !accessControlExposeHeaderSet.contains(name)) { |
1143 logConsoleError(executionContext(), "Refused to get unsafe header \"" +
name + "\""); | 1142 logConsoleError(executionContext(), "Refused to get unsafe header \"" +
name + "\""); |
1144 return String(); | 1143 return nullAtom; |
1145 } | 1144 } |
1146 return m_response.httpHeaderField(name); | 1145 return m_response.httpHeaderField(name); |
1147 } | 1146 } |
1148 | 1147 |
1149 String XMLHttpRequest::responseMIMEType() const | 1148 AtomicString XMLHttpRequest::responseMIMEType() const |
1150 { | 1149 { |
1151 String mimeType = extractMIMETypeFromMediaType(m_mimeTypeOverride); | 1150 AtomicString mimeType = extractMIMETypeFromMediaType(m_mimeTypeOverride); |
1152 if (mimeType.isEmpty()) { | 1151 if (mimeType.isEmpty()) { |
1153 if (m_response.isHTTP()) | 1152 if (m_response.isHTTP()) |
1154 mimeType = extractMIMETypeFromMediaType(m_response.httpHeaderField("
Content-Type")); | 1153 mimeType = extractMIMETypeFromMediaType(m_response.httpHeaderField("
Content-Type")); |
1155 else | 1154 else |
1156 mimeType = m_response.mimeType(); | 1155 mimeType = m_response.mimeType(); |
1157 } | 1156 } |
1158 if (mimeType.isEmpty()) | 1157 if (mimeType.isEmpty()) |
1159 mimeType = "text/xml"; | 1158 mimeType = AtomicString("text/xml", AtomicString::ConstructFromLiteral); |
1160 | 1159 |
1161 return mimeType; | 1160 return mimeType; |
1162 } | 1161 } |
1163 | 1162 |
1164 bool XMLHttpRequest::responseIsXML() const | 1163 bool XMLHttpRequest::responseIsXML() const |
1165 { | 1164 { |
1166 // FIXME: Remove the lower() call when DOMImplementation.isXMLMIMEType() is
modified | 1165 // FIXME: Remove the lower() call when DOMImplementation.isXMLMIMEType() is
modified |
1167 // to do case insensitive MIME type matching. | 1166 // to do case insensitive MIME type matching. |
1168 return DOMImplementation::isXMLMIMEType(responseMIMEType().lower()); | 1167 return DOMImplementation::isXMLMIMEType(responseMIMEType().lower()); |
1169 } | 1168 } |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1394 { | 1393 { |
1395 return EventTargetNames::XMLHttpRequest; | 1394 return EventTargetNames::XMLHttpRequest; |
1396 } | 1395 } |
1397 | 1396 |
1398 ExecutionContext* XMLHttpRequest::executionContext() const | 1397 ExecutionContext* XMLHttpRequest::executionContext() const |
1399 { | 1398 { |
1400 return ActiveDOMObject::executionContext(); | 1399 return ActiveDOMObject::executionContext(); |
1401 } | 1400 } |
1402 | 1401 |
1403 } // namespace WebCore | 1402 } // namespace WebCore |
OLD | NEW |