summaryrefslogtreecommitdiffstats
path: root/dom/xhr/XMLHttpRequestMainThread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/xhr/XMLHttpRequestMainThread.cpp')
-rw-r--r--dom/xhr/XMLHttpRequestMainThread.cpp80
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 {