Bug 1847358 part 1: move nsBaseChannel::ContentRange content out into its own class as mozilla::net::ContentRange; r=dlrobertson,necko-reviewers,valentin

Differential Revision: https://phabricator.services.mozilla.com/D203378
This commit is contained in:
Thomas Wisniewski 2024-03-04 21:34:27 +00:00
parent 0f74acc748
commit 820f1c6cb8
9 changed files with 121 additions and 84 deletions

View File

@ -47,6 +47,7 @@
#include "mozilla/dom/UserActivation.h"
#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/PreloaderBase.h"
#include "mozilla/net/ContentRange.h"
#include "mozilla/net/InterceptionInfo.h"
#include "mozilla/net/NeckoChannelParams.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h"
@ -1104,7 +1105,7 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest) {
if (IsBlobURI(uri)) {
nsBaseChannel* bchan = static_cast<nsBaseChannel*>(channel.get());
MOZ_ASSERT(bchan);
Maybe<nsBaseChannel::ContentRange> range = bchan->GetContentRange();
Maybe<mozilla::net::ContentRange> range = bchan->GetContentRange();
if (range.isSome()) {
range->AsHeader(contentRange);
}

View File

@ -12,6 +12,7 @@
#include "mozilla/ScopeExit.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/net/ContentRange.h"
#include "nsStreamUtils.h"
#include "nsMimeTypes.h"
@ -488,7 +489,7 @@ nsresult BlobURLInputStream::StoreBlobImplStream(
// If a Range header was in the request then fetch/XHR will have set a
// ContentRange on the channel earlier so we may slice the blob now.
blobImpl->GetType(blobContentType);
const Maybe<nsBaseChannel::ContentRange>& contentRange =
const Maybe<mozilla::net::ContentRange>& contentRange =
mChannel->GetContentRange();
if (contentRange.isSome()) {
IgnoredErrorResult result;

View File

@ -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"
@ -863,7 +864,7 @@ bool XMLHttpRequestMainThread::IsDeniedCrossSiteCORSRequest() {
return false;
}
Maybe<nsBaseChannel::ContentRange>
Maybe<mozilla::net::ContentRange>
XMLHttpRequestMainThread::GetRequestedContentRange() const {
MOZ_ASSERT(mChannel);
nsBaseChannel* baseChan = static_cast<nsBaseChannel*>(mChannel.get());
@ -878,7 +879,7 @@ void XMLHttpRequestMainThread::GetContentRangeHeader(nsACString& out) const {
out.SetIsVoid(true);
return;
}
Maybe<nsBaseChannel::ContentRange> range = GetRequestedContentRange();
Maybe<mozilla::net::ContentRange> range = GetRequestedContentRange();
if (range.isSome()) {
range->AsHeader(out);
} else {

View File

@ -507,7 +507,7 @@ class XMLHttpRequestMainThread final : public XMLHttpRequest,
void AbortInternal(ErrorResult& aRv);
Maybe<nsBaseChannel::ContentRange> GetRequestedContentRange() const;
Maybe<mozilla::net::ContentRange> GetRequestedContentRange() const;
void GetContentRangeHeader(nsACString&) const;
struct PendingEvent {

View File

@ -0,0 +1,64 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ContentRange.h"
#include "nsContentUtils.h"
mozilla::net::ContentRange::ContentRange(const nsACString& aRangeHeader,
uint64_t aSize)
: mStart(0), mEnd(0), mSize(0) {
auto parsed = nsContentUtils::ParseSingleRangeRequest(aRangeHeader, true);
// https://fetch.spec.whatwg.org/#ref-for-simple-range-header-value%E2%91%A1
// If rangeValue is failure, then return a network error.
if (!parsed) {
return;
}
// Sanity check: ParseSingleRangeRequest should handle these two cases.
// If rangeEndValue and rangeStartValue are null, then return failure.
MOZ_ASSERT(parsed->Start().isSome() || parsed->End().isSome());
// If rangeStartValue and rangeEndValue are numbers, and rangeStartValue
// is greater than rangeEndValue, then return failure.
MOZ_ASSERT(parsed->Start().isNothing() || parsed->End().isNothing() ||
*parsed->Start() <= *parsed->End());
// https://fetch.spec.whatwg.org/#ref-for-simple-range-header-value%E2%91%A1
// If rangeStart is null:
if (parsed->Start().isNothing()) {
// Set rangeStart to fullLength rangeEnd.
mStart = aSize - *parsed->End();
// Set rangeEnd to rangeStart + rangeEnd 1.
mEnd = mStart + *parsed->End() - 1;
// Otherwise:
} else {
// If rangeStart is greater than or equal to fullLength, then return a
// network error.
if (*parsed->Start() >= aSize) {
return;
}
mStart = *parsed->Start();
// If rangeEnd is null or rangeEnd is greater than or equal to fullLength,
// then set rangeEnd to fullLength 1.
if (parsed->End().isNothing() || *parsed->End() >= aSize) {
mEnd = aSize - 1;
} else {
mEnd = *parsed->End();
}
}
mSize = aSize;
}
void mozilla::net::ContentRange::AsHeader(nsACString& aOutString) const {
aOutString.Assign("bytes "_ns);
aOutString.AppendInt(mStart);
aOutString.AppendLiteral("-");
aOutString.AppendInt(mEnd);
aOutString.AppendLiteral("/");
aOutString.AppendInt(mSize);
}

View File

@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set et cin ts=4 sw=2 sts=2: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ContentRange_h__
#define ContentRange_h__
#include "mozilla/Maybe.h"
#include "nsString.h"
#include "nsISupportsImpl.h"
// nsIBaseChannel subclasses may support range headers when accessed via
// Fetch or XMLHTTPRequest, even if they are not HTTP assets and so do not
// normally have access to headers (such as the blob URLs). The ContentRange
// class helps to encapsulate much of the common logic involved in parsing,
// storing, validating, and writing out Content-Range headers.
namespace mozilla::net {
class ContentRange {
private:
uint64_t mStart{0};
uint64_t mEnd{0};
uint64_t mSize{0};
public:
uint64_t Start() const { return mStart; }
uint64_t End() const { return mEnd; }
uint64_t Size() const { return mSize; }
bool IsValid() const { return mStart < mSize; }
ContentRange(uint64_t aStart, uint64_t aEnd, uint64_t aSize)
: mStart(aStart), mEnd(aEnd), mSize(aSize) {}
ContentRange(const nsACString& aRangeHeader, uint64_t aSize);
void AsHeader(nsACString& aOutString) const;
};
} // namespace mozilla::net
#endif // ContentRange_h__

View File

@ -157,6 +157,7 @@ EXPORTS.mozilla += [
EXPORTS.mozilla.net += [
"CacheInfoIPCTypes.h",
"CaptivePortalService.h",
"ContentRange.h",
"Dashboard.h",
"DashboardTypes.h",
"DefaultURI.h",
@ -178,6 +179,7 @@ UNIFIED_SOURCES += [
"ArrayBufferInputStream.cpp",
"BackgroundFileSaver.cpp",
"CaptivePortalService.cpp",
"ContentRange.cpp",
"Dashboard.cpp",
"DefaultURI.cpp",
"EventTokenBucket.cpp",

View File

@ -966,59 +966,3 @@ NS_IMETHODIMP nsBaseChannel::GetCanceled(bool* aCanceled) {
void nsBaseChannel::SetupNeckoTarget() {
mNeckoTarget = GetMainThreadSerialEventTarget();
}
nsBaseChannel::ContentRange::ContentRange(const nsACString& aRangeHeader,
uint64_t aSize)
: mStart(0), mEnd(0), mSize(0) {
auto parsed = nsContentUtils::ParseSingleRangeRequest(aRangeHeader, true);
// https://fetch.spec.whatwg.org/#ref-for-simple-range-header-value%E2%91%A1
// If rangeValue is failure, then return a network error.
if (!parsed) {
return;
}
// Sanity check: ParseSingleRangeRequest should handle these two cases.
// If rangeEndValue and rangeStartValue are null, then return failure.
MOZ_ASSERT(parsed->Start().isSome() || parsed->End().isSome());
// If rangeStartValue and rangeEndValue are numbers, and rangeStartValue
// is greater than rangeEndValue, then return failure.
MOZ_ASSERT(parsed->Start().isNothing() || parsed->End().isNothing() ||
*parsed->Start() <= *parsed->End());
// https://fetch.spec.whatwg.org/#ref-for-simple-range-header-value%E2%91%A1
// If rangeStart is null:
if (parsed->Start().isNothing()) {
// Set rangeStart to fullLength rangeEnd.
mStart = aSize - *parsed->End();
// Set rangeEnd to rangeStart + rangeEnd 1.
mEnd = mStart + *parsed->End() - 1;
// Otherwise:
} else {
// If rangeStart is greater than or equal to fullLength, then return a
// network error.
if (*parsed->Start() >= aSize) {
return;
}
mStart = *parsed->Start();
// If rangeEnd is null or rangeEnd is greater than or equal to fullLength,
// then set rangeEnd to fullLength 1.
if (parsed->End().isNothing() || *parsed->End() >= aSize) {
mEnd = aSize - 1;
} else {
mEnd = *parsed->End();
}
}
mSize = aSize;
}
void nsBaseChannel::ContentRange::AsHeader(nsACString& aOutString) const {
aOutString.Assign("bytes "_ns);
aOutString.AppendInt(mStart);
aOutString.AppendLiteral("-");
aOutString.AppendInt(mEnd);
aOutString.AppendLiteral("/");
aOutString.AppendInt(mSize);
}

View File

@ -9,6 +9,7 @@
#include "mozilla/Maybe.h"
#include "mozilla/MozPromise.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/net/ContentRange.h"
#include "mozilla/net/NeckoTargetHolder.h"
#include "mozilla/net/PrivateBrowsingChannel.h"
#include "nsHashPropertyBag.h"
@ -199,35 +200,17 @@ class nsBaseChannel
// Blob requests may specify a range header. We must parse, validate, and
// store that info in a place where BlobURLInputStream::StoreBlobImplStream
// can access it. This class helps to encapsulate that logic.
class ContentRange {
private:
uint64_t mStart;
uint64_t mEnd;
uint64_t mSize;
public:
uint64_t Start() const { return mStart; }
uint64_t End() const { return mEnd; }
uint64_t Size() const { return mSize; }
bool IsValid() const { return mStart < mSize; }
ContentRange() : mStart(0), mEnd(0), mSize(0) {}
ContentRange(uint64_t aStart, uint64_t aEnd, uint64_t aSize)
: mStart(aStart), mEnd(aEnd), mSize(aSize) {}
ContentRange(const nsACString& aRangeHeader, uint64_t aSize);
void AsHeader(nsACString& aOutString) const;
};
const mozilla::Maybe<ContentRange>& GetContentRange() const {
// can access it.
const mozilla::Maybe<mozilla::net::ContentRange>& GetContentRange() const {
return mContentRange;
}
void SetContentRange(uint64_t aStart, uint64_t aEnd, uint64_t aSize) {
mContentRange.emplace(ContentRange(aStart, aEnd, aSize));
mContentRange.emplace(mozilla::net::ContentRange(aStart, aEnd, aSize));
}
bool SetContentRange(const nsACString& aRangeHeader, uint64_t aSize) {
auto range = ContentRange(aRangeHeader, aSize);
auto range = mozilla::net::ContentRange(aRangeHeader, aSize);
if (!range.IsValid()) {
return false;
}
@ -325,7 +308,7 @@ class nsBaseChannel
bool mWaitingOnAsyncRedirect{false};
bool mOpenRedirectChannel{false};
uint32_t mRedirectFlags{0};
mozilla::Maybe<ContentRange> mContentRange;
mozilla::Maybe<mozilla::net::ContentRange> mContentRange;
protected:
nsCString mContentType;