Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / xmlhttprequest / XMLHttpRequest.cpp
1 /*
2  *  Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved.
3  *  Copyright (C) 2005-2007 Alexey Proskuryakov <ap@webkit.org>
4  *  Copyright (C) 2007, 2008 Julien Chaffraix <jchaffraix@webkit.org>
5  *  Copyright (C) 2008, 2011 Google Inc. All rights reserved.
6  *  Copyright (C) 2012 Intel Corporation
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Lesser General Public
10  *  License as published by the Free Software Foundation; either
11  *  version 2 of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Lesser General Public License for more details.
17  *
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
20  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22
23 #include "config.h"
24 #include "core/xmlhttprequest/XMLHttpRequest.h"
25
26 #include "bindings/core/v8/ExceptionState.h"
27 #include "core/FetchInitiatorTypeNames.h"
28 #include "core/dom/ContextFeatures.h"
29 #include "core/dom/DOMArrayBuffer.h"
30 #include "core/dom/DOMException.h"
31 #include "core/dom/DOMImplementation.h"
32 #include "core/dom/DocumentParser.h"
33 #include "core/dom/ExceptionCode.h"
34 #include "core/dom/XMLDocument.h"
35 #include "core/editing/markup.h"
36 #include "core/events/Event.h"
37 #include "core/fetch/FetchUtils.h"
38 #include "core/fileapi/Blob.h"
39 #include "core/fileapi/File.h"
40 #include "core/fileapi/FileReaderLoader.h"
41 #include "core/fileapi/FileReaderLoaderClient.h"
42 #include "core/frame/Settings.h"
43 #include "core/frame/UseCounter.h"
44 #include "core/frame/csp/ContentSecurityPolicy.h"
45 #include "core/html/DOMFormData.h"
46 #include "core/html/HTMLDocument.h"
47 #include "core/html/parser/TextResourceDecoder.h"
48 #include "core/inspector/ConsoleMessage.h"
49 #include "core/inspector/InspectorInstrumentation.h"
50 #include "core/inspector/InspectorTraceEvents.h"
51 #include "core/loader/ThreadableLoader.h"
52 #include "core/streams/ReadableStream.h"
53 #include "core/streams/ReadableStreamImpl.h"
54 #include "core/streams/Stream.h"
55 #include "core/streams/UnderlyingSource.h"
56 #include "core/xmlhttprequest/XMLHttpRequestProgressEvent.h"
57 #include "core/xmlhttprequest/XMLHttpRequestUpload.h"
58 #include "platform/Logging.h"
59 #include "platform/RuntimeEnabledFeatures.h"
60 #include "platform/SharedBuffer.h"
61 #include "platform/blob/BlobData.h"
62 #include "platform/network/HTTPParsers.h"
63 #include "platform/network/ParsedContentType.h"
64 #include "platform/network/ResourceError.h"
65 #include "platform/network/ResourceRequest.h"
66 #include "public/platform/WebURLRequest.h"
67 #include "wtf/ArrayBuffer.h"
68 #include "wtf/ArrayBufferView.h"
69 #include "wtf/Assertions.h"
70 #include "wtf/RefCountedLeakCounter.h"
71 #include "wtf/StdLibExtras.h"
72 #include "wtf/text/CString.h"
73
74 namespace blink {
75
76 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, xmlHttpRequestCounter, ("XMLHttpRequest"));
77
78 static bool isSetCookieHeader(const AtomicString& name)
79 {
80     return equalIgnoringCase(name, "set-cookie") || equalIgnoringCase(name, "set-cookie2");
81 }
82
83 static void replaceCharsetInMediaType(String& mediaType, const String& charsetValue)
84 {
85     unsigned pos = 0, len = 0;
86
87     findCharsetInMediaType(mediaType, pos, len);
88
89     if (!len) {
90         // When no charset found, do nothing.
91         return;
92     }
93
94     // Found at least one existing charset, replace all occurrences with new charset.
95     while (len) {
96         mediaType.replace(pos, len, charsetValue);
97         unsigned start = pos + charsetValue.length();
98         findCharsetInMediaType(mediaType, pos, len, start);
99     }
100 }
101
102 static void logConsoleError(ExecutionContext* context, const String& message)
103 {
104     if (!context)
105         return;
106     // FIXME: It's not good to report the bad usage without indicating what source line it came from.
107     // We should pass additional parameters so we can tell the console where the mistake occurred.
108     context->addConsoleMessage(ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, message));
109 }
110
111 namespace {
112
113 class ReadableStreamSource : public GarbageCollectedFinalized<ReadableStreamSource>, public UnderlyingSource {
114     USING_GARBAGE_COLLECTED_MIXIN(ReadableStreamSource);
115 public:
116     ReadableStreamSource(XMLHttpRequest* owner) : m_owner(owner) { }
117     virtual ~ReadableStreamSource() { }
118     virtual void pullSource() override { }
119     virtual ScriptPromise cancelSource(ScriptState* scriptState, ScriptValue reason) override
120     {
121         m_owner->abort();
122         return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isolate()));
123     }
124     virtual void trace(Visitor* visitor) override
125     {
126         visitor->trace(m_owner);
127         UnderlyingSource::trace(visitor);
128     }
129
130 private:
131     // This is RawPtr in non-oilpan build to avoid the reference cycle. To
132     // avoid use-after free, the associated ReadableStream must be closed
133     // or errored when m_owner is gone.
134     RawPtrWillBeMember<XMLHttpRequest> m_owner;
135 };
136
137 } // namespace
138
139 class XMLHttpRequest::BlobLoader final : public NoBaseWillBeGarbageCollectedFinalized<XMLHttpRequest::BlobLoader>, public FileReaderLoaderClient {
140 public:
141     static PassOwnPtrWillBeRawPtr<BlobLoader> create(XMLHttpRequest* xhr, PassRefPtr<BlobDataHandle> handle)
142     {
143         return adoptPtrWillBeNoop(new BlobLoader(xhr, handle));
144     }
145
146     // FileReaderLoaderClient functions.
147     virtual void didStartLoading() override { }
148     virtual void didReceiveDataForClient(const char* data, unsigned length) override
149     {
150         ASSERT(length <= INT_MAX);
151         m_xhr->didReceiveData(data, length);
152     }
153     virtual void didFinishLoading() override
154     {
155         m_xhr->didFinishLoadingFromBlob();
156     }
157     virtual void didFail(FileError::ErrorCode error) override
158     {
159         m_xhr->didFailLoadingFromBlob();
160     }
161
162     void cancel()
163     {
164         m_loader.cancel();
165     }
166
167     void trace(Visitor* visitor)
168     {
169         visitor->trace(m_xhr);
170     }
171
172 private:
173     BlobLoader(XMLHttpRequest* xhr, PassRefPtr<BlobDataHandle> handle)
174         : m_xhr(xhr)
175         , m_loader(FileReaderLoader::ReadByClient, this)
176     {
177         m_loader.start(m_xhr->executionContext(), handle);
178     }
179
180     RawPtrWillBeMember<XMLHttpRequest> m_xhr;
181     FileReaderLoader m_loader;
182 };
183
184 PassRefPtrWillBeRawPtr<XMLHttpRequest> XMLHttpRequest::create(ExecutionContext* context, PassRefPtr<SecurityOrigin> securityOrigin)
185 {
186     RefPtrWillBeRawPtr<XMLHttpRequest> xmlHttpRequest = adoptRefWillBeNoop(new XMLHttpRequest(context, securityOrigin));
187     xmlHttpRequest->suspendIfNeeded();
188
189     return xmlHttpRequest.release();
190 }
191
192 XMLHttpRequest::XMLHttpRequest(ExecutionContext* context, PassRefPtr<SecurityOrigin> securityOrigin)
193     : ActiveDOMObject(context)
194     , m_timeoutMilliseconds(0)
195     , m_loaderIdentifier(0)
196     , m_state(UNSENT)
197     , m_lengthDownloadedToFile(0)
198     , m_receivedLength(0)
199     , m_exceptionCode(0)
200     , m_progressEventThrottle(this)
201     , m_responseTypeCode(ResponseTypeDefault)
202     , m_securityOrigin(securityOrigin)
203     , m_async(true)
204     , m_includeCredentials(false)
205     , m_parsedResponse(false)
206     , m_error(false)
207     , m_uploadEventsAllowed(true)
208     , m_uploadComplete(false)
209     , m_sameOriginRequest(true)
210     , m_downloadingToFile(false)
211 {
212 #ifndef NDEBUG
213     xmlHttpRequestCounter.increment();
214 #endif
215 }
216
217 XMLHttpRequest::~XMLHttpRequest()
218 {
219 #ifndef NDEBUG
220     xmlHttpRequestCounter.decrement();
221 #endif
222 }
223
224 Document* XMLHttpRequest::document() const
225 {
226     ASSERT(executionContext()->isDocument());
227     return toDocument(executionContext());
228 }
229
230 SecurityOrigin* XMLHttpRequest::securityOrigin() const
231 {
232     return m_securityOrigin ? m_securityOrigin.get() : executionContext()->securityOrigin();
233 }
234
235 XMLHttpRequest::State XMLHttpRequest::readyState() const
236 {
237     return m_state;
238 }
239
240 ScriptString XMLHttpRequest::responseText(ExceptionState& exceptionState)
241 {
242     if (m_responseTypeCode != ResponseTypeDefault && m_responseTypeCode != ResponseTypeText) {
243         exceptionState.throwDOMException(InvalidStateError, "The value is only accessible if the object's 'responseType' is '' or 'text' (was '" + responseType() + "').");
244         return ScriptString();
245     }
246     if (m_error || (m_state != LOADING && m_state != DONE))
247         return ScriptString();
248     return m_responseText;
249 }
250
251 ScriptString XMLHttpRequest::responseJSONSource()
252 {
253     ASSERT(m_responseTypeCode == ResponseTypeJSON);
254
255     if (m_error || m_state != DONE)
256         return ScriptString();
257     return m_responseText;
258 }
259
260 void XMLHttpRequest::initResponseDocument()
261 {
262     // The W3C spec requires the final MIME type to be some valid XML type, or text/html.
263     // If it is text/html, then the responseType of "document" must have been supplied explicitly.
264     bool isHTML = responseIsHTML();
265     if ((m_response.isHTTP() && !responseIsXML() && !isHTML)
266         || (isHTML && m_responseTypeCode == ResponseTypeDefault)
267         || executionContext()->isWorkerGlobalScope()) {
268         m_responseDocument = nullptr;
269         return;
270     }
271
272     DocumentInit init = DocumentInit::fromContext(document()->contextDocument(), m_url);
273     if (isHTML)
274         m_responseDocument = HTMLDocument::create(init);
275     else
276         m_responseDocument = XMLDocument::create(init);
277
278     // FIXME: Set Last-Modified.
279     m_responseDocument->setSecurityOrigin(securityOrigin());
280     m_responseDocument->setContextFeatures(document()->contextFeatures());
281     m_responseDocument->setMimeType(finalResponseMIMETypeWithFallback());
282 }
283
284 Document* XMLHttpRequest::responseXML(ExceptionState& exceptionState)
285 {
286     if (m_responseTypeCode != ResponseTypeDefault && m_responseTypeCode != ResponseTypeDocument) {
287         exceptionState.throwDOMException(InvalidStateError, "The value is only accessible if the object's 'responseType' is '' or 'document' (was '" + responseType() + "').");
288         return 0;
289     }
290
291     if (m_error || m_state != DONE)
292         return 0;
293
294     if (!m_parsedResponse) {
295         initResponseDocument();
296         if (!m_responseDocument)
297             return nullptr;
298
299         m_responseDocument->setContent(m_responseText.flattenToString());
300         if (!m_responseDocument->wellFormed())
301             m_responseDocument = nullptr;
302
303         m_parsedResponse = true;
304     }
305
306     return m_responseDocument.get();
307 }
308
309 Blob* XMLHttpRequest::responseBlob()
310 {
311     ASSERT(m_responseTypeCode == ResponseTypeBlob);
312
313     // We always return null before DONE.
314     if (m_error || m_state != DONE)
315         return 0;
316
317     if (!m_responseBlob) {
318         if (m_downloadingToFile) {
319             ASSERT(!m_binaryResponseBuilder);
320
321             // When responseType is set to "blob", we redirect the downloaded
322             // data to a file-handle directly in the browser process. We get
323             // the file-path from the ResourceResponse directly instead of
324             // copying the bytes between the browser and the renderer.
325             m_responseBlob = Blob::create(createBlobDataHandleFromResponse());
326         } else {
327             OwnPtr<BlobData> blobData = BlobData::create();
328             size_t size = 0;
329             if (m_binaryResponseBuilder && m_binaryResponseBuilder->size()) {
330                 size = m_binaryResponseBuilder->size();
331                 blobData->appendBytes(m_binaryResponseBuilder->data(), size);
332                 blobData->setContentType(finalResponseMIMETypeWithFallback());
333                 m_binaryResponseBuilder.clear();
334             }
335             m_responseBlob = Blob::create(BlobDataHandle::create(blobData.release(), size));
336         }
337     }
338
339     return m_responseBlob.get();
340 }
341
342 DOMArrayBuffer* XMLHttpRequest::responseArrayBuffer()
343 {
344     ASSERT(m_responseTypeCode == ResponseTypeArrayBuffer);
345
346     if (m_error || m_state != DONE)
347         return 0;
348
349     if (!m_responseArrayBuffer) {
350         if (m_binaryResponseBuilder && m_binaryResponseBuilder->size()) {
351             m_responseArrayBuffer = DOMArrayBuffer::create(m_binaryResponseBuilder->getAsArrayBuffer());
352             if (!m_responseArrayBuffer) {
353                 // m_binaryResponseBuilder failed to allocate an ArrayBuffer.
354                 // We need to crash the renderer since there's no way defined in
355                 // the spec to tell this to the user.
356                 CRASH();
357             }
358             m_binaryResponseBuilder.clear();
359         } else {
360             m_responseArrayBuffer = DOMArrayBuffer::create(static_cast<void*>(0), 0);
361         }
362     }
363
364     return m_responseArrayBuffer.get();
365 }
366
367 Stream* XMLHttpRequest::responseLegacyStream()
368 {
369     ASSERT(m_responseTypeCode == ResponseTypeLegacyStream);
370
371     if (m_error || (m_state != LOADING && m_state != DONE))
372         return 0;
373
374     return m_responseLegacyStream.get();
375 }
376
377 ReadableStream* XMLHttpRequest::responseStream()
378 {
379     ASSERT(m_responseTypeCode == ResponseTypeStream);
380     if (m_error || (m_state != LOADING && m_state != DONE))
381         return 0;
382
383     return m_responseStream;
384 }
385
386 void XMLHttpRequest::setTimeout(unsigned long timeout, ExceptionState& exceptionState)
387 {
388     // FIXME: Need to trigger or update the timeout Timer here, if needed. http://webkit.org/b/98156
389     // XHR2 spec, 4.7.3. "This implies that the timeout attribute can be set while fetching is in progress. If that occurs it will still be measured relative to the start of fetching."
390     if (executionContext()->isDocument() && !m_async) {
391         exceptionState.throwDOMException(InvalidAccessError, "Timeouts cannot be set for synchronous requests made from a document.");
392         return;
393     }
394
395     m_timeoutMilliseconds = timeout;
396
397     // From http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute:
398     // Note: This implies that the timeout attribute can be set while fetching is in progress. If
399     // that occurs it will still be measured relative to the start of fetching.
400     //
401     // The timeout may be overridden after send.
402     if (m_loader)
403         m_loader->overrideTimeout(timeout);
404 }
405
406 void XMLHttpRequest::setResponseType(const String& responseType, ExceptionState& exceptionState)
407 {
408     if (m_state >= LOADING) {
409         exceptionState.throwDOMException(InvalidStateError, "The response type cannot be set if the object's state is LOADING or DONE.");
410         return;
411     }
412
413     // Newer functionality is not available to synchronous requests in window contexts, as a spec-mandated
414     // attempt to discourage synchronous XHR use. responseType is one such piece of functionality.
415     if (!m_async && executionContext()->isDocument()) {
416         exceptionState.throwDOMException(InvalidAccessError, "The response type cannot be changed for synchronous requests made from a document.");
417         return;
418     }
419
420     if (responseType == "") {
421         m_responseTypeCode = ResponseTypeDefault;
422     } else if (responseType == "text") {
423         m_responseTypeCode = ResponseTypeText;
424     } else if (responseType == "json") {
425         m_responseTypeCode = ResponseTypeJSON;
426     } else if (responseType == "document") {
427         m_responseTypeCode = ResponseTypeDocument;
428     } else if (responseType == "blob") {
429         m_responseTypeCode = ResponseTypeBlob;
430     } else if (responseType == "arraybuffer") {
431         m_responseTypeCode = ResponseTypeArrayBuffer;
432     } else if (responseType == "legacystream") {
433         if (RuntimeEnabledFeatures::streamEnabled())
434             m_responseTypeCode = ResponseTypeLegacyStream;
435         else
436             return;
437     } else if (responseType == "stream") {
438         if (RuntimeEnabledFeatures::streamEnabled())
439             m_responseTypeCode = ResponseTypeStream;
440         else
441             return;
442     } else {
443         ASSERT_NOT_REACHED();
444     }
445 }
446
447 String XMLHttpRequest::responseType()
448 {
449     switch (m_responseTypeCode) {
450     case ResponseTypeDefault:
451         return "";
452     case ResponseTypeText:
453         return "text";
454     case ResponseTypeJSON:
455         return "json";
456     case ResponseTypeDocument:
457         return "document";
458     case ResponseTypeBlob:
459         return "blob";
460     case ResponseTypeArrayBuffer:
461         return "arraybuffer";
462     case ResponseTypeLegacyStream:
463         return "legacystream";
464     case ResponseTypeStream:
465         return "stream";
466     }
467     return "";
468 }
469
470 String XMLHttpRequest::responseURL()
471 {
472     KURL responseURL(m_response.url());
473     if (!responseURL.isNull())
474         responseURL.removeFragmentIdentifier();
475     return responseURL.string();
476 }
477
478 XMLHttpRequestUpload* XMLHttpRequest::upload()
479 {
480     if (!m_upload)
481         m_upload = XMLHttpRequestUpload::create(this);
482     return m_upload.get();
483 }
484
485 void XMLHttpRequest::trackProgress(long long length)
486 {
487     m_receivedLength += length;
488
489     if (m_state != LOADING) {
490         changeState(LOADING);
491     } else {
492         // Dispatch a readystatechange event because many applications use
493         // it to track progress although this is not specified.
494         //
495         // FIXME: Stop dispatching this event for progress tracking.
496         dispatchReadyStateChangeEvent();
497     }
498     if (m_async)
499         dispatchProgressEventFromSnapshot(EventTypeNames::progress);
500 }
501
502 void XMLHttpRequest::changeState(State newState)
503 {
504     if (m_state != newState) {
505         m_state = newState;
506         dispatchReadyStateChangeEvent();
507     }
508 }
509
510 void XMLHttpRequest::dispatchReadyStateChangeEvent()
511 {
512     if (!executionContext())
513         return;
514
515     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchXHRReadyStateChangeEvent(executionContext(), this);
516
517     if (m_async || (m_state <= OPENED || m_state == DONE)) {
518         TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "XHRReadyStateChange", "data", InspectorXhrReadyStateChangeEvent::data(executionContext(), this));
519         TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
520         XMLHttpRequestProgressEventThrottle::DeferredEventAction action = XMLHttpRequestProgressEventThrottle::Ignore;
521         if (m_state == DONE) {
522             if (m_error)
523                 action = XMLHttpRequestProgressEventThrottle::Clear;
524             else
525                 action = XMLHttpRequestProgressEventThrottle::Flush;
526         }
527         m_progressEventThrottle.dispatchReadyStateChangeEvent(Event::create(EventTypeNames::readystatechange), action);
528         TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data());
529     }
530
531     InspectorInstrumentation::didDispatchXHRReadyStateChangeEvent(cookie);
532     if (m_state == DONE && !m_error) {
533         TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "XHRLoad", "data", InspectorXhrLoadEvent::data(executionContext(), this));
534         TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
535         InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchXHRLoadEvent(executionContext(), this);
536         dispatchProgressEventFromSnapshot(EventTypeNames::load);
537         InspectorInstrumentation::didDispatchXHRLoadEvent(cookie);
538
539         dispatchProgressEventFromSnapshot(EventTypeNames::loadend);
540         TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data());
541     }
542 }
543
544 void XMLHttpRequest::setWithCredentials(bool value, ExceptionState& exceptionState)
545 {
546     if (m_state > OPENED || m_loader) {
547         exceptionState.throwDOMException(InvalidStateError,  "The value may only be set if the object's state is UNSENT or OPENED.");
548         return;
549     }
550
551     // FIXME: According to XMLHttpRequest Level 2 we should throw InvalidAccessError exception here.
552     // However for time being only print warning message to warn web developers.
553     if (!m_async)
554         UseCounter::countDeprecation(executionContext(), UseCounter::SyncXHRWithCredentials);
555
556     m_includeCredentials = value;
557 }
558
559 void XMLHttpRequest::open(const AtomicString& method, const KURL& url, ExceptionState& exceptionState)
560 {
561     open(method, url, true, exceptionState);
562 }
563
564 void XMLHttpRequest::open(const AtomicString& method, const KURL& url, bool async, ExceptionState& exceptionState)
565 {
566     WTF_LOG(Network, "XMLHttpRequest %p open('%s', '%s', %d)", this, method.utf8().data(), url.elidedString().utf8().data(), async);
567
568     if (!internalAbort())
569         return;
570
571     State previousState = m_state;
572     m_state = UNSENT;
573     m_error = false;
574     m_uploadComplete = false;
575
576     if (!isValidHTTPToken(method)) {
577         exceptionState.throwDOMException(SyntaxError, "'" + method + "' is not a valid HTTP method.");
578         return;
579     }
580
581     if (FetchUtils::isForbiddenMethod(method)) {
582         exceptionState.throwSecurityError("'" + method + "' HTTP method is unsupported.");
583         return;
584     }
585
586     if (!ContentSecurityPolicy::shouldBypassMainWorld(executionContext()) && !executionContext()->contentSecurityPolicy()->allowConnectToSource(url)) {
587         // We can safely expose the URL to JavaScript, as these checks happen synchronously before redirection. JavaScript receives no new information.
588         exceptionState.throwSecurityError("Refused to connect to '" + url.elidedString() + "' because it violates the document's Content Security Policy.");
589         return;
590     }
591
592     if (!async && executionContext()->isDocument()) {
593         if (document()->settings() && !document()->settings()->syncXHRInDocumentsEnabled()) {
594             exceptionState.throwDOMException(InvalidAccessError, "Synchronous requests are disabled for this page.");
595             return;
596         }
597
598         // Newer functionality is not available to synchronous requests in window contexts, as a spec-mandated
599         // attempt to discourage synchronous XHR use. responseType is one such piece of functionality.
600         if (m_responseTypeCode != ResponseTypeDefault) {
601             exceptionState.throwDOMException(InvalidAccessError, "Synchronous requests from a document must not set a response type.");
602             return;
603         }
604
605         // Similarly, timeouts are disabled for synchronous requests as well.
606         if (m_timeoutMilliseconds > 0) {
607             exceptionState.throwDOMException(InvalidAccessError, "Synchronous requests must not set a timeout.");
608             return;
609         }
610
611         // Here we just warn that firing sync XHR's may affect responsiveness.
612         // Eventually sync xhr will be deprecated and an "InvalidAccessError" exception thrown.
613         // Refer : https://xhr.spec.whatwg.org/#sync-warning
614         // Use count for XHR synchronous requests on main thread only.
615         if (!document()->processingBeforeUnload())
616             UseCounter::countDeprecation(executionContext(), UseCounter::XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload);
617     }
618
619     m_method = FetchUtils::normalizeMethod(method);
620
621     m_url = url;
622
623     m_async = async;
624
625     ASSERT(!m_loader);
626
627     // Check previous state to avoid dispatching readyState event
628     // when calling open several times in a row.
629     if (previousState != OPENED)
630         changeState(OPENED);
631     else
632         m_state = OPENED;
633 }
634
635 void XMLHttpRequest::open(const AtomicString& method, const KURL& url, bool async, const String& user, ExceptionState& exceptionState)
636 {
637     KURL urlWithCredentials(url);
638     urlWithCredentials.setUser(user);
639
640     open(method, urlWithCredentials, async, exceptionState);
641 }
642
643 void XMLHttpRequest::open(const AtomicString& method, const KURL& url, bool async, const String& user, const String& password, ExceptionState& exceptionState)
644 {
645     KURL urlWithCredentials(url);
646     urlWithCredentials.setUser(user);
647     urlWithCredentials.setPass(password);
648
649     open(method, urlWithCredentials, async, exceptionState);
650 }
651
652 bool XMLHttpRequest::initSend(ExceptionState& exceptionState)
653 {
654     if (!executionContext())
655         return false;
656
657     if (m_state != OPENED || m_loader) {
658         exceptionState.throwDOMException(InvalidStateError, "The object's state must be OPENED.");
659         return false;
660     }
661
662     m_error = false;
663     return true;
664 }
665
666 void XMLHttpRequest::send(ExceptionState& exceptionState)
667 {
668     send(String(), exceptionState);
669 }
670
671 bool XMLHttpRequest::areMethodAndURLValidForSend()
672 {
673     return m_method != "GET" && m_method != "HEAD" && m_url.protocolIsInHTTPFamily();
674 }
675
676 void XMLHttpRequest::send(Document* document, ExceptionState& exceptionState)
677 {
678     WTF_LOG(Network, "XMLHttpRequest %p send() Document %p", this, document);
679
680     ASSERT(document);
681
682     if (!initSend(exceptionState))
683         return;
684
685     RefPtr<FormData> httpBody;
686
687     if (areMethodAndURLValidForSend()) {
688         if (getRequestHeader("Content-Type").isEmpty()) {
689             // FIXME: this should include the charset used for encoding.
690             setRequestHeaderInternal("Content-Type", "application/xml");
691         }
692
693         // FIXME: According to XMLHttpRequest Level 2, this should use the Document.innerHTML algorithm
694         // from the HTML5 specification to serialize the document.
695         String body = createMarkup(document);
696
697         // FIXME: This should use value of document.inputEncoding to determine the encoding to use.
698         httpBody = FormData::create(UTF8Encoding().encode(body, WTF::EntitiesForUnencodables));
699     }
700
701     createRequest(httpBody.release(), exceptionState);
702 }
703
704 void XMLHttpRequest::send(const String& body, ExceptionState& exceptionState)
705 {
706     WTF_LOG(Network, "XMLHttpRequest %p send() String '%s'", this, body.utf8().data());
707
708     if (!initSend(exceptionState))
709         return;
710
711     RefPtr<FormData> httpBody;
712
713     if (!body.isNull() && areMethodAndURLValidForSend()) {
714         String contentType = getRequestHeader("Content-Type");
715         if (contentType.isEmpty()) {
716             setRequestHeaderInternal("Content-Type", "text/plain;charset=UTF-8");
717         } else {
718             replaceCharsetInMediaType(contentType, "UTF-8");
719             m_requestHeaders.set("Content-Type", AtomicString(contentType));
720         }
721
722         httpBody = FormData::create(UTF8Encoding().encode(body, WTF::EntitiesForUnencodables));
723     }
724
725     createRequest(httpBody.release(), exceptionState);
726 }
727
728 void XMLHttpRequest::send(Blob* body, ExceptionState& exceptionState)
729 {
730     WTF_LOG(Network, "XMLHttpRequest %p send() Blob '%s'", this, body->uuid().utf8().data());
731
732     if (!initSend(exceptionState))
733         return;
734
735     RefPtr<FormData> httpBody;
736
737     if (areMethodAndURLValidForSend()) {
738         if (getRequestHeader("Content-Type").isEmpty()) {
739             const String& blobType = body->type();
740             if (!blobType.isEmpty() && isValidContentType(blobType)) {
741                 setRequestHeaderInternal("Content-Type", AtomicString(blobType));
742             } else {
743                 // From FileAPI spec, whenever media type cannot be determined,
744                 // empty string must be returned.
745                 setRequestHeaderInternal("Content-Type", "");
746             }
747         }
748
749         // FIXME: add support for uploading bundles.
750         httpBody = FormData::create();
751         if (body->hasBackingFile()) {
752             File* file = toFile(body);
753             if (!file->path().isEmpty())
754                 httpBody->appendFile(file->path());
755             else if (!file->fileSystemURL().isEmpty())
756                 httpBody->appendFileSystemURL(file->fileSystemURL());
757             else
758                 ASSERT_NOT_REACHED();
759         } else {
760             httpBody->appendBlob(body->uuid(), body->blobDataHandle());
761         }
762     }
763
764     createRequest(httpBody.release(), exceptionState);
765 }
766
767 void XMLHttpRequest::send(DOMFormData* body, ExceptionState& exceptionState)
768 {
769     WTF_LOG(Network, "XMLHttpRequest %p send() DOMFormData %p", this, body);
770
771     if (!initSend(exceptionState))
772         return;
773
774     RefPtr<FormData> httpBody;
775
776     if (areMethodAndURLValidForSend()) {
777         httpBody = body->createMultiPartFormData();
778
779         if (getRequestHeader("Content-Type").isEmpty()) {
780             AtomicString contentType = AtomicString("multipart/form-data; boundary=", AtomicString::ConstructFromLiteral) + httpBody->boundary().data();
781             setRequestHeaderInternal("Content-Type", contentType);
782         }
783     }
784
785     createRequest(httpBody.release(), exceptionState);
786 }
787
788 void XMLHttpRequest::send(ArrayBuffer* body, ExceptionState& exceptionState)
789 {
790     WTF_LOG(Network, "XMLHttpRequest %p send() ArrayBuffer %p", this, body);
791
792     sendBytesData(body->data(), body->byteLength(), exceptionState);
793 }
794
795 void XMLHttpRequest::send(ArrayBufferView* body, ExceptionState& exceptionState)
796 {
797     WTF_LOG(Network, "XMLHttpRequest %p send() ArrayBufferView %p", this, body);
798
799     sendBytesData(body->baseAddress(), body->byteLength(), exceptionState);
800 }
801
802 void XMLHttpRequest::sendBytesData(const void* data, size_t length, ExceptionState& exceptionState)
803 {
804     if (!initSend(exceptionState))
805         return;
806
807     RefPtr<FormData> httpBody;
808
809     if (areMethodAndURLValidForSend()) {
810         httpBody = FormData::create(data, length);
811     }
812
813     createRequest(httpBody.release(), exceptionState);
814 }
815
816 void XMLHttpRequest::sendForInspectorXHRReplay(PassRefPtr<FormData> formData, ExceptionState& exceptionState)
817 {
818     createRequest(formData ? formData->deepCopy() : nullptr, exceptionState);
819     m_exceptionCode = exceptionState.code();
820 }
821
822 void XMLHttpRequest::createRequest(PassRefPtr<FormData> httpBody, ExceptionState& exceptionState)
823 {
824     // Only GET request is supported for blob URL.
825     if (m_url.protocolIs("blob") && m_method != "GET") {
826         exceptionState.throwDOMException(NetworkError, "'GET' is the only method allowed for 'blob:' URLs.");
827         return;
828     }
829
830     // The presence of upload event listeners forces us to use preflighting because POSTing to an URL that does not
831     // permit cross origin requests should look exactly like POSTing to an URL that does not respond at all.
832     // Also, only async requests support upload progress events.
833     bool uploadEvents = false;
834     if (m_async) {
835         dispatchProgressEvent(EventTypeNames::loadstart, 0, 0);
836         if (httpBody && m_upload) {
837             uploadEvents = m_upload->hasEventListeners();
838             m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(EventTypeNames::loadstart));
839         }
840     }
841
842     m_sameOriginRequest = securityOrigin()->canRequest(m_url);
843
844     // We also remember whether upload events should be allowed for this request in case the upload listeners are
845     // added after the request is started.
846     m_uploadEventsAllowed = m_sameOriginRequest || uploadEvents || !FetchUtils::isSimpleRequest(m_method, m_requestHeaders);
847
848     ASSERT(executionContext());
849     ExecutionContext& executionContext = *this->executionContext();
850
851     ResourceRequest request(m_url);
852     request.setHTTPMethod(m_method);
853     request.setRequestContext(blink::WebURLRequest::RequestContextXMLHttpRequest);
854     request.setFetchCredentialsMode(m_includeCredentials ? WebURLRequest::FetchCredentialsModeInclude : WebURLRequest::FetchCredentialsModeSameOrigin);
855
856     InspectorInstrumentation::willLoadXHR(&executionContext, this, this, m_method, m_url, m_async, httpBody ? httpBody->deepCopy() : nullptr, m_requestHeaders, m_includeCredentials);
857
858     if (httpBody) {
859         ASSERT(m_method != "GET");
860         ASSERT(m_method != "HEAD");
861         request.setHTTPBody(httpBody);
862     }
863
864     if (m_requestHeaders.size() > 0)
865         request.addHTTPHeaderFields(m_requestHeaders);
866
867     ThreadableLoaderOptions options;
868     options.preflightPolicy = uploadEvents ? ForcePreflight : ConsiderPreflight;
869     options.crossOriginRequestPolicy = UseAccessControl;
870     options.initiator = FetchInitiatorTypeNames::xmlhttprequest;
871     options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypassMainWorld(&executionContext) ? DoNotEnforceContentSecurityPolicy : EnforceConnectSrcDirective;
872     options.timeoutMilliseconds = m_timeoutMilliseconds;
873
874     ResourceLoaderOptions resourceLoaderOptions;
875     resourceLoaderOptions.allowCredentials = (m_sameOriginRequest || m_includeCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials;
876     resourceLoaderOptions.credentialsRequested = m_includeCredentials ? ClientRequestedCredentials : ClientDidNotRequestCredentials;
877     resourceLoaderOptions.securityOrigin = securityOrigin();
878     resourceLoaderOptions.mixedContentBlockingTreatment = RuntimeEnabledFeatures::laxMixedContentCheckingEnabled() ? TreatAsPassiveContent : TreatAsActiveContent;
879
880     // When responseType is set to "blob", we redirect the downloaded data to a
881     // file-handle directly.
882     m_downloadingToFile = responseTypeCode() == ResponseTypeBlob;
883     if (m_downloadingToFile) {
884         request.setDownloadToFile(true);
885         resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData;
886     }
887
888     m_exceptionCode = 0;
889     m_error = false;
890
891     if (m_async) {
892         if (m_upload)
893             request.setReportUploadProgress(true);
894
895         // ThreadableLoader::create can return null here, for example if we're no longer attached to a page.
896         // This is true while running onunload handlers.
897         // FIXME: Maybe we need to be able to send XMLHttpRequests from onunload, <http://bugs.webkit.org/show_bug.cgi?id=10904>.
898         // FIXME: Maybe create() can return null for other reasons too?
899         ASSERT(!m_loader);
900         m_loader = ThreadableLoader::create(executionContext, this, request, options, resourceLoaderOptions);
901     } else {
902         // Use count for XHR synchronous requests.
903         UseCounter::count(&executionContext, UseCounter::XMLHttpRequestSynchronous);
904         ThreadableLoader::loadResourceSynchronously(executionContext, request, *this, options, resourceLoaderOptions);
905     }
906
907     if (!m_exceptionCode && m_error)
908         m_exceptionCode = NetworkError;
909     if (m_exceptionCode)
910         exceptionState.throwDOMException(m_exceptionCode, "Failed to load '" + m_url.elidedString() + "'.");
911 }
912
913 void XMLHttpRequest::abort()
914 {
915     WTF_LOG(Network, "XMLHttpRequest %p abort()", this);
916
917     // internalAbort() clears |m_loader|. Compute |sendFlag| now.
918     //
919     // |sendFlag| corresponds to "the send() flag" defined in the XHR spec.
920     //
921     // |sendFlag| is only set when we have an active, asynchronous loader.
922     // Don't use it as "the send() flag" when the XHR is in sync mode.
923     bool sendFlag = m_loader;
924
925     // internalAbort() clears the response. Save the data needed for
926     // dispatching ProgressEvents.
927     long long expectedLength = m_response.expectedContentLength();
928     long long receivedLength = m_receivedLength;
929
930     if (!internalAbort())
931         return;
932
933     // The script never gets any chance to call abort() on a sync XHR between
934     // send() call and transition to the DONE state. It's because a sync XHR
935     // doesn't dispatch any event between them. So, if |m_async| is false, we
936     // can skip the "request error steps" (defined in the XHR spec) without any
937     // state check.
938     //
939     // FIXME: It's possible open() is invoked in internalAbort() and |m_async|
940     // becomes true by that. We should implement more reliable treatment for
941     // nested method invocations at some point.
942     if (m_async) {
943         if ((m_state == OPENED && sendFlag) || m_state == HEADERS_RECEIVED || m_state == LOADING) {
944             ASSERT(!m_loader);
945             handleRequestError(0, EventTypeNames::abort, receivedLength, expectedLength);
946         }
947     }
948     m_state = UNSENT;
949 }
950
951 void XMLHttpRequest::clearVariablesForLoading()
952 {
953     if (m_blobLoader) {
954         m_blobLoader->cancel();
955         m_blobLoader = nullptr;
956     }
957
958     m_decoder.clear();
959
960     if (m_responseDocumentParser) {
961         m_responseDocumentParser->removeClient(this);
962 #if !ENABLE(OILPAN)
963         m_responseDocumentParser->detach();
964 #endif
965         m_responseDocumentParser = nullptr;
966     }
967
968     m_finalResponseCharset = String();
969 }
970
971 bool XMLHttpRequest::internalAbort()
972 {
973     m_error = true;
974
975     if (m_responseDocumentParser && !m_responseDocumentParser->isStopped())
976         m_responseDocumentParser->stopParsing();
977
978     clearVariablesForLoading();
979
980     InspectorInstrumentation::didFailXHRLoading(executionContext(), this, this);
981
982     if (m_responseLegacyStream && m_state != DONE)
983         m_responseLegacyStream->abort();
984
985     if (m_responseStream) {
986         // When the stream is already closed (including canceled from the
987         // user), |error| does nothing.
988         // FIXME: Create a more specific error.
989         m_responseStream->error(DOMException::create(!m_async && m_exceptionCode ? m_exceptionCode : AbortError, "XMLHttpRequest::abort"));
990     }
991
992     clearResponse();
993     clearRequest();
994
995     if (!m_loader)
996         return true;
997
998     // Cancelling the ThreadableLoader m_loader may result in calling
999     // window.onload synchronously. If such an onload handler contains open()
1000     // call on the same XMLHttpRequest object, reentry happens.
1001     //
1002     // If, window.onload contains open() and send(), m_loader will be set to
1003     // non 0 value. So, we cannot continue the outer open(). In such case,
1004     // just abort the outer open() by returning false.
1005     RefPtr<ThreadableLoader> loader = m_loader.release();
1006     loader->cancel();
1007
1008     // If abort() called internalAbort() and a nested open() ended up
1009     // clearing the error flag, but didn't send(), make sure the error
1010     // flag is still set.
1011     bool newLoadStarted = hasPendingActivity();
1012     if (!newLoadStarted)
1013         m_error = true;
1014
1015     return !newLoadStarted;
1016 }
1017
1018 void XMLHttpRequest::clearResponse()
1019 {
1020     // FIXME: when we add the support for multi-part XHR, we will have to
1021     // be careful with this initialization.
1022     m_receivedLength = 0;
1023
1024     m_response = ResourceResponse();
1025
1026     m_responseText.clear();
1027
1028     m_parsedResponse = false;
1029     m_responseDocument = nullptr;
1030
1031     m_responseBlob = nullptr;
1032
1033     m_downloadingToFile = false;
1034     m_lengthDownloadedToFile = 0;
1035
1036     m_responseLegacyStream = nullptr;
1037     m_responseStream = nullptr;
1038
1039     // These variables may referred by the response accessors. So, we can clear
1040     // this only when we clear the response holder variables above.
1041     m_binaryResponseBuilder.clear();
1042     m_responseArrayBuffer.clear();
1043 }
1044
1045 void XMLHttpRequest::clearRequest()
1046 {
1047     m_requestHeaders.clear();
1048 }
1049
1050 void XMLHttpRequest::dispatchProgressEvent(const AtomicString& type, long long receivedLength, long long expectedLength)
1051 {
1052     bool lengthComputable = expectedLength > 0 && receivedLength <= expectedLength;
1053     unsigned long long loaded = receivedLength >= 0 ? static_cast<unsigned long long>(receivedLength) : 0;
1054     unsigned long long total = lengthComputable ? static_cast<unsigned long long>(expectedLength) : 0;
1055
1056     m_progressEventThrottle.dispatchProgressEvent(type, lengthComputable, loaded, total);
1057
1058     if (type == EventTypeNames::loadend)
1059         InspectorInstrumentation::didDispatchXHRLoadendEvent(executionContext(), this);
1060 }
1061
1062 void XMLHttpRequest::dispatchProgressEventFromSnapshot(const AtomicString& type)
1063 {
1064     dispatchProgressEvent(type, m_receivedLength, m_response.expectedContentLength());
1065 }
1066
1067 void XMLHttpRequest::handleNetworkError()
1068 {
1069     WTF_LOG(Network, "XMLHttpRequest %p handleNetworkError()", this);
1070
1071     // Response is cleared next, save needed progress event data.
1072     long long expectedLength = m_response.expectedContentLength();
1073     long long receivedLength = m_receivedLength;
1074
1075     // Prevent the XMLHttpRequest instance from being destoryed during
1076     // |internalAbort()|.
1077     RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
1078
1079     if (!internalAbort())
1080         return;
1081
1082     handleRequestError(NetworkError, EventTypeNames::error, receivedLength, expectedLength);
1083 }
1084
1085 void XMLHttpRequest::handleDidCancel()
1086 {
1087     WTF_LOG(Network, "XMLHttpRequest %p handleDidCancel()", this);
1088
1089     // Response is cleared next, save needed progress event data.
1090     long long expectedLength = m_response.expectedContentLength();
1091     long long receivedLength = m_receivedLength;
1092
1093     // Prevent the XMLHttpRequest instance from being destoryed during
1094     // |internalAbort()|.
1095     RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
1096
1097     if (!internalAbort())
1098         return;
1099
1100     handleRequestError(AbortError, EventTypeNames::abort, receivedLength, expectedLength);
1101 }
1102
1103 void XMLHttpRequest::handleRequestError(ExceptionCode exceptionCode, const AtomicString& type, long long receivedLength, long long expectedLength)
1104 {
1105     WTF_LOG(Network, "XMLHttpRequest %p handleRequestError()", this);
1106
1107     // The request error steps for event 'type' and exception 'exceptionCode'.
1108
1109     if (!m_async && exceptionCode) {
1110         m_state = DONE;
1111         m_exceptionCode = exceptionCode;
1112         return;
1113     }
1114     // With m_error set, the state change steps are minimal: any pending
1115     // progress event is flushed + a readystatechange is dispatched.
1116     // No new progress events dispatched; as required, that happens at
1117     // the end here.
1118     ASSERT(m_error);
1119     changeState(DONE);
1120
1121     if (!m_uploadComplete) {
1122         m_uploadComplete = true;
1123         if (m_upload && m_uploadEventsAllowed)
1124             m_upload->handleRequestError(type);
1125     }
1126
1127     // Note: The below event dispatch may be called while |hasPendingActivity() == false|,
1128     // when |handleRequestError| is called after |internalAbort()|.
1129     // This is safe, however, as |this| will be kept alive from a strong ref |Event::m_target|.
1130     dispatchProgressEvent(EventTypeNames::progress, receivedLength, expectedLength);
1131     dispatchProgressEvent(type, receivedLength, expectedLength);
1132     dispatchProgressEvent(EventTypeNames::loadend, receivedLength, expectedLength);
1133 }
1134
1135 void XMLHttpRequest::overrideMimeType(const AtomicString& mimeType, ExceptionState& exceptionState)
1136 {
1137     if (m_state == LOADING || m_state == DONE) {
1138         exceptionState.throwDOMException(InvalidStateError, "MimeType cannot be overridden when the state is LOADING or DONE.");
1139         return;
1140     }
1141
1142     m_mimeTypeOverride = mimeType;
1143 }
1144
1145 void XMLHttpRequest::setRequestHeader(const AtomicString& name, const AtomicString& value, ExceptionState& exceptionState)
1146 {
1147     if (m_state != OPENED || m_loader) {
1148         exceptionState.throwDOMException(InvalidStateError, "The object's state must be OPENED.");
1149         return;
1150     }
1151
1152     if (!isValidHTTPToken(name)) {
1153         exceptionState.throwDOMException(SyntaxError, "'" + name + "' is not a valid HTTP header field name.");
1154         return;
1155     }
1156
1157     if (!isValidHTTPHeaderValue(value)) {
1158         exceptionState.throwDOMException(SyntaxError, "'" + value + "' is not a valid HTTP header field value.");
1159         return;
1160     }
1161
1162     // No script (privileged or not) can set unsafe headers.
1163     if (FetchUtils::isForbiddenHeaderName(name)) {
1164         logConsoleError(executionContext(), "Refused to set unsafe header \"" + name + "\"");
1165         return;
1166     }
1167
1168     setRequestHeaderInternal(name, value);
1169 }
1170
1171 void XMLHttpRequest::setRequestHeaderInternal(const AtomicString& name, const AtomicString& value)
1172 {
1173     HTTPHeaderMap::AddResult result = m_requestHeaders.add(name, value);
1174     if (!result.isNewEntry)
1175         result.storedValue->value = result.storedValue->value + ", " + value;
1176 }
1177
1178 const AtomicString& XMLHttpRequest::getRequestHeader(const AtomicString& name) const
1179 {
1180     return m_requestHeaders.get(name);
1181 }
1182
1183 String XMLHttpRequest::getAllResponseHeaders() const
1184 {
1185     if (m_state < HEADERS_RECEIVED || m_error)
1186         return "";
1187
1188     StringBuilder stringBuilder;
1189
1190     HTTPHeaderSet accessControlExposeHeaderSet;
1191     parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField("Access-Control-Expose-Headers"), accessControlExposeHeaderSet);
1192     HTTPHeaderMap::const_iterator end = m_response.httpHeaderFields().end();
1193     for (HTTPHeaderMap::const_iterator it = m_response.httpHeaderFields().begin(); it!= end; ++it) {
1194         // Hide Set-Cookie header fields from the XMLHttpRequest client for these reasons:
1195         //     1) If the client did have access to the fields, then it could read HTTP-only
1196         //        cookies; those cookies are supposed to be hidden from scripts.
1197         //     2) There's no known harm in hiding Set-Cookie header fields entirely; we don't
1198         //        know any widely used technique that requires access to them.
1199         //     3) Firefox has implemented this policy.
1200         if (isSetCookieHeader(it->key) && !securityOrigin()->canLoadLocalResources())
1201             continue;
1202
1203         if (!m_sameOriginRequest && !isOnAccessControlResponseHeaderWhitelist(it->key) && !accessControlExposeHeaderSet.contains(it->key))
1204             continue;
1205
1206         stringBuilder.append(it->key);
1207         stringBuilder.append(':');
1208         stringBuilder.append(' ');
1209         stringBuilder.append(it->value);
1210         stringBuilder.append('\r');
1211         stringBuilder.append('\n');
1212     }
1213
1214     return stringBuilder.toString();
1215 }
1216
1217 const AtomicString& XMLHttpRequest::getResponseHeader(const AtomicString& name) const
1218 {
1219     if (m_state < HEADERS_RECEIVED || m_error)
1220         return nullAtom;
1221
1222     // See comment in getAllResponseHeaders above.
1223     if (isSetCookieHeader(name) && !securityOrigin()->canLoadLocalResources()) {
1224         logConsoleError(executionContext(), "Refused to get unsafe header \"" + name + "\"");
1225         return nullAtom;
1226     }
1227
1228     HTTPHeaderSet accessControlExposeHeaderSet;
1229     parseAccessControlExposeHeadersAllowList(m_response.httpHeaderField("Access-Control-Expose-Headers"), accessControlExposeHeaderSet);
1230
1231     if (!m_sameOriginRequest && !isOnAccessControlResponseHeaderWhitelist(name) && !accessControlExposeHeaderSet.contains(name)) {
1232         logConsoleError(executionContext(), "Refused to get unsafe header \"" + name + "\"");
1233         return nullAtom;
1234     }
1235     return m_response.httpHeaderField(name);
1236 }
1237
1238 AtomicString XMLHttpRequest::finalResponseMIMEType() const
1239 {
1240     AtomicString overriddenType = extractMIMETypeFromMediaType(m_mimeTypeOverride);
1241     if (!overriddenType.isEmpty())
1242         return overriddenType;
1243
1244     if (m_response.isHTTP())
1245         return extractMIMETypeFromMediaType(m_response.httpHeaderField("Content-Type"));
1246
1247     return m_response.mimeType();
1248 }
1249
1250 AtomicString XMLHttpRequest::finalResponseMIMETypeWithFallback() const
1251 {
1252     AtomicString finalType = finalResponseMIMEType();
1253     if (!finalType.isEmpty())
1254         return finalType;
1255
1256     // FIXME: This fallback is not specified in the final MIME type algorithm
1257     // of the XHR spec. Move this to more appropriate place.
1258     return AtomicString("text/xml", AtomicString::ConstructFromLiteral);
1259 }
1260
1261 bool XMLHttpRequest::responseIsXML() const
1262 {
1263     return DOMImplementation::isXMLMIMEType(finalResponseMIMETypeWithFallback());
1264 }
1265
1266 bool XMLHttpRequest::responseIsHTML() const
1267 {
1268     return equalIgnoringCase(finalResponseMIMEType(), "text/html");
1269 }
1270
1271 int XMLHttpRequest::status() const
1272 {
1273     if (m_state == UNSENT || m_state == OPENED || m_error)
1274         return 0;
1275
1276     if (m_response.httpStatusCode())
1277         return m_response.httpStatusCode();
1278
1279     return 0;
1280 }
1281
1282 String XMLHttpRequest::statusText() const
1283 {
1284     if (m_state == UNSENT || m_state == OPENED || m_error)
1285         return String();
1286
1287     if (!m_response.httpStatusText().isNull())
1288         return m_response.httpStatusText();
1289
1290     return String();
1291 }
1292
1293 void XMLHttpRequest::didFail(const ResourceError& error)
1294 {
1295     WTF_LOG(Network, "XMLHttpRequest %p didFail()", this);
1296
1297     // If we are already in an error state, for instance we called abort(), bail out early.
1298     if (m_error)
1299         return;
1300
1301     if (error.isCancellation()) {
1302         handleDidCancel();
1303         // Now the XMLHttpRequest instance may be dead.
1304         return;
1305     }
1306
1307     if (error.isTimeout()) {
1308         handleDidTimeout();
1309         // Now the XMLHttpRequest instance may be dead.
1310         return;
1311     }
1312
1313     // Network failures are already reported to Web Inspector by ResourceLoader.
1314     if (error.domain() == errorDomainBlinkInternal)
1315         logConsoleError(executionContext(), "XMLHttpRequest cannot load " + error.failingURL() + ". " + error.localizedDescription());
1316
1317     handleNetworkError();
1318     // Now the XMLHttpRequest instance may be dead.
1319 }
1320
1321 void XMLHttpRequest::didFailRedirectCheck()
1322 {
1323     WTF_LOG(Network, "XMLHttpRequest %p didFailRedirectCheck()", this);
1324
1325     handleNetworkError();
1326     // Now the XMLHttpRequest instance may be dead.
1327 }
1328
1329 void XMLHttpRequest::didFinishLoading(unsigned long identifier, double)
1330 {
1331     WTF_LOG(Network, "XMLHttpRequest %p didFinishLoading(%lu)", this, identifier);
1332
1333     if (m_error)
1334         return;
1335
1336     if (m_state < HEADERS_RECEIVED)
1337         changeState(HEADERS_RECEIVED);
1338
1339     m_loaderIdentifier = identifier;
1340
1341     if (m_downloadingToFile && m_responseTypeCode != ResponseTypeBlob && m_lengthDownloadedToFile) {
1342         ASSERT(m_state == LOADING);
1343         // In this case, we have sent the request with DownloadToFile true,
1344         // but the user changed the response type after that. Hence we need to
1345         // read the response data and provide it to this object.
1346         m_blobLoader = BlobLoader::create(this, createBlobDataHandleFromResponse());
1347     } else {
1348         didFinishLoadingInternal();
1349     }
1350 }
1351
1352 void XMLHttpRequest::didFinishLoadingInternal()
1353 {
1354     if (m_responseDocumentParser) {
1355         // |DocumentParser::finish()| tells the parser that we have reached end of the data.
1356         // When using |HTMLDocumentParser|, which works asynchronously, we do not have the
1357         // complete document just after the |DocumentParser::finish()| call.
1358         // Wait for the parser to call us back in |notifyParserStopped| to progress state.
1359         m_responseDocumentParser->finish();
1360         ASSERT(m_responseDocument);
1361         return;
1362     }
1363
1364     if (m_decoder)
1365         m_responseText = m_responseText.concatenateWith(m_decoder->flush());
1366
1367     if (m_responseLegacyStream)
1368         m_responseLegacyStream->finalize();
1369
1370     if (m_responseStream)
1371         m_responseStream->close();
1372
1373     clearVariablesForLoading();
1374     endLoading();
1375 }
1376
1377 void XMLHttpRequest::didFinishLoadingFromBlob()
1378 {
1379     WTF_LOG(Network, "XMLHttpRequest %p didFinishLoadingFromBlob", this);
1380
1381     didFinishLoadingInternal();
1382 }
1383
1384 void XMLHttpRequest::didFailLoadingFromBlob()
1385 {
1386     WTF_LOG(Network, "XMLHttpRequest %p didFailLoadingFromBlob()", this);
1387
1388     if (m_error)
1389         return;
1390     handleNetworkError();
1391 }
1392
1393 PassRefPtr<BlobDataHandle> XMLHttpRequest::createBlobDataHandleFromResponse()
1394 {
1395     ASSERT(m_downloadingToFile);
1396     OwnPtr<BlobData> blobData = BlobData::create();
1397     String filePath = m_response.downloadedFilePath();
1398     // If we errored out or got no data, we return an empty handle.
1399     if (!filePath.isEmpty() && m_lengthDownloadedToFile) {
1400         blobData->appendFile(filePath);
1401         // FIXME: finalResponseMIMETypeWithFallback() defaults to
1402         // text/xml which may be incorrect. Replace it with
1403         // finalResponseMIMEType() after compatibility investigation.
1404         blobData->setContentType(finalResponseMIMETypeWithFallback());
1405     }
1406     return BlobDataHandle::create(blobData.release(), m_lengthDownloadedToFile);
1407 }
1408
1409 void XMLHttpRequest::notifyParserStopped()
1410 {
1411     // This should only be called when response document is parsed asynchronously.
1412     ASSERT(m_responseDocumentParser);
1413     ASSERT(!m_responseDocumentParser->isParsing());
1414     ASSERT(!m_responseLegacyStream);
1415     ASSERT(!m_responseStream);
1416
1417     // Do nothing if we are called from |internalAbort()|.
1418     if (m_error)
1419         return;
1420
1421     clearVariablesForLoading();
1422
1423     m_responseDocument->implicitClose();
1424
1425     if (!m_responseDocument->wellFormed())
1426         m_responseDocument = nullptr;
1427
1428     m_parsedResponse = true;
1429
1430     endLoading();
1431 }
1432
1433 void XMLHttpRequest::endLoading()
1434 {
1435     InspectorInstrumentation::didFinishXHRLoading(executionContext(), this, this, m_loaderIdentifier, m_responseText, m_method, m_url);
1436
1437     if (m_loader)
1438         m_loader = nullptr;
1439     m_loaderIdentifier = 0;
1440
1441     changeState(DONE);
1442 }
1443
1444 void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
1445 {
1446     WTF_LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSent, totalBytesToBeSent);
1447
1448     if (!m_upload)
1449         return;
1450
1451     if (m_uploadEventsAllowed)
1452         m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent);
1453
1454     if (bytesSent == totalBytesToBeSent && !m_uploadComplete) {
1455         m_uploadComplete = true;
1456         if (m_uploadEventsAllowed)
1457             m_upload->dispatchEventAndLoadEnd(EventTypeNames::load, true, bytesSent, totalBytesToBeSent);
1458     }
1459 }
1460
1461 void XMLHttpRequest::didReceiveResponse(unsigned long identifier, const ResourceResponse& response, PassOwnPtr<WebDataConsumerHandle>)
1462 {
1463     WTF_LOG(Network, "XMLHttpRequest %p didReceiveResponse(%lu)", this, identifier);
1464
1465     m_response = response;
1466     if (!m_mimeTypeOverride.isEmpty()) {
1467         m_response.setHTTPHeaderField("Content-Type", m_mimeTypeOverride);
1468         m_finalResponseCharset = extractCharsetFromMediaType(m_mimeTypeOverride);
1469     }
1470
1471     if (m_finalResponseCharset.isEmpty())
1472         m_finalResponseCharset = response.textEncodingName();
1473 }
1474
1475 void XMLHttpRequest::parseDocumentChunk(const char* data, unsigned len)
1476 {
1477     if (!m_responseDocumentParser) {
1478         ASSERT(!m_responseDocument);
1479         initResponseDocument();
1480         if (!m_responseDocument)
1481             return;
1482
1483         m_responseDocumentParser = m_responseDocument->implicitOpen();
1484         m_responseDocumentParser->addClient(this);
1485     }
1486     ASSERT(m_responseDocumentParser);
1487
1488     if (m_responseDocumentParser->needsDecoder())
1489         m_responseDocumentParser->setDecoder(createDecoder());
1490
1491     m_responseDocumentParser->appendBytes(data, len);
1492 }
1493
1494 PassOwnPtr<TextResourceDecoder> XMLHttpRequest::createDecoder() const
1495 {
1496     if (m_responseTypeCode == ResponseTypeJSON)
1497         return TextResourceDecoder::create("application/json", "UTF-8");
1498
1499     if (!m_finalResponseCharset.isEmpty())
1500         return TextResourceDecoder::create("text/plain", m_finalResponseCharset);
1501
1502     // allow TextResourceDecoder to look inside the m_response if it's XML or HTML
1503     if (responseIsXML()) {
1504         OwnPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("application/xml");
1505         // Don't stop on encoding errors, unlike it is done for other kinds
1506         // of XML resources. This matches the behavior of previous WebKit
1507         // versions, Firefox and Opera.
1508         decoder->useLenientXMLDecoding();
1509
1510         return decoder.release();
1511     }
1512
1513     if (responseIsHTML())
1514         return TextResourceDecoder::create("text/html", "UTF-8");
1515
1516     return TextResourceDecoder::create("text/plain", "UTF-8");
1517 }
1518
1519 void XMLHttpRequest::didReceiveData(const char* data, unsigned len)
1520 {
1521     if (m_error)
1522         return;
1523
1524     if (m_state < HEADERS_RECEIVED)
1525         changeState(HEADERS_RECEIVED);
1526
1527     // We need to check for |m_error| again, because |changeState| may trigger
1528     // readystatechange, and user javascript can cause |abort()|.
1529     if (m_error)
1530         return;
1531
1532     if (!len)
1533         return;
1534
1535     if (m_responseTypeCode == ResponseTypeDocument && responseIsHTML()) {
1536         parseDocumentChunk(data, len);
1537     } else if (m_responseTypeCode == ResponseTypeDefault || m_responseTypeCode == ResponseTypeText || m_responseTypeCode == ResponseTypeJSON || m_responseTypeCode == ResponseTypeDocument) {
1538         if (!m_decoder)
1539             m_decoder = createDecoder();
1540
1541         m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len));
1542     } else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCode == ResponseTypeBlob) {
1543         // Buffer binary data.
1544         if (!m_binaryResponseBuilder)
1545             m_binaryResponseBuilder = SharedBuffer::create();
1546         m_binaryResponseBuilder->append(data, len);
1547     } else if (m_responseTypeCode == ResponseTypeLegacyStream) {
1548         if (!m_responseLegacyStream)
1549             m_responseLegacyStream = Stream::create(executionContext(), responseType());
1550         m_responseLegacyStream->addData(data, len);
1551     } else if (m_responseTypeCode == ResponseTypeStream) {
1552         if (!m_responseStream) {
1553             m_responseStream = new ReadableStreamImpl<ReadableStreamChunkTypeTraits<DOMArrayBuffer> >(executionContext(), new ReadableStreamSource(this));
1554             m_responseStream->didSourceStart();
1555         }
1556         m_responseStream->enqueue(DOMArrayBuffer::create(data, len));
1557     }
1558
1559     if (m_blobLoader) {
1560         // In this case, the data is provided by m_blobLoader. As progress
1561         // events are already fired, we should return here.
1562         return;
1563     }
1564     trackProgress(len);
1565 }
1566
1567 void XMLHttpRequest::didDownloadData(int dataLength)
1568 {
1569     if (m_error)
1570         return;
1571
1572     ASSERT(m_downloadingToFile);
1573
1574     if (m_state < HEADERS_RECEIVED)
1575         changeState(HEADERS_RECEIVED);
1576
1577     if (!dataLength)
1578         return;
1579
1580     // readystatechange event handler may do something to put this XHR in error
1581     // state. We need to check m_error again here.
1582     if (m_error)
1583         return;
1584
1585     m_lengthDownloadedToFile += dataLength;
1586
1587     trackProgress(dataLength);
1588 }
1589
1590 void XMLHttpRequest::handleDidTimeout()
1591 {
1592     WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this);
1593
1594     // Response is cleared next, save needed progress event data.
1595     long long expectedLength = m_response.expectedContentLength();
1596     long long receivedLength = m_receivedLength;
1597
1598     // Prevent the XMLHttpRequest instance from being destoryed during
1599     // |internalAbort()|.
1600     RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
1601
1602     if (!internalAbort())
1603         return;
1604
1605     handleRequestError(TimeoutError, EventTypeNames::timeout, receivedLength, expectedLength);
1606 }
1607
1608 void XMLHttpRequest::suspend()
1609 {
1610     m_progressEventThrottle.suspend();
1611 }
1612
1613 void XMLHttpRequest::resume()
1614 {
1615     m_progressEventThrottle.resume();
1616 }
1617
1618 void XMLHttpRequest::stop()
1619 {
1620     internalAbort();
1621 }
1622
1623 bool XMLHttpRequest::hasPendingActivity() const
1624 {
1625     // Neither this object nor the JavaScript wrapper should be deleted while
1626     // a request is in progress because we need to keep the listeners alive,
1627     // and they are referenced by the JavaScript wrapper.
1628     // |m_loader| is non-null while request is active and ThreadableLoaderClient
1629     // callbacks may be called, and |m_responseDocumentParser| is non-null while
1630     // DocumentParserClient callbacks may be called.
1631     return m_loader || m_responseDocumentParser;
1632 }
1633
1634 void XMLHttpRequest::contextDestroyed()
1635 {
1636     ASSERT(!m_loader);
1637     ActiveDOMObject::contextDestroyed();
1638 }
1639
1640 const AtomicString& XMLHttpRequest::interfaceName() const
1641 {
1642     return EventTargetNames::XMLHttpRequest;
1643 }
1644
1645 ExecutionContext* XMLHttpRequest::executionContext() const
1646 {
1647     return ActiveDOMObject::executionContext();
1648 }
1649
1650 void XMLHttpRequest::trace(Visitor* visitor)
1651 {
1652     visitor->trace(m_responseBlob);
1653     visitor->trace(m_responseLegacyStream);
1654     visitor->trace(m_responseStream);
1655     visitor->trace(m_streamSource);
1656     visitor->trace(m_responseDocument);
1657     visitor->trace(m_responseDocumentParser);
1658     visitor->trace(m_progressEventThrottle);
1659     visitor->trace(m_upload);
1660     visitor->trace(m_blobLoader);
1661     XMLHttpRequestEventTarget::trace(visitor);
1662     DocumentParserClient::trace(visitor);
1663 }
1664
1665 } // namespace blink