| 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 13 matching lines...) Expand all Loading... |
| 24 #include "core/xml/XMLHttpRequest.h" | 24 #include "core/xml/XMLHttpRequest.h" |
| 25 | 25 |
| 26 #include "bindings/core/v8/ExceptionState.h" | 26 #include "bindings/core/v8/ExceptionState.h" |
| 27 #include "core/FetchInitiatorTypeNames.h" | 27 #include "core/FetchInitiatorTypeNames.h" |
| 28 #include "core/dom/ContextFeatures.h" | 28 #include "core/dom/ContextFeatures.h" |
| 29 #include "core/dom/DOMImplementation.h" | 29 #include "core/dom/DOMImplementation.h" |
| 30 #include "core/dom/ExceptionCode.h" | 30 #include "core/dom/ExceptionCode.h" |
| 31 #include "core/dom/XMLDocument.h" | 31 #include "core/dom/XMLDocument.h" |
| 32 #include "core/editing/markup.h" | 32 #include "core/editing/markup.h" |
| 33 #include "core/events/Event.h" | 33 #include "core/events/Event.h" |
| 34 #include "core/fetch/CrossOriginAccessControl.h" | 34 #include "core/fetch/FetchUtils.h" |
| 35 #include "core/fileapi/Blob.h" | 35 #include "core/fileapi/Blob.h" |
| 36 #include "core/fileapi/File.h" | 36 #include "core/fileapi/File.h" |
| 37 #include "core/frame/Settings.h" | 37 #include "core/frame/Settings.h" |
| 38 #include "core/frame/UseCounter.h" | 38 #include "core/frame/UseCounter.h" |
| 39 #include "core/frame/csp/ContentSecurityPolicy.h" | 39 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 40 #include "core/html/DOMFormData.h" | 40 #include "core/html/DOMFormData.h" |
| 41 #include "core/html/HTMLDocument.h" | 41 #include "core/html/HTMLDocument.h" |
| 42 #include "core/html/parser/TextResourceDecoder.h" | 42 #include "core/html/parser/TextResourceDecoder.h" |
| 43 #include "core/inspector/InspectorInstrumentation.h" | 43 #include "core/inspector/InspectorInstrumentation.h" |
| 44 #include "core/inspector/InspectorTraceEvents.h" | 44 #include "core/inspector/InspectorTraceEvents.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 70 // As dispatching readystatechange when readystatechange is NOT changed is not | 70 // As dispatching readystatechange when readystatechange is NOT changed is not |
| 71 // specified, 50ms is not specified, too. | 71 // specified, 50ms is not specified, too. |
| 72 // We choose this value because progress event is dispatched every 50ms, but | 72 // We choose this value because progress event is dispatched every 50ms, but |
| 73 // actually this value doesn't have to equal to the interval. | 73 // actually this value doesn't have to equal to the interval. |
| 74 // Note: When readystate is actually changed readystatechange event must be | 74 // Note: When readystate is actually changed readystatechange event must be |
| 75 // dispatched no matter how recently dispatched the event was. | 75 // dispatched no matter how recently dispatched the event was. |
| 76 const double readyStateChangeFireInterval = 0.05; | 76 const double readyStateChangeFireInterval = 0.05; |
| 77 | 77 |
| 78 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, xmlHttpRequestCounter, ("XM
LHttpRequest")); | 78 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, xmlHttpRequestCounter, ("XM
LHttpRequest")); |
| 79 | 79 |
| 80 struct XMLHttpRequestStaticData { | |
| 81 WTF_MAKE_NONCOPYABLE(XMLHttpRequestStaticData); WTF_MAKE_FAST_ALLOCATED; | |
| 82 public: | |
| 83 XMLHttpRequestStaticData(); | |
| 84 String m_proxyHeaderPrefix; | |
| 85 String m_secHeaderPrefix; | |
| 86 HashSet<String, CaseFoldingHash> m_forbiddenRequestHeaders; | |
| 87 }; | |
| 88 | |
| 89 XMLHttpRequestStaticData::XMLHttpRequestStaticData() | |
| 90 : m_proxyHeaderPrefix("proxy-") | |
| 91 , m_secHeaderPrefix("sec-") | |
| 92 { | |
| 93 m_forbiddenRequestHeaders.add("accept-charset"); | |
| 94 m_forbiddenRequestHeaders.add("accept-encoding"); | |
| 95 m_forbiddenRequestHeaders.add("access-control-request-headers"); | |
| 96 m_forbiddenRequestHeaders.add("access-control-request-method"); | |
| 97 m_forbiddenRequestHeaders.add("connection"); | |
| 98 m_forbiddenRequestHeaders.add("content-length"); | |
| 99 m_forbiddenRequestHeaders.add("cookie"); | |
| 100 m_forbiddenRequestHeaders.add("cookie2"); | |
| 101 m_forbiddenRequestHeaders.add("date"); | |
| 102 m_forbiddenRequestHeaders.add("dnt"); | |
| 103 m_forbiddenRequestHeaders.add("expect"); | |
| 104 m_forbiddenRequestHeaders.add("host"); | |
| 105 m_forbiddenRequestHeaders.add("keep-alive"); | |
| 106 m_forbiddenRequestHeaders.add("origin"); | |
| 107 m_forbiddenRequestHeaders.add("referer"); | |
| 108 m_forbiddenRequestHeaders.add("te"); | |
| 109 m_forbiddenRequestHeaders.add("trailer"); | |
| 110 m_forbiddenRequestHeaders.add("transfer-encoding"); | |
| 111 m_forbiddenRequestHeaders.add("upgrade"); | |
| 112 m_forbiddenRequestHeaders.add("user-agent"); | |
| 113 m_forbiddenRequestHeaders.add("via"); | |
| 114 } | |
| 115 | |
| 116 static bool isSetCookieHeader(const AtomicString& name) | 80 static bool isSetCookieHeader(const AtomicString& name) |
| 117 { | 81 { |
| 118 return equalIgnoringCase(name, "set-cookie") || equalIgnoringCase(name, "set
-cookie2"); | 82 return equalIgnoringCase(name, "set-cookie") || equalIgnoringCase(name, "set
-cookie2"); |
| 119 } | 83 } |
| 120 | 84 |
| 121 static void replaceCharsetInMediaType(String& mediaType, const String& charsetVa
lue) | 85 static void replaceCharsetInMediaType(String& mediaType, const String& charsetVa
lue) |
| 122 { | 86 { |
| 123 unsigned pos = 0, len = 0; | 87 unsigned pos = 0, len = 0; |
| 124 | 88 |
| 125 findCharsetInMediaType(mediaType, pos, len); | 89 findCharsetInMediaType(mediaType, pos, len); |
| 126 | 90 |
| 127 if (!len) { | 91 if (!len) { |
| 128 // When no charset found, do nothing. | 92 // When no charset found, do nothing. |
| 129 return; | 93 return; |
| 130 } | 94 } |
| 131 | 95 |
| 132 // Found at least one existing charset, replace all occurrences with new cha
rset. | 96 // Found at least one existing charset, replace all occurrences with new cha
rset. |
| 133 while (len) { | 97 while (len) { |
| 134 mediaType.replace(pos, len, charsetValue); | 98 mediaType.replace(pos, len, charsetValue); |
| 135 unsigned start = pos + charsetValue.length(); | 99 unsigned start = pos + charsetValue.length(); |
| 136 findCharsetInMediaType(mediaType, pos, len, start); | 100 findCharsetInMediaType(mediaType, pos, len, start); |
| 137 } | 101 } |
| 138 } | 102 } |
| 139 | 103 |
| 140 static const XMLHttpRequestStaticData* staticData = 0; | |
| 141 | |
| 142 static const XMLHttpRequestStaticData* createXMLHttpRequestStaticData() | |
| 143 { | |
| 144 staticData = new XMLHttpRequestStaticData; | |
| 145 return staticData; | |
| 146 } | |
| 147 | |
| 148 static const XMLHttpRequestStaticData* initializeXMLHttpRequestStaticData() | |
| 149 { | |
| 150 // Uses dummy to avoid warnings about an unused variable. | |
| 151 AtomicallyInitializedStatic(const XMLHttpRequestStaticData*, dummy = createX
MLHttpRequestStaticData()); | |
| 152 return dummy; | |
| 153 } | |
| 154 | |
| 155 static void logConsoleError(ExecutionContext* context, const String& message) | 104 static void logConsoleError(ExecutionContext* context, const String& message) |
| 156 { | 105 { |
| 157 if (!context) | 106 if (!context) |
| 158 return; | 107 return; |
| 159 // FIXME: It's not good to report the bad usage without indicating what sour
ce line it came from. | 108 // FIXME: It's not good to report the bad usage without indicating what sour
ce line it came from. |
| 160 // We should pass additional parameters so we can tell the console where the
mistake occurred. | 109 // We should pass additional parameters so we can tell the console where the
mistake occurred. |
| 161 context->addConsoleMessage(JSMessageSource, ErrorMessageLevel, message); | 110 context->addConsoleMessage(JSMessageSource, ErrorMessageLevel, message); |
| 162 } | 111 } |
| 163 | 112 |
| 164 PassRefPtrWillBeRawPtr<XMLHttpRequest> XMLHttpRequest::create(ExecutionContext*
context, PassRefPtr<SecurityOrigin> securityOrigin) | 113 PassRefPtrWillBeRawPtr<XMLHttpRequest> XMLHttpRequest::create(ExecutionContext*
context, PassRefPtr<SecurityOrigin> securityOrigin) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 182 , m_securityOrigin(securityOrigin) | 131 , m_securityOrigin(securityOrigin) |
| 183 , m_previousReadyStateChangeFireTime(0) | 132 , m_previousReadyStateChangeFireTime(0) |
| 184 , m_async(true) | 133 , m_async(true) |
| 185 , m_includeCredentials(false) | 134 , m_includeCredentials(false) |
| 186 , m_createdDocument(false) | 135 , m_createdDocument(false) |
| 187 , m_error(false) | 136 , m_error(false) |
| 188 , m_uploadEventsAllowed(true) | 137 , m_uploadEventsAllowed(true) |
| 189 , m_uploadComplete(false) | 138 , m_uploadComplete(false) |
| 190 , m_sameOriginRequest(true) | 139 , m_sameOriginRequest(true) |
| 191 { | 140 { |
| 192 initializeXMLHttpRequestStaticData(); | |
| 193 #ifndef NDEBUG | 141 #ifndef NDEBUG |
| 194 xmlHttpRequestCounter.increment(); | 142 xmlHttpRequestCounter.increment(); |
| 195 #endif | 143 #endif |
| 196 ScriptWrappable::init(this); | 144 ScriptWrappable::init(this); |
| 197 } | 145 } |
| 198 | 146 |
| 199 XMLHttpRequest::~XMLHttpRequest() | 147 XMLHttpRequest::~XMLHttpRequest() |
| 200 { | 148 { |
| 201 #ifndef NDEBUG | 149 #ifndef NDEBUG |
| 202 xmlHttpRequestCounter.decrement(); | 150 xmlHttpRequestCounter.decrement(); |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 } | 443 } |
| 496 | 444 |
| 497 // FIXME: According to XMLHttpRequest Level 2 we should throw InvalidAccessE
rror exception here. | 445 // FIXME: According to XMLHttpRequest Level 2 we should throw InvalidAccessE
rror exception here. |
| 498 // However for time being only print warning message to warn web developers. | 446 // However for time being only print warning message to warn web developers. |
| 499 if (!m_async) | 447 if (!m_async) |
| 500 UseCounter::countDeprecation(executionContext(), UseCounter::SyncXHRWith
Credentials); | 448 UseCounter::countDeprecation(executionContext(), UseCounter::SyncXHRWith
Credentials); |
| 501 | 449 |
| 502 m_includeCredentials = value; | 450 m_includeCredentials = value; |
| 503 } | 451 } |
| 504 | 452 |
| 505 bool XMLHttpRequest::isAllowedHTTPMethod(const String& method) | |
| 506 { | |
| 507 return !equalIgnoringCase(method, "TRACE") | |
| 508 && !equalIgnoringCase(method, "TRACK") | |
| 509 && !equalIgnoringCase(method, "CONNECT"); | |
| 510 } | |
| 511 | |
| 512 AtomicString XMLHttpRequest::uppercaseKnownHTTPMethod(const AtomicString& method
) | 453 AtomicString XMLHttpRequest::uppercaseKnownHTTPMethod(const AtomicString& method
) |
| 513 { | 454 { |
| 514 // Valid methods per step-5 of http://xhr.spec.whatwg.org/#the-open()-method
. | 455 // Valid methods per step-5 of http://xhr.spec.whatwg.org/#the-open()-method
. |
| 515 const char* const methods[] = { | 456 const char* const methods[] = { |
| 516 "DELETE", | 457 "DELETE", |
| 517 "GET", | 458 "GET", |
| 518 "HEAD", | 459 "HEAD", |
| 519 "OPTIONS", | 460 "OPTIONS", |
| 520 "POST", | 461 "POST", |
| 521 "PUT" }; | 462 "PUT" }; |
| 522 | 463 |
| 523 for (unsigned i = 0; i < WTF_ARRAY_LENGTH(methods); ++i) { | 464 for (unsigned i = 0; i < WTF_ARRAY_LENGTH(methods); ++i) { |
| 524 if (equalIgnoringCase(method, methods[i])) { | 465 if (equalIgnoringCase(method, methods[i])) { |
| 525 // Don't bother allocating a new string if it's already all uppercas
e. | 466 // Don't bother allocating a new string if it's already all uppercas
e. |
| 526 if (method == methods[i]) | 467 if (method == methods[i]) |
| 527 return method; | 468 return method; |
| 528 return methods[i]; | 469 return methods[i]; |
| 529 } | 470 } |
| 530 } | 471 } |
| 531 return method; | 472 return method; |
| 532 } | 473 } |
| 533 | 474 |
| 534 bool XMLHttpRequest::isAllowedHTTPHeader(const String& name) | |
| 535 { | |
| 536 initializeXMLHttpRequestStaticData(); | |
| 537 return !staticData->m_forbiddenRequestHeaders.contains(name) && !name.starts
With(staticData->m_proxyHeaderPrefix, false) | |
| 538 && !name.startsWith(staticData->m_secHeaderPrefix, false); | |
| 539 } | |
| 540 | |
| 541 void XMLHttpRequest::open(const AtomicString& method, const KURL& url, Exception
State& exceptionState) | 475 void XMLHttpRequest::open(const AtomicString& method, const KURL& url, Exception
State& exceptionState) |
| 542 { | 476 { |
| 543 open(method, url, true, exceptionState); | 477 open(method, url, true, exceptionState); |
| 544 } | 478 } |
| 545 | 479 |
| 546 void XMLHttpRequest::open(const AtomicString& method, const KURL& url, bool asyn
c, ExceptionState& exceptionState) | 480 void XMLHttpRequest::open(const AtomicString& method, const KURL& url, bool asyn
c, ExceptionState& exceptionState) |
| 547 { | 481 { |
| 548 WTF_LOG(Network, "XMLHttpRequest %p open('%s', '%s', %d)", this, method.utf8
().data(), url.elidedString().utf8().data(), async); | 482 WTF_LOG(Network, "XMLHttpRequest %p open('%s', '%s', %d)", this, method.utf8
().data(), url.elidedString().utf8().data(), async); |
| 549 | 483 |
| 550 if (!internalAbort()) | 484 if (!internalAbort()) |
| 551 return; | 485 return; |
| 552 | 486 |
| 553 State previousState = m_state; | 487 State previousState = m_state; |
| 554 m_state = UNSENT; | 488 m_state = UNSENT; |
| 555 m_error = false; | 489 m_error = false; |
| 556 m_uploadComplete = false; | 490 m_uploadComplete = false; |
| 557 | 491 |
| 558 // clear stuff from possible previous load | 492 // clear stuff from possible previous load |
| 559 clearResponse(); | 493 clearResponse(); |
| 560 clearRequest(); | 494 clearRequest(); |
| 561 | 495 |
| 562 ASSERT(m_state == UNSENT); | 496 ASSERT(m_state == UNSENT); |
| 563 | 497 |
| 564 if (!isValidHTTPToken(method)) { | 498 if (!isValidHTTPToken(method)) { |
| 565 exceptionState.throwDOMException(SyntaxError, "'" + method + "' is not a
valid HTTP method."); | 499 exceptionState.throwDOMException(SyntaxError, "'" + method + "' is not a
valid HTTP method."); |
| 566 return; | 500 return; |
| 567 } | 501 } |
| 568 | 502 |
| 569 if (!isAllowedHTTPMethod(method)) { | 503 if (FetchUtils::isForbiddenMethod(method)) { |
| 570 exceptionState.throwSecurityError("'" + method + "' HTTP method is unsup
ported."); | 504 exceptionState.throwSecurityError("'" + method + "' HTTP method is unsup
ported."); |
| 571 return; | 505 return; |
| 572 } | 506 } |
| 573 | 507 |
| 574 if (!ContentSecurityPolicy::shouldBypassMainWorld(executionContext()) && !ex
ecutionContext()->contentSecurityPolicy()->allowConnectToSource(url)) { | 508 if (!ContentSecurityPolicy::shouldBypassMainWorld(executionContext()) && !ex
ecutionContext()->contentSecurityPolicy()->allowConnectToSource(url)) { |
| 575 // We can safely expose the URL to JavaScript, as these checks happen sy
nchronously before redirection. JavaScript receives no new information. | 509 // We can safely expose the URL to JavaScript, as these checks happen sy
nchronously before redirection. JavaScript receives no new information. |
| 576 exceptionState.throwSecurityError("Refused to connect to '" + url.elided
String() + "' because it violates the document's Content Security Policy."); | 510 exceptionState.throwSecurityError("Refused to connect to '" + url.elided
String() + "' because it violates the document's Content Security Policy."); |
| 577 return; | 511 return; |
| 578 } | 512 } |
| 579 | 513 |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 823 if (httpBody && m_upload) { | 757 if (httpBody && m_upload) { |
| 824 uploadEvents = m_upload->hasEventListeners(); | 758 uploadEvents = m_upload->hasEventListeners(); |
| 825 m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(EventTyp
eNames::loadstart)); | 759 m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(EventTyp
eNames::loadstart)); |
| 826 } | 760 } |
| 827 } | 761 } |
| 828 | 762 |
| 829 m_sameOriginRequest = securityOrigin()->canRequest(m_url); | 763 m_sameOriginRequest = securityOrigin()->canRequest(m_url); |
| 830 | 764 |
| 831 // We also remember whether upload events should be allowed for this request
in case the upload listeners are | 765 // We also remember whether upload events should be allowed for this request
in case the upload listeners are |
| 832 // added after the request is started. | 766 // added after the request is started. |
| 833 m_uploadEventsAllowed = m_sameOriginRequest || uploadEvents || !isSimpleCros
sOriginAccessRequest(m_method, m_requestHeaders); | 767 m_uploadEventsAllowed = m_sameOriginRequest || uploadEvents || !FetchUtils::
isSimpleRequest(m_method, m_requestHeaders); |
| 834 | 768 |
| 835 ASSERT(executionContext()); | 769 ASSERT(executionContext()); |
| 836 ExecutionContext& executionContext = *this->executionContext(); | 770 ExecutionContext& executionContext = *this->executionContext(); |
| 837 | 771 |
| 838 ResourceRequest request(m_url); | 772 ResourceRequest request(m_url); |
| 839 request.setHTTPMethod(m_method); | 773 request.setHTTPMethod(m_method); |
| 840 request.setRequestContext(blink::WebURLRequest::RequestContextXMLHttpRequest
); | 774 request.setRequestContext(blink::WebURLRequest::RequestContextXMLHttpRequest
); |
| 841 | 775 |
| 842 InspectorInstrumentation::willLoadXHR(&executionContext, this, this, m_metho
d, m_url, m_async, httpBody ? httpBody->deepCopy() : nullptr, m_requestHeaders,
m_includeCredentials); | 776 InspectorInstrumentation::willLoadXHR(&executionContext, this, this, m_metho
d, m_url, m_async, httpBody ? httpBody->deepCopy() : nullptr, m_requestHeaders,
m_includeCredentials); |
| 843 | 777 |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1089 exceptionState.throwDOMException(SyntaxError, "'" + name + "' is not a v
alid HTTP header field name."); | 1023 exceptionState.throwDOMException(SyntaxError, "'" + name + "' is not a v
alid HTTP header field name."); |
| 1090 return; | 1024 return; |
| 1091 } | 1025 } |
| 1092 | 1026 |
| 1093 if (!isValidHTTPHeaderValue(value)) { | 1027 if (!isValidHTTPHeaderValue(value)) { |
| 1094 exceptionState.throwDOMException(SyntaxError, "'" + value + "' is not a
valid HTTP header field value."); | 1028 exceptionState.throwDOMException(SyntaxError, "'" + value + "' is not a
valid HTTP header field value."); |
| 1095 return; | 1029 return; |
| 1096 } | 1030 } |
| 1097 | 1031 |
| 1098 // No script (privileged or not) can set unsafe headers. | 1032 // No script (privileged or not) can set unsafe headers. |
| 1099 if (!isAllowedHTTPHeader(name)) { | 1033 if (FetchUtils::isForbiddenHeaderName(name)) { |
| 1100 logConsoleError(executionContext(), "Refused to set unsafe header \"" +
name + "\""); | 1034 logConsoleError(executionContext(), "Refused to set unsafe header \"" +
name + "\""); |
| 1101 return; | 1035 return; |
| 1102 } | 1036 } |
| 1103 | 1037 |
| 1104 setRequestHeaderInternal(name, value); | 1038 setRequestHeaderInternal(name, value); |
| 1105 } | 1039 } |
| 1106 | 1040 |
| 1107 void XMLHttpRequest::setRequestHeaderInternal(const AtomicString& name, const At
omicString& value) | 1041 void XMLHttpRequest::setRequestHeaderInternal(const AtomicString& name, const At
omicString& value) |
| 1108 { | 1042 { |
| 1109 HTTPHeaderMap::AddResult result = m_requestHeaders.add(name, value); | 1043 HTTPHeaderMap::AddResult result = m_requestHeaders.add(name, value); |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1439 { | 1373 { |
| 1440 visitor->trace(m_responseBlob); | 1374 visitor->trace(m_responseBlob); |
| 1441 visitor->trace(m_responseStream); | 1375 visitor->trace(m_responseStream); |
| 1442 visitor->trace(m_responseDocument); | 1376 visitor->trace(m_responseDocument); |
| 1443 visitor->trace(m_progressEventThrottle); | 1377 visitor->trace(m_progressEventThrottle); |
| 1444 visitor->trace(m_upload); | 1378 visitor->trace(m_upload); |
| 1445 XMLHttpRequestEventTarget::trace(visitor); | 1379 XMLHttpRequestEventTarget::trace(visitor); |
| 1446 } | 1380 } |
| 1447 | 1381 |
| 1448 } // namespace blink | 1382 } // namespace blink |
| OLD | NEW |