gecko-dev/dom/fetch/InternalRequest.h

624 строки
16 KiB
C
Исходник Обычный вид История

/* -*- 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/. */
#ifndef mozilla_dom_InternalRequest_h
#define mozilla_dom_InternalRequest_h
#include "mozilla/dom/HeadersBinding.h"
#include "mozilla/dom/InternalHeaders.h"
#include "mozilla/dom/RequestBinding.h"
#include "mozilla/LoadTainting.h"
#include "mozilla/net/ReferrerPolicy.h"
#include "nsIContentPolicy.h"
#include "nsIInputStream.h"
#include "nsISupportsImpl.h"
#ifdef DEBUG
#include "nsIURLParser.h"
#include "nsNetCID.h"
#include "nsServiceManagerUtils.h"
#endif
namespace mozilla {
namespace ipc {
class PrincipalInfo;
} // namespace ipc
namespace dom {
/*
* The mapping of RequestDestination and nsContentPolicyType is currently as the
* following. Note that this mapping is not perfect yet (see the TODO comments
* below for examples).
*
* RequestDestination| nsContentPolicyType
* ------------------+--------------------
* audio | TYPE_INTERNAL_AUDIO
* audioworklet | TODO
* document | TYPE_DOCUMENT, TYPE_INTERNAL_IFRAME, TYPE_SUBDOCUMENT
* embed | TYPE_INTERNAL_EMBED
* font | TYPE_FONT
* image | TYPE_INTERNAL_IMAGE, TYPE_INTERNAL_IMAGE_PRELOAD,
* | TYPE_IMAGE, TYPE_INTERNAL_IMAGE_FAVICON, TYPE_IMAGESET
Bug 1089255 - Implement and test manifest-src CSP directive. r=bholley, r=dveditz, r=ckerschb --- dom/base/nsContentPolicyUtils.h | 1 + dom/base/nsDataDocumentContentPolicy.cpp | 3 +- dom/base/nsIContentPolicy.idl | 2 +- dom/base/nsIContentPolicyBase.idl | 7 +- dom/base/nsISimpleContentPolicy.idl | 2 +- dom/base/test/csp/browser.ini | 4 + dom/base/test/csp/browser_test_web_manifest.js | 265 +++++++++++++++++++++ .../csp/browser_test_web_manifest_mixed_content.js | 55 +++++ dom/base/test/csp/file_CSP_web_manifest.html | 6 + dom/base/test/csp/file_CSP_web_manifest.json | 1 + .../test/csp/file_CSP_web_manifest.json^headers^ | 1 + dom/base/test/csp/file_CSP_web_manifest_https.html | 4 + dom/base/test/csp/file_CSP_web_manifest_https.json | 1 + .../csp/file_CSP_web_manifest_mixed_content.html | 9 + .../test/csp/file_CSP_web_manifest_remote.html | 8 + dom/base/test/csp/file_csp_testserver.sjs | 14 +- dom/base/test/csp/mochitest.ini | 7 + dom/base/test/moz.build | 5 +- dom/fetch/InternalRequest.cpp | 3 + dom/fetch/InternalRequest.h | 2 +- .../security/nsIContentSecurityPolicy.idl | 3 +- dom/ipc/manifestMessages.js | 25 +- dom/security/nsCSPUtils.cpp | 7 + dom/security/nsCSPUtils.h | 10 +- dom/security/nsMixedContentBlocker.cpp | 1 + dom/webidl/CSPDictionaries.webidl | 1 + extensions/permissions/nsContentBlocker.cpp | 6 +- netwerk/mime/nsMimeTypes.h | 1 + 28 files changed, 439 insertions(+), 15 deletions(-) create mode 100644 dom/base/test/csp/browser.ini create mode 100644 dom/base/test/csp/browser_test_web_manifest.js create mode 100644 dom/base/test/csp/browser_test_web_manifest_mixed_content.js create mode 100644 dom/base/test/csp/file_CSP_web_manifest.html create mode 100644 dom/base/test/csp/file_CSP_web_manifest.json create mode 100644 dom/base/test/csp/file_CSP_web_manifest.json^headers^ create mode 100644 dom/base/test/csp/file_CSP_web_manifest_https.html create mode 100644 dom/base/test/csp/file_CSP_web_manifest_https.json create mode 100644 dom/base/test/csp/file_CSP_web_manifest_mixed_content.html create mode 100644 dom/base/test/csp/file_CSP_web_manifest_remote.html
2015-06-02 22:42:19 +03:00
* manifest | TYPE_WEB_MANIFEST
* object | TYPE_INTERNAL_OBJECT, TYPE_OBJECT
* "paintworklet" | TODO
* report" | TODO
* script | TYPE_INTERNAL_SCRIPT, TYPE_INTERNAL_SCRIPT_PRELOAD, TYPE_SCRIPT
* | TYPE_INTERNAL_SERVICE_WORKER, TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS
* sharedworker | TYPE_INTERNAL_SHARED_WORKER
* serviceworker | The spec lists this as a valid value for the enum,however it
* | is impossible to observe a request with this destination value.
* style | TYPE_INTERNAL_STYLESHEET, TYPE_INTERNAL_STYLESHEET_PRELOAD,
* | TYPE_STYLESHEET
* track | TYPE_INTERNAL_TRACK
* video | TYPE_INTERNAL_VIDEO
* worker | TYPE_INTERNAL_WORKER
* xslt | TYPE_XSLT
* _empty | Default for everything else.
*
*/
class Request;
class IPCInternalRequest;
#define kFETCH_CLIENT_REFERRER_STR "about:client"
class InternalRequest final
{
friend class Request;
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalRequest)
InternalRequest(const nsACString& aURL, const nsACString& aFragment);
InternalRequest(const nsACString& aURL,
const nsACString& aFragment,
const nsACString& aMethod,
already_AddRefed<InternalHeaders> aHeaders,
RequestCache aCacheMode,
RequestMode aMode,
RequestRedirect aRequestRedirect,
RequestCredentials aRequestCredentials,
const nsAString& aReferrer,
ReferrerPolicy aReferrerPolicy,
nsContentPolicyType aContentPolicyType,
const nsAString& aIntegrity);
explicit InternalRequest(const IPCInternalRequest& aIPCRequest);
void ToIPC(IPCInternalRequest* aIPCRequest);
already_AddRefed<InternalRequest> Clone();
void
GetMethod(nsCString& aMethod) const
{
aMethod.Assign(mMethod);
}
void
SetMethod(const nsACString& aMethod)
{
mMethod.Assign(aMethod);
}
bool
HasSimpleMethod() const
{
return mMethod.LowerCaseEqualsASCII("get") ||
mMethod.LowerCaseEqualsASCII("post") ||
mMethod.LowerCaseEqualsASCII("head");
}
// 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
{
aURL.Assign(GetURLWithoutFragment());
if (GetFragment().IsEmpty()) {
return;
}
aURL.AppendLiteral("#");
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 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, const nsACString& aFragment)
{
MOZ_ASSERT(!aURL.IsEmpty());
MOZ_ASSERT(!aURL.Contains('#'));
mURLList.AppendElement(aURL);
mFragment.Assign(aFragment);
}
// Get the URL list without their fragments.
void
GetURLListWithoutFragment(nsTArray<nsCString>& aURLList)
{
aURLList.Assign(mURLList);
}
void
GetReferrer(nsAString& aReferrer) const
{
aReferrer.Assign(mReferrer);
}
void
SetReferrer(const nsAString& aReferrer)
{
#ifdef DEBUG
bool validReferrer = false;
if (aReferrer.IsEmpty() ||
aReferrer.EqualsLiteral(kFETCH_CLIENT_REFERRER_STR)) {
validReferrer = true;
} else {
nsCOMPtr<nsIURLParser> parser = do_GetService(NS_STDURLPARSER_CONTRACTID);
if (!parser) {
NS_WARNING("Could not get parser to validate URL!");
} else {
uint32_t schemePos;
int32_t schemeLen;
uint32_t authorityPos;
int32_t authorityLen;
uint32_t pathPos;
int32_t pathLen;
NS_ConvertUTF16toUTF8 ref(aReferrer);
nsresult rv = parser->ParseURL(ref.get(), ref.Length(),
&schemePos, &schemeLen,
&authorityPos, &authorityLen,
&pathPos, &pathLen);
if (NS_FAILED(rv)) {
NS_WARNING("Invalid referrer URL!");
} else if (schemeLen < 0 || authorityLen < 0) {
NS_WARNING("Invalid referrer URL!");
} else {
validReferrer = true;
}
}
}
MOZ_ASSERT(validReferrer);
#endif
mReferrer.Assign(aReferrer);
}
ReferrerPolicy
ReferrerPolicy_() const
{
return mReferrerPolicy;
}
void
SetReferrerPolicy(ReferrerPolicy aReferrerPolicy)
{
mReferrerPolicy = aReferrerPolicy;
}
void
SetReferrerPolicy(net::ReferrerPolicy aReferrerPolicy)
{
switch (aReferrerPolicy) {
case net::RP_Unset:
mReferrerPolicy = ReferrerPolicy::_empty;
break;
case net::RP_No_Referrer:
mReferrerPolicy = ReferrerPolicy::No_referrer;
break;
case net::RP_No_Referrer_When_Downgrade:
mReferrerPolicy = ReferrerPolicy::No_referrer_when_downgrade;
break;
case net::RP_Origin:
mReferrerPolicy = ReferrerPolicy::Origin;
break;
case net::RP_Origin_When_Crossorigin:
mReferrerPolicy = ReferrerPolicy::Origin_when_cross_origin;
break;
case net::RP_Unsafe_URL:
mReferrerPolicy = ReferrerPolicy::Unsafe_url;
break;
case net::RP_Same_Origin:
mReferrerPolicy = ReferrerPolicy::Same_origin;
break;
case net::RP_Strict_Origin:
mReferrerPolicy = ReferrerPolicy::Strict_origin;
break;
case net::RP_Strict_Origin_When_Cross_Origin:
mReferrerPolicy = ReferrerPolicy::Strict_origin_when_cross_origin;
break;
default:
MOZ_ASSERT_UNREACHABLE("Invalid ReferrerPolicy value");
break;
}
}
net::ReferrerPolicy
GetReferrerPolicy()
{
switch (mReferrerPolicy) {
case ReferrerPolicy::_empty:
return net::RP_Unset;
case ReferrerPolicy::No_referrer:
return net::RP_No_Referrer;
case ReferrerPolicy::No_referrer_when_downgrade:
return net::RP_No_Referrer_When_Downgrade;
case ReferrerPolicy::Origin:
return net::RP_Origin;
case ReferrerPolicy::Origin_when_cross_origin:
return net::RP_Origin_When_Crossorigin;
case ReferrerPolicy::Unsafe_url:
return net::RP_Unsafe_URL;
case ReferrerPolicy::Strict_origin:
return net::RP_Strict_Origin;
case ReferrerPolicy::Same_origin:
return net::RP_Same_Origin;
case ReferrerPolicy::Strict_origin_when_cross_origin:
return net::RP_Strict_Origin_When_Cross_Origin;
default:
MOZ_ASSERT_UNREACHABLE("Invalid ReferrerPolicy enum value?");
break;
}
return net::RP_Unset;
}
net::ReferrerPolicy
GetEnvironmentReferrerPolicy() const
{
return mEnvironmentReferrerPolicy;
}
void
SetEnvironmentReferrerPolicy(net::ReferrerPolicy aReferrerPolicy)
{
mEnvironmentReferrerPolicy = aReferrerPolicy;
}
bool
SkipServiceWorker() const
{
return mSkipServiceWorker;
}
void
SetSkipServiceWorker()
{
mSkipServiceWorker = true;
}
bool
IsSynchronous() const
{
return mSynchronous;
}
RequestMode
Mode() const
{
return mMode;
}
void
SetMode(RequestMode aMode)
{
mMode = aMode;
}
RequestCredentials
GetCredentialsMode() const
{
return mCredentialsMode;
}
void
SetCredentialsMode(RequestCredentials aCredentialsMode)
{
mCredentialsMode = aCredentialsMode;
}
LoadTainting
GetResponseTainting() const
{
return mResponseTainting;
}
void
MaybeIncreaseResponseTainting(LoadTainting aTainting)
{
if (aTainting > mResponseTainting) {
mResponseTainting = aTainting;
}
}
RequestCache
GetCacheMode() const
{
return mCacheMode;
}
void
SetCacheMode(RequestCache aCacheMode)
{
mCacheMode = aCacheMode;
}
RequestRedirect
GetRedirectMode() const
{
return mRedirectMode;
}
void
SetRedirectMode(RequestRedirect aRedirectMode)
{
mRedirectMode = aRedirectMode;
}
const nsString&
GetIntegrity() const
{
return mIntegrity;
}
void
SetIntegrity(const nsAString& aIntegrity)
{
MOZ_ASSERT(mIntegrity.IsEmpty());
mIntegrity.Assign(aIntegrity);
}
bool
MozErrors() const
{
return mMozErrors;
}
void
SetMozErrors()
{
mMozErrors = true;
}
const nsCString&
GetFragment() const
{
return mFragment;
}
nsContentPolicyType
ContentPolicyType() const
{
return mContentPolicyType;
}
void
SetContentPolicyType(nsContentPolicyType aContentPolicyType);
void
OverrideContentPolicyType(nsContentPolicyType aContentPolicyType);
RequestDestination
Destination() const
{
return MapContentPolicyTypeToRequestDestination(mContentPolicyType);
}
bool
UnsafeRequest() const
{
return mUnsafeRequest;
}
void
SetUnsafeRequest()
{
mUnsafeRequest = true;
}
InternalHeaders*
Headers()
{
return mHeaders;
}
bool
ForceOriginHeader()
{
return mForceOriginHeader;
}
bool
SameOriginDataURL() const
{
return mSameOriginDataURL;
}
void
UnsetSameOriginDataURL()
{
mSameOriginDataURL = false;
}
void
SetBody(nsIInputStream* aStream, int64_t aBodyLength)
{
// A request's body may not be reset once set.
MOZ_ASSERT_IF(aStream, !mBodyStream);
mBodyStream = aStream;
mBodyLength = aBodyLength;
}
// Will return the original stream!
// Use a tee or copy if you don't want to erase the original.
void
GetBody(nsIInputStream** aStream, int64_t* aBodyLength = nullptr)
{
nsCOMPtr<nsIInputStream> s = mBodyStream;
s.forget(aStream);
if (aBodyLength) {
*aBodyLength = mBodyLength;
}
}
// The global is used as the client for the new object.
already_AddRefed<InternalRequest>
GetRequestConstructorCopy(nsIGlobalObject* aGlobal, ErrorResult& aRv) const;
bool
WasCreatedByFetchEvent() const
{
return mCreatedByFetchEvent;
}
void
SetCreatedByFetchEvent()
{
mCreatedByFetchEvent = true;
}
void
ClearCreatedByFetchEvent()
{
mCreatedByFetchEvent = false;
}
bool
IsNavigationRequest() const;
bool
IsWorkerRequest() const;
bool
IsClientRequest() const;
void
MaybeSkipCacheIfPerformingRevalidation();
bool
IsContentPolicyTypeOverridden() const
{
return mContentPolicyTypeOverridden;
}
static RequestMode
MapChannelToRequestMode(nsIChannel* aChannel);
static RequestCredentials
MapChannelToRequestCredentials(nsIChannel* aChannel);
// Takes ownership of the principal info.
void
SetPrincipalInfo(UniquePtr<mozilla::ipc::PrincipalInfo> aPrincipalInfo);
const UniquePtr<mozilla::ipc::PrincipalInfo>&
GetPrincipalInfo() const
{
return mPrincipalInfo;
}
const nsCString&
GetPreferredAlternativeDataType() const
{
return mPreferredAlternativeDataType;
}
void
SetPreferredAlternativeDataType(const nsACString& aDataType)
{
mPreferredAlternativeDataType = aDataType;
}
private:
// Does not copy mBodyStream. Use fallible Clone() for complete copy.
explicit InternalRequest(const InternalRequest& aOther);
~InternalRequest();
// Map the content policy type to the associated fetch destination, as defined
// by the spec at https://fetch.spec.whatwg.org/#concept-request-destination.
// Note that while the HTML spec for the "Link" element and its "as" attribute
// (https://html.spec.whatwg.org/#attr-link-as) reuse fetch's definition of
// destination, and the Link class has an internal Link::AsDestination enum type,
// the latter is only a support type to map the string values via
// Link::ParseAsValue and Link::AsValueToContentPolicy to our canonical nsContentPolicyType.
static RequestDestination
MapContentPolicyTypeToRequestDestination(nsContentPolicyType aContentPolicyType);
static bool
IsNavigationContentPolicy(nsContentPolicyType aContentPolicyType);
static bool
IsWorkerContentPolicy(nsContentPolicyType aContentPolicyType);
nsCString mMethod;
// mURLList: a list of one or more fetch URLs
nsTArray<nsCString> mURLList;
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<InternalHeaders> mHeaders;
nsCOMPtr<nsIInputStream> mBodyStream;
int64_t mBodyLength;
nsCString mPreferredAlternativeDataType;
nsContentPolicyType mContentPolicyType;
// Empty string: no-referrer
// "about:client": client (default)
// URL: an URL
nsString mReferrer;
ReferrerPolicy mReferrerPolicy;
// This will be used for request created from Window or Worker contexts
// In case there's no Referrer Policy in Request, this will be passed to
// channel.
// 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;
bool mMozErrors;
nsCString mFragment;
MOZ_INIT_OUTSIDE_CTOR bool mAuthenticationFlag;
MOZ_INIT_OUTSIDE_CTOR bool mForceOriginHeader;
MOZ_INIT_OUTSIDE_CTOR bool mPreserveContentCodings;
MOZ_INIT_OUTSIDE_CTOR bool mSameOriginDataURL;
MOZ_INIT_OUTSIDE_CTOR bool mSkipServiceWorker;
MOZ_INIT_OUTSIDE_CTOR bool mSynchronous;
MOZ_INIT_OUTSIDE_CTOR bool mUnsafeRequest;
MOZ_INIT_OUTSIDE_CTOR bool mUseURLCredentials;
// This is only set when a Request object is created by a fetch event. We
// use it to check if Service Workers are simply fetching intercepted Request
// objects without modifying them.
bool mCreatedByFetchEvent = false;
// This is only set when Request.overrideContentPolicyType() has been set.
// It is illegal to pass such a Request object to a fetch() method unless
// if the caller has chrome privileges.
bool mContentPolicyTypeOverridden = false;
UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_InternalRequest_h