diff options
Diffstat (limited to 'dom/xhr/XMLHttpRequestMainThread.cpp')
-rw-r--r-- | dom/xhr/XMLHttpRequestMainThread.cpp | 80 |
1 files changed, 52 insertions, 28 deletions
diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp index dc256b10c2..ace26f296f 100644 --- a/dom/xhr/XMLHttpRequestMainThread.cpp +++ b/dom/xhr/XMLHttpRequestMainThread.cpp @@ -40,6 +40,7 @@ #include "mozilla/LoadInfo.h" #include "mozilla/LoadContext.h" #include "mozilla/MemoryReporting.h" +#include "mozilla/net/ContentRange.h" #include "mozilla/PreloaderBase.h" #include "mozilla/ScopeExit.h" #include "mozilla/SpinEventLoopUntil.h" @@ -48,9 +49,9 @@ #include "mozilla/StaticPrefs_privacy.h" #include "mozilla/dom/ProgressEvent.h" #include "nsDataChannel.h" +#include "nsIBaseChannel.h" #include "nsIJARChannel.h" #include "nsIJARURI.h" -#include "nsLayoutCID.h" #include "nsReadableUtils.h" #include "nsSandboxFlags.h" @@ -186,15 +187,17 @@ static void AddLoadFlags(nsIRequest* request, nsLoadFlags newFlags) { // invoked for increased scrutability. Save the previous value on the stack. namespace { struct DebugWorkerRefs { - RefPtr<ThreadSafeWorkerRef>& mTSWorkerRef; + Mutex& mMutex; + RefPtr<ThreadSafeWorkerRef> mTSWorkerRef; nsCString mPrev; - DebugWorkerRefs(RefPtr<ThreadSafeWorkerRef>& aTSWorkerRef, - const std::string& aStatus) - : mTSWorkerRef(aTSWorkerRef) { + DebugWorkerRefs(XMLHttpRequestMainThread& aXHR, const std::string& aStatus) + : mMutex(aXHR.mTSWorkerRefMutex) { + MutexAutoLock lock(mMutex); + + mTSWorkerRef = aXHR.mTSWorkerRef; + if (!mTSWorkerRef) { - MOZ_LOG(gXMLHttpRequestLog, LogLevel::Info, - ("No WorkerRef during: %s", aStatus.c_str())); return; } @@ -206,6 +209,8 @@ struct DebugWorkerRefs { } ~DebugWorkerRefs() { + MutexAutoLock lock(mMutex); + if (!mTSWorkerRef) { return; } @@ -213,6 +218,8 @@ struct DebugWorkerRefs { MOZ_ASSERT(mTSWorkerRef->Private()); SET_WORKERREF_DEBUG_STATUS(mTSWorkerRef->Ref(), mPrev); + + mTSWorkerRef = nullptr; } }; } // namespace @@ -220,11 +227,13 @@ struct DebugWorkerRefs { # define STREAM_STRING(stuff) \ (((const std::ostringstream&)(std::ostringstream() << stuff)) \ .str()) // NOLINT + # define DEBUG_WORKERREFS \ - DebugWorkerRefs MOZ_UNIQUE_VAR(debugWR__)(mTSWorkerRef, __func__) + DebugWorkerRefs MOZ_UNIQUE_VAR(debugWR__)(*this, __func__) + # define DEBUG_WORKERREFS1(x) \ DebugWorkerRefs MOZ_UNIQUE_VAR(debugWR__)( \ - mTSWorkerRef, STREAM_STRING(__func__ << ": " << x)) // NOLINT + *this, STREAM_STRING(__func__ << ": " << x)) // NOLINT #else # define DEBUG_WORKERREFS void() @@ -236,6 +245,9 @@ bool XMLHttpRequestMainThread::sDontWarnAboutSyncXHR = false; XMLHttpRequestMainThread::XMLHttpRequestMainThread( nsIGlobalObject* aGlobalObject) : XMLHttpRequest(aGlobalObject), +#ifdef DEBUG + mTSWorkerRefMutex("Debug WorkerRefs"), +#endif mResponseBodyDecodedPos(0), mResponseType(XMLHttpRequestResponseType::_empty), mState(XMLHttpRequest_Binding::UNSENT), @@ -864,14 +876,28 @@ bool XMLHttpRequestMainThread::IsDeniedCrossSiteCORSRequest() { return false; } -Maybe<nsBaseChannel::ContentRange> +bool XMLHttpRequestMainThread::BadContentRangeRequested() { + if (!mChannel) { + return false; + } + // Only nsIBaseChannel supports this + nsCOMPtr<nsIBaseChannel> baseChan = do_QueryInterface(mChannel); + if (!baseChan) { + return false; + } + // A bad range was requested if the channel has no content range + // despite the request specifying a range header. + return !baseChan->ContentRange() && mAuthorRequestHeaders.Has("range"); +} + +RefPtr<mozilla::net::ContentRange> XMLHttpRequestMainThread::GetRequestedContentRange() const { MOZ_ASSERT(mChannel); - nsBaseChannel* baseChan = static_cast<nsBaseChannel*>(mChannel.get()); + nsCOMPtr<nsIBaseChannel> baseChan = do_QueryInterface(mChannel); if (!baseChan) { - return mozilla::Nothing(); + return nullptr; } - return baseChan->GetContentRange(); + return baseChan->ContentRange(); } void XMLHttpRequestMainThread::GetContentRangeHeader(nsACString& out) const { @@ -879,8 +905,8 @@ void XMLHttpRequestMainThread::GetContentRangeHeader(nsACString& out) const { out.SetIsVoid(true); return; } - Maybe<nsBaseChannel::ContentRange> range = GetRequestedContentRange(); - if (range.isSome()) { + RefPtr<mozilla::net::ContentRange> range = GetRequestedContentRange(); + if (range) { range->AsHeader(out); } else { out.SetIsVoid(true); @@ -944,8 +970,7 @@ uint32_t XMLHttpRequestMainThread::GetStatus(ErrorResult& aRv) { nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel(); if (!httpChannel) { // Pretend like we got a 200/206 response, since our load was successful - return IsBlobURI(mRequestURL) && GetRequestedContentRange().isSome() ? 206 - : 200; + return GetRequestedContentRange() ? 206 : 200; } uint32_t status; @@ -1194,13 +1219,13 @@ bool XMLHttpRequestMainThread::IsSafeHeader( bool XMLHttpRequestMainThread::GetContentType(nsACString& aValue) const { MOZ_ASSERT(mChannel); - nsCOMPtr<nsIURI> uri; - if (NS_SUCCEEDED(mChannel->GetURI(getter_AddRefs(uri))) && - uri->SchemeIs("data")) { - nsDataChannel* dchan = static_cast<nsDataChannel*>(mChannel.get()); - MOZ_ASSERT(dchan); - aValue.Assign(dchan->MimeType()); - return true; + nsCOMPtr<nsIBaseChannel> baseChan = do_QueryInterface(mChannel); + if (baseChan) { + RefPtr<CMimeType> fullMimeType(baseChan->FullMimeType()); + if (fullMimeType) { + fullMimeType->Serialize(aValue); + return true; + } } if (NS_SUCCEEDED(mChannel->GetContentType(aValue))) { nsCString value; @@ -1956,8 +1981,7 @@ XMLHttpRequestMainThread::OnStartRequest(nsIRequest* request) { // If we were asked for a bad range on a blob URL, but we're async, // we should throw now in order to fire an error progress event. - if (IsBlobURI(mRequestURL) && GetRequestedContentRange().isNothing() && - mAuthorRequestHeaders.Has("range")) { + if (BadContentRangeRequested()) { return NS_ERROR_NET_PARTIAL_TRANSFER; } @@ -3128,7 +3152,7 @@ void XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody, if (uploadContentType.IsVoid()) { uploadContentType = defaultContentType; } else if (aBodyIsDocumentOrString) { - UniquePtr<CMimeType> contentTypeRecord = + RefPtr<CMimeType> contentTypeRecord = CMimeType::Parse(uploadContentType); nsAutoCString charset; if (contentTypeRecord && @@ -3391,7 +3415,7 @@ void XMLHttpRequestMainThread::OverrideMimeType(const nsAString& aMimeType, return; } - UniquePtr<MimeType> parsed = MimeType::Parse(aMimeType); + RefPtr<MimeType> parsed = MimeType::Parse(aMimeType); if (parsed) { parsed->Serialize(mOverrideMimeType); } else { |