mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-05 05:30:29 +00:00
Bug 1264178 - Part 1: Expose URL fragment to request but not response. r=bkelly
--HG-- extra : rebase_source : ee0cac184ac64b1fa9185f912753f10b61a55383
This commit is contained in:
parent
bea3aefea7
commit
a63de77d6a
2
dom/cache/CacheTypes.ipdlh
vendored
2
dom/cache/CacheTypes.ipdlh
vendored
@ -50,12 +50,12 @@ struct HeadersEntry
|
||||
nsCString name;
|
||||
nsCString value;
|
||||
};
|
||||
|
||||
struct CacheRequest
|
||||
{
|
||||
nsCString method;
|
||||
nsCString urlWithoutQuery;
|
||||
nsCString urlQuery;
|
||||
nsCString urlFragment;
|
||||
HeadersEntry[] headers;
|
||||
HeadersGuardEnum headersGuard;
|
||||
nsString referrer;
|
||||
|
84
dom/cache/DBSchema.cpp
vendored
84
dom/cache/DBSchema.cpp
vendored
@ -32,20 +32,15 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
namespace db {
|
||||
|
||||
const int32_t kFirstShippedSchemaVersion = 15;
|
||||
|
||||
namespace {
|
||||
|
||||
// Update this whenever the DB schema is changed.
|
||||
const int32_t kLatestSchemaVersion = 23;
|
||||
|
||||
const int32_t kLatestSchemaVersion = 24;
|
||||
// ---------
|
||||
// The following constants define the SQL schema. These are defined in the
|
||||
// same order the SQL should be executed in CreateOrMigrateSchema(). They are
|
||||
// broken out as constants for convenient use in validation and migration.
|
||||
// ---------
|
||||
|
||||
// The caches table is the single source of truth about what Cache
|
||||
// objects exist for the origin. The contents of the Cache are stored
|
||||
// in the entries table that references back to caches.
|
||||
@ -103,14 +98,13 @@ const char* const kTableEntries =
|
||||
"response_security_info_id INTEGER NULL REFERENCES security_info(id), "
|
||||
"response_principal_info TEXT NOT NULL, "
|
||||
"cache_id INTEGER NOT NULL REFERENCES caches(id) ON DELETE CASCADE, "
|
||||
|
||||
"request_redirect INTEGER NOT NULL, "
|
||||
"request_referrer_policy INTEGER NOT NULL, "
|
||||
"request_integrity TEXT NOT NULL"
|
||||
"request_integrity TEXT NOT NULL, "
|
||||
"request_url_fragment TEXT NOT NULL"
|
||||
// New columns must be added at the end of table to migrate and
|
||||
// validate properly.
|
||||
")";
|
||||
|
||||
// Create an index to support the QueryCache() matching algorithm. This
|
||||
// needs to quickly find entries in a given Cache that match the request
|
||||
// URL. The url query is separated in order to support the ignoreSearch
|
||||
@ -1655,6 +1649,7 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
"request_url_no_query_hash, "
|
||||
"request_url_query, "
|
||||
"request_url_query_hash, "
|
||||
"request_url_fragment, "
|
||||
"request_referrer, "
|
||||
"request_referrer_policy, "
|
||||
"request_headers_guard, "
|
||||
@ -1679,6 +1674,7 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
":request_url_no_query_hash, "
|
||||
":request_url_query, "
|
||||
":request_url_query_hash, "
|
||||
":request_url_fragment, "
|
||||
":request_referrer, "
|
||||
":request_referrer_policy, "
|
||||
":request_headers_guard, "
|
||||
@ -1724,19 +1720,19 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
nsAutoCString urlQueryHash;
|
||||
rv = HashCString(crypto, aRequest.urlQuery(), urlQueryHash);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = state->BindUTF8StringAsBlobByName(
|
||||
NS_LITERAL_CSTRING("request_url_query_hash"), urlQueryHash);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
rv = state->BindUTF8StringByName(NS_LITERAL_CSTRING("request_url_fragment"),
|
||||
aRequest.urlFragment());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = state->BindStringByName(NS_LITERAL_CSTRING("request_referrer"),
|
||||
aRequest.referrer());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_referrer_policy"),
|
||||
static_cast<int32_t>(aRequest.referrerPolicy()));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_headers_guard"),
|
||||
static_cast<int32_t>(aRequest.headersGuard()));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
@ -2043,13 +2039,13 @@ ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
MOZ_ASSERT(aSavedRequestOut);
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> state;
|
||||
nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT "
|
||||
"request_method, "
|
||||
"request_url_no_query, "
|
||||
"request_url_query, "
|
||||
"request_url_fragment, "
|
||||
"request_referrer, "
|
||||
"request_referrer_policy, "
|
||||
"request_headers_guard, "
|
||||
@ -2074,70 +2070,59 @@ ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
|
||||
|
||||
rv = state->GetUTF8String(0, aSavedRequestOut->mValue.method());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = state->GetUTF8String(1, aSavedRequestOut->mValue.urlWithoutQuery());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = state->GetUTF8String(2, aSavedRequestOut->mValue.urlQuery());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = state->GetString(3, aSavedRequestOut->mValue.referrer());
|
||||
rv = state->GetUTF8String(3, aSavedRequestOut->mValue.urlFragment());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
rv = state->GetString(4, aSavedRequestOut->mValue.referrer());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
int32_t referrerPolicy;
|
||||
rv = state->GetInt32(4, &referrerPolicy);
|
||||
rv = state->GetInt32(5, &referrerPolicy);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
aSavedRequestOut->mValue.referrerPolicy() =
|
||||
static_cast<ReferrerPolicy>(referrerPolicy);
|
||||
|
||||
int32_t guard;
|
||||
rv = state->GetInt32(5, &guard);
|
||||
rv = state->GetInt32(6, &guard);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
aSavedRequestOut->mValue.headersGuard() =
|
||||
static_cast<HeadersGuardEnum>(guard);
|
||||
|
||||
int32_t mode;
|
||||
rv = state->GetInt32(6, &mode);
|
||||
rv = state->GetInt32(7, &mode);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
aSavedRequestOut->mValue.mode() = static_cast<RequestMode>(mode);
|
||||
|
||||
int32_t credentials;
|
||||
rv = state->GetInt32(7, &credentials);
|
||||
rv = state->GetInt32(8, &credentials);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
aSavedRequestOut->mValue.credentials() =
|
||||
static_cast<RequestCredentials>(credentials);
|
||||
|
||||
int32_t requestContentPolicyType;
|
||||
rv = state->GetInt32(8, &requestContentPolicyType);
|
||||
rv = state->GetInt32(9, &requestContentPolicyType);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
aSavedRequestOut->mValue.contentPolicyType() =
|
||||
static_cast<nsContentPolicyType>(requestContentPolicyType);
|
||||
|
||||
int32_t requestCache;
|
||||
rv = state->GetInt32(9, &requestCache);
|
||||
rv = state->GetInt32(10, &requestCache);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
aSavedRequestOut->mValue.requestCache() =
|
||||
static_cast<RequestCache>(requestCache);
|
||||
|
||||
int32_t requestRedirect;
|
||||
rv = state->GetInt32(10, &requestRedirect);
|
||||
rv = state->GetInt32(11, &requestRedirect);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
aSavedRequestOut->mValue.requestRedirect() =
|
||||
static_cast<RequestRedirect>(requestRedirect);
|
||||
|
||||
rv = state->GetString(11, aSavedRequestOut->mValue.integrity());
|
||||
rv = state->GetString(12, aSavedRequestOut->mValue.integrity());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
bool nullBody = false;
|
||||
rv = state->GetIsNull(12, &nullBody);
|
||||
rv = state->GetIsNull(13, &nullBody);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
aSavedRequestOut->mHasBodyId = !nullBody;
|
||||
|
||||
if (aSavedRequestOut->mHasBodyId) {
|
||||
rv = ExtractId(state, 12, &aSavedRequestOut->mBodyId);
|
||||
rv = ExtractId(state, 13, &aSavedRequestOut->mBodyId);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
}
|
||||
|
||||
rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT "
|
||||
"name, "
|
||||
@ -2492,7 +2477,7 @@ nsresult MigrateFrom19To20(mozIStorageConnection* aConn, bool& aRewriteSchema);
|
||||
nsresult MigrateFrom20To21(mozIStorageConnection* aConn, bool& aRewriteSchema);
|
||||
nsresult MigrateFrom21To22(mozIStorageConnection* aConn, bool& aRewriteSchema);
|
||||
nsresult MigrateFrom22To23(mozIStorageConnection* aConn, bool& aRewriteSchema);
|
||||
|
||||
nsresult MigrateFrom23To24(mozIStorageConnection* aConn, bool& aRewriteSchema);
|
||||
// Configure migration functions to run for the given starting version.
|
||||
Migration sMigrationList[] = {
|
||||
Migration(15, MigrateFrom15To16),
|
||||
@ -2503,10 +2488,9 @@ Migration sMigrationList[] = {
|
||||
Migration(20, MigrateFrom20To21),
|
||||
Migration(21, MigrateFrom21To22),
|
||||
Migration(22, MigrateFrom22To23),
|
||||
Migration(23, MigrateFrom23To24),
|
||||
};
|
||||
|
||||
uint32_t sMigrationListLength = sizeof(sMigrationList) / sizeof(Migration);
|
||||
|
||||
nsresult
|
||||
RewriteEntriesSchema(mozIStorageConnection* aConn)
|
||||
{
|
||||
@ -3001,15 +2985,31 @@ nsresult MigrateFrom22To23(mozIStorageConnection* aConn, bool& aRewriteSchema)
|
||||
|
||||
// The only change between 22 and 23 was a different snappy compression
|
||||
// format, but it's backwards-compatible.
|
||||
|
||||
nsresult rv = aConn->SetSchemaVersion(23);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
return rv;
|
||||
}
|
||||
nsresult MigrateFrom23To24(mozIStorageConnection* aConn, bool& aRewriteSchema)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
||||
// Add the request_url_fragment column.
|
||||
nsresult rv = aConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"ALTER TABLE entries "
|
||||
"ADD COLUMN request_url_fragment TEXT NOT NULL DEFAULT ''"
|
||||
));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
rv = aConn->SetSchemaVersion(24);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
aRewriteSchema = true;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
} // namespace db
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
|
16
dom/cache/TypeUtils.cpp
vendored
16
dom/cache/TypeUtils.cpp
vendored
@ -122,18 +122,13 @@ TypeUtils::ToCacheRequest(CacheRequest& aOut, InternalRequest* aIn,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aIn);
|
||||
|
||||
aIn->GetMethod(aOut.method());
|
||||
|
||||
nsAutoCString url;
|
||||
aIn->GetURL(url);
|
||||
|
||||
nsCString url(aIn->GetURLWithoutFragment());
|
||||
bool schemeValid;
|
||||
ProcessURL(url, &schemeValid, &aOut.urlWithoutQuery(), &aOut.urlQuery(), aRv);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!schemeValid) {
|
||||
if (aSchemeAction == TypeErrorOnInvalidScheme) {
|
||||
NS_ConvertUTF8toUTF16 urlUTF16(url);
|
||||
@ -142,10 +137,10 @@ TypeUtils::ToCacheRequest(CacheRequest& aOut, InternalRequest* aIn,
|
||||
return;
|
||||
}
|
||||
}
|
||||
aOut.urlFragment() = aIn->GetFragment();
|
||||
|
||||
aIn->GetReferrer(aOut.referrer());
|
||||
aOut.referrerPolicy() = aIn->ReferrerPolicy_();
|
||||
|
||||
RefPtr<InternalHeaders> headers = aIn->Headers();
|
||||
MOZ_ASSERT(headers);
|
||||
ToHeadersEntryList(aOut.headers(), headers);
|
||||
@ -306,17 +301,14 @@ TypeUtils::ToResponse(const CacheResponse& aIn)
|
||||
RefPtr<Response> ref = new Response(GetGlobalObject(), ir);
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<InternalRequest>
|
||||
TypeUtils::ToInternalRequest(const CacheRequest& aIn)
|
||||
{
|
||||
nsAutoCString url(aIn.urlWithoutQuery());
|
||||
url.Append(aIn.urlQuery());
|
||||
|
||||
RefPtr<InternalRequest> internalRequest = new InternalRequest(url);
|
||||
|
||||
RefPtr<InternalRequest> internalRequest =
|
||||
new InternalRequest(url, aIn.urlFragment());
|
||||
internalRequest->SetMethod(aIn.method());
|
||||
|
||||
internalRequest->SetReferrer(aIn.referrer());
|
||||
internalRequest->SetReferrerPolicy(aIn.referrerPolicy());
|
||||
internalRequest->SetMode(aIn.mode());
|
||||
|
@ -25,6 +25,35 @@ function checkResponse(r, expectedBody) {
|
||||
}
|
||||
});
|
||||
}
|
||||
function checkFragment(cache, request, requestWithDifferentFragment) {
|
||||
var req1 = new Request(request);
|
||||
var req2 = new Request(requestWithDifferentFragment);
|
||||
var res1 = new Response("Hello World1");
|
||||
var res2 = new Response("Hello World2");
|
||||
|
||||
// Ensure both request and requestWithDifferentFragment have fragment.
|
||||
ok(req1.url.includes('#fragment'), "Request URL should keep the fragment.");
|
||||
ok(req2.url.includes('#other'), "Request URL should keep the fragment.");
|
||||
|
||||
cache.put(req1, res1).then(() => cache.put(req2, res2))
|
||||
.then(function () {
|
||||
// Test for ensuring we get the fragment from cache request.
|
||||
cache.keys(req2).then(function(keys) {
|
||||
keys.forEach(function(r, index, array) {
|
||||
is(req2.url, r.url, "Request URL should be the same");
|
||||
});
|
||||
})
|
||||
return cache.match(req1);
|
||||
}).then(function (resp) {
|
||||
return resp.text();
|
||||
}).then(function (body) {
|
||||
// Test for ensuring only the last response will be cached.
|
||||
is(body, "Hello World2", "Response should be the same as last one");
|
||||
cache.delete(req1);
|
||||
cache.delete(req2);
|
||||
});
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
fetch(new Request(request)).then(function(r) {
|
||||
response = r;
|
||||
@ -39,12 +68,13 @@ fetch(new Request(request)).then(function(r) {
|
||||
}).then(function() {
|
||||
testDone();
|
||||
});
|
||||
|
||||
// The request argument can either be a URL string, or a Request object.
|
||||
function testRequest(request, unknownRequest, requestWithAlternateQueryString,
|
||||
requestWithDifferentFragment) {
|
||||
return caches.open(name).then(function(cache) {
|
||||
c = cache;
|
||||
return checkFragment(c, request, requestWithDifferentFragment);
|
||||
}).then(function() {
|
||||
return c.add(request);
|
||||
}).then(function() {
|
||||
return Promise.all(
|
||||
|
@ -375,19 +375,15 @@ FetchDriver::HttpFetch()
|
||||
// Step 4 onwards of "HTTP Fetch" is handled internally by Necko.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<InternalResponse>
|
||||
FetchDriver::BeginAndGetFilteredResponse(InternalResponse* aResponse,
|
||||
bool aFoundOpaqueRedirect)
|
||||
{
|
||||
MOZ_ASSERT(aResponse);
|
||||
|
||||
AutoTArray<nsCString, 4> reqURLList;
|
||||
mRequest->GetURLList(reqURLList);
|
||||
|
||||
mRequest->GetURLListWithoutFragment(reqURLList);
|
||||
MOZ_ASSERT(!reqURLList.IsEmpty());
|
||||
aResponse->SetURLList(reqURLList);
|
||||
|
||||
RefPtr<InternalResponse> filteredResponse;
|
||||
if (aFoundOpaqueRedirect) {
|
||||
filteredResponse = aResponse->OpaqueRedirectResponse();
|
||||
@ -808,15 +804,18 @@ FetchDriver::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
||||
if(NS_WARN_IF(NS_FAILED(rv))){
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCString spec;
|
||||
rv = uriClone->GetSpec(spec);
|
||||
if(NS_WARN_IF(NS_FAILED(rv))){
|
||||
return rv;
|
||||
}
|
||||
nsCString fragment;
|
||||
rv = uri->GetRef(fragment);
|
||||
if(NS_WARN_IF(NS_FAILED(rv))){
|
||||
return rv;
|
||||
}
|
||||
|
||||
mRequest->AddURL(spec);
|
||||
|
||||
mRequest->AddURL(spec, fragment);
|
||||
NS_ConvertUTF8toUTF16 tRPHeaderValue(tRPHeaderCValue);
|
||||
// updates request’s associated referrer policy according to the
|
||||
// Referrer-Policy header (if any).
|
||||
|
@ -19,18 +19,16 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
// The global is used to extract the principal.
|
||||
already_AddRefed<InternalRequest>
|
||||
InternalRequest::GetRequestConstructorCopy(nsIGlobalObject* aGlobal, ErrorResult& aRv) const
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!mURLList.IsEmpty(), "Internal Request's urlList should not be empty when copied from constructor.");
|
||||
|
||||
RefPtr<InternalRequest> copy = new InternalRequest(mURLList.LastElement());
|
||||
RefPtr<InternalRequest> copy = new InternalRequest(mURLList.LastElement(),
|
||||
mFragment);
|
||||
copy->SetMethod(mMethod);
|
||||
copy->mHeaders = new InternalHeaders(*mHeaders);
|
||||
copy->SetUnsafeRequest();
|
||||
|
||||
copy->mBodyStream = mBodyStream;
|
||||
copy->mForceOriginHeader = true;
|
||||
// The "client" is not stored in our implementation. Fetch API users should
|
||||
@ -75,11 +73,10 @@ InternalRequest::Clone()
|
||||
if (replacementBody) {
|
||||
mBodyStream.swap(replacementBody);
|
||||
}
|
||||
|
||||
return clone.forget();
|
||||
}
|
||||
|
||||
InternalRequest::InternalRequest(const nsACString& aURL)
|
||||
InternalRequest::InternalRequest(const nsACString& aURL,
|
||||
const nsACString& aFragment)
|
||||
: mMethod("GET")
|
||||
, mHeaders(new InternalHeaders(HeadersGuardEnum::None))
|
||||
, mContentPolicyType(nsIContentPolicy::TYPE_FETCH)
|
||||
@ -105,10 +102,10 @@ InternalRequest::InternalRequest(const nsACString& aURL)
|
||||
, mUseURLCredentials(false)
|
||||
{
|
||||
MOZ_ASSERT(!aURL.IsEmpty());
|
||||
AddURL(aURL);
|
||||
AddURL(aURL, aFragment);
|
||||
}
|
||||
|
||||
InternalRequest::InternalRequest(const nsACString& aURL,
|
||||
const nsACString& aFragment,
|
||||
const nsACString& aMethod,
|
||||
already_AddRefed<InternalHeaders> aHeaders,
|
||||
RequestCache aCacheMode,
|
||||
@ -142,9 +139,8 @@ InternalRequest::InternalRequest(const nsACString& aURL,
|
||||
, mUseURLCredentials(false)
|
||||
{
|
||||
MOZ_ASSERT(!aURL.IsEmpty());
|
||||
AddURL(aURL);
|
||||
AddURL(aURL, aFragment);
|
||||
}
|
||||
|
||||
InternalRequest::InternalRequest(const InternalRequest& aOther)
|
||||
: mMethod(aOther.mMethod)
|
||||
, mURLList(aOther.mURLList)
|
||||
@ -159,6 +155,7 @@ InternalRequest::InternalRequest(const InternalRequest& aOther)
|
||||
, mCacheMode(aOther.mCacheMode)
|
||||
, mRedirectMode(aOther.mRedirectMode)
|
||||
, mIntegrity(aOther.mIntegrity)
|
||||
, mFragment(aOther.mFragment)
|
||||
, mAuthenticationFlag(aOther.mAuthenticationFlag)
|
||||
, mForceOriginHeader(aOther.mForceOriginHeader)
|
||||
, mPreserveContentCodings(aOther.mPreserveContentCodings)
|
||||
|
@ -87,17 +87,14 @@ class Request;
|
||||
class IPCInternalRequest;
|
||||
|
||||
#define kFETCH_CLIENT_REFERRER_STR "about:client"
|
||||
|
||||
class InternalRequest final
|
||||
{
|
||||
friend class Request;
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalRequest)
|
||||
|
||||
explicit InternalRequest(const nsACString& aURL);
|
||||
|
||||
InternalRequest(const nsACString& aURL, const nsACString& aFragment);
|
||||
InternalRequest(const nsACString& aURL,
|
||||
const nsACString& aFragment,
|
||||
const nsACString& aMethod,
|
||||
already_AddRefed<InternalHeaders> aHeaders,
|
||||
RequestCache aCacheMode,
|
||||
@ -134,37 +131,49 @@ public:
|
||||
mMethod.LowerCaseEqualsASCII("post") ||
|
||||
mMethod.LowerCaseEqualsASCII("head");
|
||||
}
|
||||
|
||||
// GetURL should get the request's current url. A request has an associated
|
||||
// current url. It is a pointer to the last fetch URL in request's url list.
|
||||
// GetURL should get the request's current url with fragment. A request has
|
||||
// an associated current url. It is a pointer to the last fetch URL in
|
||||
// request's url list.
|
||||
void
|
||||
GetURL(nsACString& aURL) const
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!mURLList.IsEmpty(), "Internal Request's urlList should not be empty.");
|
||||
|
||||
aURL.Assign(mURLList.LastElement());
|
||||
aURL.Assign(GetURLWithoutFragment());
|
||||
if (GetFragment().IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
aURL.Append(NS_LITERAL_CSTRING("#"));
|
||||
aURL.Append(GetFragment());
|
||||
}
|
||||
|
||||
const nsCString&
|
||||
GetURLWithoutFragment() const
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!mURLList.IsEmpty(),
|
||||
"Internal Request's urlList should not be empty.");
|
||||
|
||||
return mURLList.LastElement();
|
||||
}
|
||||
// AddURL should append the url into url list.
|
||||
// Normally we strip the fragment from the URL in Request::Constructor.
|
||||
// If internal code is directly constructing this object they must
|
||||
// strip the fragment first. Since these should be well formed URLs we
|
||||
// can use a simple check for a fragment here. The full parser is
|
||||
// difficult to use off the main thread.
|
||||
// Normally we strip the fragment from the URL in Request::Constructor and
|
||||
// pass the fragment as the second argument into it.
|
||||
// If a fragment is present in the URL it must be stripped and passed in
|
||||
// separately.
|
||||
void
|
||||
AddURL(const nsACString& aURL)
|
||||
AddURL(const nsACString& aURL, const nsACString& aFragment)
|
||||
{
|
||||
MOZ_ASSERT(!aURL.IsEmpty());
|
||||
mURLList.AppendElement(aURL);
|
||||
MOZ_ASSERT(mURLList.LastElement().Find(NS_LITERAL_CSTRING("#")) == kNotFound);
|
||||
}
|
||||
MOZ_ASSERT(!aURL.Contains('#'));
|
||||
|
||||
mURLList.AppendElement(aURL);
|
||||
|
||||
mFragment.Assign(aFragment);
|
||||
}
|
||||
// Get the URL list without their fragments.
|
||||
void
|
||||
GetURLList(nsTArray<nsCString>& aURLList)
|
||||
GetURLListWithoutFragment(nsTArray<nsCString>& aURLList)
|
||||
{
|
||||
aURLList.Assign(mURLList);
|
||||
}
|
||||
|
||||
void
|
||||
GetReferrer(nsAString& aReferrer) const
|
||||
{
|
||||
@ -321,20 +330,23 @@ public:
|
||||
{
|
||||
return mIntegrity;
|
||||
}
|
||||
|
||||
void
|
||||
SetIntegrity(const nsAString& aIntegrity)
|
||||
{
|
||||
MOZ_ASSERT(mIntegrity.IsEmpty());
|
||||
mIntegrity.Assign(aIntegrity);
|
||||
}
|
||||
const nsCString&
|
||||
GetFragment() const
|
||||
{
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
nsContentPolicyType
|
||||
ContentPolicyType() const
|
||||
{
|
||||
return mContentPolicyType;
|
||||
}
|
||||
|
||||
void
|
||||
SetContentPolicyType(nsContentPolicyType aContentPolicyType);
|
||||
|
||||
@ -491,15 +503,13 @@ private:
|
||||
// The Environment Referrer Policy should be net::ReferrerPolicy so that it
|
||||
// could be associated with nsIHttpChannel.
|
||||
net::ReferrerPolicy mEnvironmentReferrerPolicy;
|
||||
|
||||
RequestMode mMode;
|
||||
RequestCredentials mCredentialsMode;
|
||||
MOZ_INIT_OUTSIDE_CTOR LoadTainting mResponseTainting;
|
||||
RequestCache mCacheMode;
|
||||
RequestRedirect mRedirectMode;
|
||||
|
||||
nsString mIntegrity;
|
||||
|
||||
nsCString mFragment;
|
||||
MOZ_INIT_OUTSIDE_CTOR bool mAuthenticationFlag;
|
||||
MOZ_INIT_OUTSIDE_CTOR bool mForceOriginHeader;
|
||||
MOZ_INIT_OUTSIDE_CTOR bool mPreserveContentCodings;
|
||||
|
@ -89,16 +89,15 @@ ParseURLFromDocument(nsIDocument* aDocument, const nsAString& aInput,
|
||||
}
|
||||
return resolvedURI.forget();
|
||||
}
|
||||
|
||||
void
|
||||
GetRequestURLFromDocument(nsIDocument* aDocument, const nsAString& aInput,
|
||||
nsAString& aRequestURL, ErrorResult& aRv)
|
||||
nsAString& aRequestURL, nsACString& aURLfragment,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIURI> resolvedURI = ParseURLFromDocument(aDocument, aInput, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This fails with URIs with weird protocols, even when they are valid,
|
||||
// so we ignore the failure
|
||||
nsAutoCString credentials;
|
||||
@ -115,21 +114,23 @@ GetRequestURLFromDocument(nsIDocument* aDocument, const nsAString& aInput,
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString spec;
|
||||
aRv = resolvedURIClone->GetSpec(spec);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
CopyUTF8toUTF16(spec, aRequestURL);
|
||||
}
|
||||
|
||||
// Get the fragment from nsIURI.
|
||||
aRv = resolvedURI->GetRef(aURLfragment);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
already_AddRefed<nsIURI>
|
||||
ParseURLFromChrome(const nsAString& aInput, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
aRv = NS_NewURI(getter_AddRefs(uri), aInput, nullptr, nullptr);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
@ -137,16 +138,14 @@ ParseURLFromChrome(const nsAString& aInput, ErrorResult& aRv)
|
||||
}
|
||||
return uri.forget();
|
||||
}
|
||||
|
||||
void
|
||||
GetRequestURLFromChrome(const nsAString& aInput, nsAString& aRequestURL,
|
||||
ErrorResult& aRv)
|
||||
nsACString& aURLfragment, ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri = ParseURLFromChrome(aInput, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This fails with URIs with weird protocols, even when they are valid,
|
||||
// so we ignore the failure
|
||||
nsAutoCString credentials;
|
||||
@ -163,16 +162,19 @@ GetRequestURLFromChrome(const nsAString& aInput, nsAString& aRequestURL,
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString spec;
|
||||
aRv = uriClone->GetSpec(spec);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
CopyUTF8toUTF16(spec, aRequestURL);
|
||||
}
|
||||
|
||||
// Get the fragment from nsIURI.
|
||||
aRv = uri->GetRef(aURLfragment);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
already_AddRefed<URL>
|
||||
ParseURLFromWorker(const GlobalObject& aGlobal, const nsAString& aInput,
|
||||
ErrorResult& aRv)
|
||||
@ -188,16 +190,15 @@ ParseURLFromWorker(const GlobalObject& aGlobal, const nsAString& aInput,
|
||||
}
|
||||
return url.forget();
|
||||
}
|
||||
|
||||
void
|
||||
GetRequestURLFromWorker(const GlobalObject& aGlobal, const nsAString& aInput,
|
||||
nsAString& aRequestURL, ErrorResult& aRv)
|
||||
nsAString& aRequestURL, nsACString& aURLfragment,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<URL> url = ParseURLFromWorker(aGlobal, aInput, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsString username;
|
||||
url->GetUsername(username, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
@ -209,17 +210,27 @@ GetRequestURLFromWorker(const GlobalObject& aGlobal, const nsAString& aInput,
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!username.IsEmpty() || !password.IsEmpty()) {
|
||||
aRv.ThrowTypeError<MSG_URL_HAS_CREDENTIALS>(aInput);
|
||||
return;
|
||||
}
|
||||
// Get the fragment from URL.
|
||||
nsAutoString fragment;
|
||||
url->GetHash(fragment, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: URL::GetHash() includes the "#" and we want the fragment with out
|
||||
// the hash symbol.
|
||||
if (!fragment.IsEmpty()) {
|
||||
CopyUTF16toUTF8(Substring(fragment, 1), aURLfragment);
|
||||
}
|
||||
|
||||
url->SetHash(EmptyString(), aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
||||
url->Stringify(aRequestURL, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
@ -284,38 +295,33 @@ Request::Constructor(const GlobalObject& aGlobal,
|
||||
}
|
||||
|
||||
request = inputReq->GetInternalRequest();
|
||||
|
||||
} else {
|
||||
// aInput is USVString.
|
||||
// We need to get url before we create a InternalRequest.
|
||||
nsAutoString input;
|
||||
input.Assign(aInput.GetAsUSVString());
|
||||
|
||||
nsAutoString requestURL;
|
||||
nsCString fragment;
|
||||
if (NS_IsMainThread()) {
|
||||
nsIDocument* doc = GetEntryDocument();
|
||||
if (doc) {
|
||||
GetRequestURLFromDocument(doc, input, requestURL, aRv);
|
||||
GetRequestURLFromDocument(doc, input, requestURL, fragment, aRv);
|
||||
} else {
|
||||
// If we don't have a document, we must assume that this is a full URL.
|
||||
GetRequestURLFromChrome(input, requestURL, aRv);
|
||||
GetRequestURLFromChrome(input, requestURL, fragment, aRv);
|
||||
}
|
||||
} else {
|
||||
GetRequestURLFromWorker(aGlobal, input, requestURL, aRv);
|
||||
GetRequestURLFromWorker(aGlobal, input, requestURL, fragment, aRv);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
request = new InternalRequest(NS_ConvertUTF16toUTF8(requestURL));
|
||||
request = new InternalRequest(NS_ConvertUTF16toUTF8(requestURL), fragment);
|
||||
}
|
||||
|
||||
request = request->GetRequestConstructorCopy(global, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RequestMode fallbackMode = RequestMode::EndGuard_;
|
||||
RequestCredentials fallbackCredentials = RequestCredentials::EndGuard_;
|
||||
RequestCache fallbackCache = RequestCache::EndGuard_;
|
||||
|
@ -585,16 +585,13 @@ HttpServer::Connection::ConsumeLine(const char* aBuffer,
|
||||
NS_ENSURE_TRUE(tokens.hasMoreTokens(), NS_ERROR_UNEXPECTED);
|
||||
nsDependentCSubstring method = tokens.nextToken();
|
||||
NS_ENSURE_TRUE(NS_IsValidHTTPToken(method), NS_ERROR_UNEXPECTED);
|
||||
|
||||
NS_ENSURE_TRUE(tokens.hasMoreTokens(), NS_ERROR_UNEXPECTED);
|
||||
nsDependentCSubstring url = tokens.nextToken();
|
||||
// Seems like it's also allowed to pass full urls with scheme+host+port.
|
||||
// May need to support that.
|
||||
NS_ENSURE_TRUE(url.First() == '/', NS_ERROR_UNEXPECTED);
|
||||
|
||||
mPendingReq = new InternalRequest(url);
|
||||
mPendingReq = new InternalRequest(url, /* aURLFragment */ EmptyCString());
|
||||
mPendingReq->SetMethod(method);
|
||||
|
||||
NS_ENSURE_TRUE(tokens.hasMoreTokens(), NS_ERROR_UNEXPECTED);
|
||||
nsDependentCSubstring version = tokens.nextToken();
|
||||
NS_ENSURE_TRUE(StringBeginsWith(version, NS_LITERAL_CSTRING("HTTP/1.")),
|
||||
|
@ -231,16 +231,14 @@ function testMethod() {
|
||||
} catch(e) {
|
||||
is(e.name, "TypeError", "HEAD/GET request cannot have a body");
|
||||
}
|
||||
|
||||
// Non HEAD/GET should not throw.
|
||||
var r = new Request("", { method: "patch", body: "hello" });
|
||||
}
|
||||
|
||||
function testUrlFragment() {
|
||||
var req = new Request("./request#withfragment");
|
||||
is(req.url, (new URL("./request", self.location.href)).href, "request.url should be serialized with exclude fragment flag set");
|
||||
is(req.url, (new URL("./request#withfragment", self.location.href)).href,
|
||||
"request.url should be serialized without exclude fragment flag set");
|
||||
}
|
||||
|
||||
function testUrlMalformed() {
|
||||
try {
|
||||
var req = new Request("http:// example.com");
|
||||
|
@ -1248,6 +1248,7 @@ class FetchEventRunnable : public ExtendableFunctionalEventWorkerRunnable
|
||||
nsTArray<nsCString> mHeaderNames;
|
||||
nsTArray<nsCString> mHeaderValues;
|
||||
nsCString mSpec;
|
||||
nsCString mFragment;
|
||||
nsCString mMethod;
|
||||
nsString mClientId;
|
||||
bool mIsReload;
|
||||
@ -1319,18 +1320,17 @@ public:
|
||||
nsCOMPtr<nsIURI> uriNoFragment;
|
||||
rv = uri->CloneIgnoringRef(getter_AddRefs(uriNoFragment));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = uriNoFragment->GetSpec(mSpec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = uri->GetRef(mFragment);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uint32_t loadFlags;
|
||||
rv = channel->GetLoadFlags(&loadFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo;
|
||||
rv = channel->GetLoadInfo(getter_AddRefs(loadInfo));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mContentPolicyType = loadInfo->InternalContentPolicyType();
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
|
||||
@ -1475,8 +1475,8 @@ private:
|
||||
result.SuppressException();
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<InternalRequest> internalReq = new InternalRequest(mSpec,
|
||||
mFragment,
|
||||
mMethod,
|
||||
internalHeaders.forget(),
|
||||
mCacheMode,
|
||||
|
@ -2,7 +2,3 @@
|
||||
type: testharness
|
||||
[Check request values when initialized from url string]
|
||||
expected: FAIL
|
||||
|
||||
[Check request values when initialized from url and init values]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -419,14 +419,13 @@ async_test(function(t) {
|
||||
.then(function(frame) {
|
||||
assert_equals(
|
||||
frame.contentDocument.body.textContent,
|
||||
'Fragment Not Found',
|
||||
'Service worker should not expose URL fragments.');
|
||||
'Fragment Found :' + fragment,
|
||||
'Service worker should expose URL fragments in request.');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Service Worker must not expose FetchEvent URL fragments.');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/simple.html?cache';
|
||||
var frame;
|
||||
|
@ -80,21 +80,19 @@ function handleUsedCheck(event) {
|
||||
'bodyUsed: ' + lastResponseForUsedCheck.bodyUsed));
|
||||
}
|
||||
}
|
||||
|
||||
function handleFragmentCheck(event) {
|
||||
var body;
|
||||
if (event.request.url.indexOf('#') === -1) {
|
||||
body = 'Fragment Not Found';
|
||||
} else {
|
||||
body = 'Fragment Found';
|
||||
body = 'Fragment Found :' +
|
||||
event.request.url.substring(event.request.url.indexOf('#'));
|
||||
}
|
||||
event.respondWith(new Response(body));
|
||||
}
|
||||
|
||||
function handleCache(event) {
|
||||
event.respondWith(new Response(event.request.cache));
|
||||
}
|
||||
|
||||
function handleEventSource(event) {
|
||||
if (event.request.mode === 'navigate') {
|
||||
return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user