123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 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 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 RequestContext and nsContentPolicyType is currently as the
- * following. Note that this mapping is not perfect yet (see the TODO comments
- * below for examples).
- *
- * RequestContext | nsContentPolicyType
- * ------------------+--------------------
- * audio | TYPE_INTERNAL_AUDIO
- * beacon | TYPE_BEACON
- * cspreport | TYPE_CSP_REPORT
- * download |
- * embed | TYPE_INTERNAL_EMBED
- * eventsource |
- * favicon |
- * fetch | TYPE_FETCH
- * font | TYPE_FONT
- * form |
- * frame | TYPE_INTERNAL_FRAME
- * hyperlink |
- * iframe | TYPE_INTERNAL_IFRAME
- * image | TYPE_INTERNAL_IMAGE, TYPE_INTERNAL_IMAGE_PRELOAD, TYPE_INTERNAL_IMAGE_FAVICON
- * imageset | TYPE_IMAGESET
- * import | Not supported by Gecko
- * internal | TYPE_DOCUMENT, TYPE_XBL, TYPE_OTHER, TYPE_SAVEAS_DOWNLOAD
- * location |
- * manifest | TYPE_WEB_MANIFEST
- * object | TYPE_INTERNAL_OBJECT
- * ping | TYPE_PING
- * plugin | TYPE_OBJECT_SUBREQUEST
- * prefetch |
- * script | TYPE_INTERNAL_SCRIPT, TYPE_INTERNAL_SCRIPT_PRELOAD
- * sharedworker | TYPE_INTERNAL_SHARED_WORKER
- * subresource | Not supported by Gecko
- * style | TYPE_INTERNAL_STYLESHEET, TYPE_INTERNAL_STYLESHEET_PRELOAD
- * track | TYPE_INTERNAL_TRACK
- * video | TYPE_INTERNAL_VIDEO
- * worker | TYPE_INTERNAL_WORKER
- * xmlhttprequest | TYPE_INTERNAL_XMLHTTPREQUEST
- * eventsource | TYPE_INTERNAL_EVENTSOURCE
- * xslt | TYPE_XSLT
- *
- * TODO: Figure out if TYPE_REFRESH maps to anything useful
- * TODO: Figure out if TYPE_DTD maps to anything useful
- * TODO: Figure out if TYPE_WEBSOCKET maps to anything useful
- * TODO: Add a content type for prefetch
- * TODO: Use the content type for manifest when it becomes available
- * TODO: Add a content type for location
- * TODO: Add a content type for hyperlink
- * TODO: Add a content type for form
- * TODO: Add a content type for favicon
- * TODO: Add a content type for download
- */
- 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.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 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;
- }
- 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);
- }
- const nsCString&
- GetFragment() const
- {
- return mFragment;
- }
- nsContentPolicyType
- ContentPolicyType() const
- {
- return mContentPolicyType;
- }
- void
- SetContentPolicyType(nsContentPolicyType aContentPolicyType);
- void
- OverrideContentPolicyType(nsContentPolicyType aContentPolicyType);
- RequestContext
- Context() const
- {
- return MapContentPolicyTypeToRequestContext(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)
- {
- // A request's body may not be reset once set.
- MOZ_ASSERT_IF(aStream, !mBodyStream);
- mBodyStream = aStream;
- }
- // Will return the original stream!
- // Use a tee or copy if you don't want to erase the original.
- void
- GetBody(nsIInputStream** aStream)
- {
- nsCOMPtr<nsIInputStream> s = mBodyStream;
- s.forget(aStream);
- }
- // 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;
- }
- private:
- // Does not copy mBodyStream. Use fallible Clone() for complete copy.
- explicit InternalRequest(const InternalRequest& aOther);
- ~InternalRequest();
- static RequestContext
- MapContentPolicyTypeToRequestContext(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;
- RefPtr<InternalHeaders> mHeaders;
- nsCOMPtr<nsIInputStream> mBodyStream;
- 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;
- 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
|