mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-07 04:05:49 +00:00
47c59f235a
As the documentation in InternalRequest.h in this patch shows, the mapping between nsContentPolicyType and RequestContext is not complete yet. Because the InternalRequest object needs to know the actual nsContentPolicyType in order for FetchDriver to be able to use that information, we can't just store the RequestContext. Therefore, this patch adds both of these to InternalRequest. Once we get to a stage where we have a complete mapping of these values, we can store only one of them and compute the other from it. That requires addressing all of the TODO comments in the InternalRequest.h documentation.
415 lines
9.4 KiB
C++
415 lines
9.4 KiB
C++
/* -*- Mode: C++; tab-width: 2; 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 "nsIContentPolicy.h"
|
|
#include "nsIInputStream.h"
|
|
#include "nsISupportsImpl.h"
|
|
#ifdef DEBUG
|
|
#include "nsIURLParser.h"
|
|
#include "nsNetCID.h"
|
|
#include "nsServiceManagerUtils.h"
|
|
#endif
|
|
|
|
class nsIDocument;
|
|
class nsPIDOMWindow;
|
|
|
|
namespace mozilla {
|
|
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), so for now we'll have to keep both an mContext and an
|
|
* mContentPolicyType, because we cannot have a two way conversion.
|
|
*
|
|
* RequestContext | nsContentPolicyType
|
|
* ------------------+--------------------
|
|
* audio | TYPE_MEDIA
|
|
* beacon | TYPE_BEACON
|
|
* cspreport | TYPE_CSP_REPORT
|
|
* download |
|
|
* embed | TYPE_OBJECT
|
|
* eventsource |
|
|
* favicon |
|
|
* fetch | TYPE_FETCH
|
|
* font | TYPE_FONT
|
|
* form |
|
|
* frame | TYPE_SUBDOCUMENT
|
|
* hyperlink |
|
|
* iframe | TYPE_SUBDOCUMENT
|
|
* image | TYPE_IMAGE
|
|
* imageset | TYPE_IMAGESET
|
|
* import | Not supported by Gecko
|
|
* internal | TYPE_DOCUMENT, TYPE_XBL, TYPE_OTHER
|
|
* location |
|
|
* manifest |
|
|
* object | TYPE_OBJECT
|
|
* ping | TYPE_PING
|
|
* plugin | TYPE_OBJECT_SUBREQUEST
|
|
* prefetch |
|
|
* script | TYPE_SCRIPT
|
|
* serviceworker |
|
|
* sharedworker |
|
|
* subresource | Not supported by Gecko
|
|
* style | TYPE_STYLESHEET
|
|
* track | TYPE_MEDIA
|
|
* video | TYPE_MEDIA
|
|
* worker |
|
|
* xmlhttprequest | TYPE_XMLHTTPREQUEST
|
|
* xslt | TYPE_XSLT
|
|
*
|
|
* TODO: Figure out if TYPE_REFRESH maps to anything useful
|
|
* TODO: Figure out if TYPE_DTD maps to anything useful
|
|
* TODO: Split TYPE_MEDIA into TYPE_AUDIO, TYPE_VIDEO and TYPE_TRACK
|
|
* TODO: Split TYPE_XMLHTTPREQUEST and TYPE_DATAREQUEST for EventSource
|
|
* TODO: Figure out if TYPE_WEBSOCKET maps to anything useful
|
|
* TODO: Differentiate between frame and iframe
|
|
* TODO: Add content types for different kinds of workers
|
|
* 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
|
|
* TODO: Split TYPE_OBJECT into TYPE_EMBED and TYPE_OBJECT
|
|
*/
|
|
|
|
class FetchBodyStream;
|
|
class Request;
|
|
|
|
#define kFETCH_CLIENT_REFERRER_STR "about:client"
|
|
|
|
class InternalRequest final
|
|
{
|
|
friend class Request;
|
|
|
|
public:
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalRequest)
|
|
|
|
enum ResponseTainting
|
|
{
|
|
RESPONSETAINT_BASIC,
|
|
RESPONSETAINT_CORS,
|
|
RESPONSETAINT_OPAQUE,
|
|
};
|
|
|
|
explicit InternalRequest()
|
|
: mMethod("GET")
|
|
, mHeaders(new InternalHeaders(HeadersGuardEnum::None))
|
|
, mReferrer(NS_LITERAL_STRING(kFETCH_CLIENT_REFERRER_STR))
|
|
, mMode(RequestMode::No_cors)
|
|
, mCredentialsMode(RequestCredentials::Omit)
|
|
, mResponseTainting(RESPONSETAINT_BASIC)
|
|
, mCacheMode(RequestCache::Default)
|
|
, mAuthenticationFlag(false)
|
|
, mForceOriginHeader(false)
|
|
, mPreserveContentCodings(false)
|
|
// FIXME(nsm): This should be false by default, but will lead to the
|
|
// algorithm never loading data: URLs right now. See Bug 1018872 about
|
|
// how certain contexts will override it to set it to true. Fetch
|
|
// specification does not handle this yet.
|
|
, mSameOriginDataURL(true)
|
|
, mSkipServiceWorker(false)
|
|
, mSynchronous(false)
|
|
, mUnsafeRequest(false)
|
|
, mUseURLCredentials(false)
|
|
{
|
|
}
|
|
|
|
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");
|
|
}
|
|
|
|
void
|
|
GetURL(nsCString& aURL) const
|
|
{
|
|
aURL.Assign(mURL);
|
|
}
|
|
|
|
void
|
|
SetURL(const nsACString& aURL)
|
|
{
|
|
mURL.Assign(aURL);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
ResponseTainting
|
|
GetResponseTainting() const
|
|
{
|
|
return mResponseTainting;
|
|
}
|
|
|
|
void
|
|
SetResponseTainting(ResponseTainting aTainting)
|
|
{
|
|
mResponseTainting = aTainting;
|
|
}
|
|
|
|
RequestCache
|
|
GetCacheMode() const
|
|
{
|
|
return mCacheMode;
|
|
}
|
|
|
|
void
|
|
SetCacheMode(RequestCache aCacheMode)
|
|
{
|
|
mCacheMode = aCacheMode;
|
|
}
|
|
|
|
nsContentPolicyType
|
|
ContentPolicyType() const
|
|
{
|
|
return mContentPolicyType;
|
|
}
|
|
|
|
void
|
|
SetContentPolicyType(nsContentPolicyType aContentPolicyType);
|
|
|
|
RequestContext
|
|
Context() const
|
|
{
|
|
return mContext;
|
|
}
|
|
|
|
void
|
|
SetContext(RequestContext aContext)
|
|
{
|
|
mContext = aContext;
|
|
}
|
|
|
|
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(!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;
|
|
}
|
|
|
|
private:
|
|
// Does not copy mBodyStream. Use fallible Clone() for complete copy.
|
|
explicit InternalRequest(const InternalRequest& aOther);
|
|
|
|
~InternalRequest();
|
|
|
|
nsCString mMethod;
|
|
nsCString mURL;
|
|
nsRefPtr<InternalHeaders> mHeaders;
|
|
nsCOMPtr<nsIInputStream> mBodyStream;
|
|
|
|
nsContentPolicyType mContentPolicyType;
|
|
RequestContext mContext;
|
|
|
|
// Empty string: no-referrer
|
|
// "about:client": client (default)
|
|
// URL: an URL
|
|
nsString mReferrer;
|
|
|
|
RequestMode mMode;
|
|
RequestCredentials mCredentialsMode;
|
|
ResponseTainting mResponseTainting;
|
|
RequestCache mCacheMode;
|
|
|
|
bool mAuthenticationFlag;
|
|
bool mForceOriginHeader;
|
|
bool mPreserveContentCodings;
|
|
bool mSameOriginDataURL;
|
|
bool mSandboxedStorageAreaURLs;
|
|
bool mSkipServiceWorker;
|
|
bool mSynchronous;
|
|
bool mUnsafeRequest;
|
|
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;
|
|
};
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_dom_InternalRequest_h
|