gecko-dev/dom/fetch/InternalResponse.h
Nikhil Marathe b52b66ebf5 Bug 1169044 - Patch 3 - Store and set principal with script URI on ServiceWorkers. r=ehsan
The ServiceWorkerRegistrationInfo's principal is the principal of the document
that called register(). If we create WorkerPrivate instances based off of
this, they have a valid principal in terms of security and same-origin-ness,
but the URI path is wrong. When fetching the script from the network, the
channel's principal is used to update the worker principal. We need to do the
same when the script is loaded from Cache. This patch adds support to store the
channel principal in the cache.

--HG--
extra : rebase_source : e7d527335aa4f0d4ee52e58915c8b0ef4ad26983
2015-06-04 21:39:34 -07:00

214 lines
4.7 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_InternalResponse_h
#define mozilla_dom_InternalResponse_h
#include "nsIInputStream.h"
#include "nsISupportsImpl.h"
#include "mozilla/dom/ResponseBinding.h"
#include "mozilla/dom/ChannelInfo.h"
#include "mozilla/UniquePtr.h"
namespace mozilla {
namespace ipc {
class PrincipalInfo;
}
namespace dom {
class InternalHeaders;
class InternalResponse final
{
friend class FetchDriver;
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalResponse)
InternalResponse(uint16_t aStatus, const nsACString& aStatusText);
already_AddRefed<InternalResponse> Clone();
static already_AddRefed<InternalResponse>
NetworkError()
{
nsRefPtr<InternalResponse> response = new InternalResponse(0, EmptyCString());
ErrorResult result;
response->Headers()->SetGuard(HeadersGuardEnum::Immutable, result);
MOZ_ASSERT(!result.Failed());
response->mType = ResponseType::Error;
return response.forget();
}
already_AddRefed<InternalResponse>
OpaqueResponse();
already_AddRefed<InternalResponse>
BasicResponse();
already_AddRefed<InternalResponse>
CORSResponse();
ResponseType
Type() const
{
MOZ_ASSERT_IF(mType == ResponseType::Error, !mWrappedResponse);
MOZ_ASSERT_IF(mType == ResponseType::Default, !mWrappedResponse);
MOZ_ASSERT_IF(mType == ResponseType::Basic, mWrappedResponse);
MOZ_ASSERT_IF(mType == ResponseType::Cors, mWrappedResponse);
MOZ_ASSERT_IF(mType == ResponseType::Opaque, mWrappedResponse);
return mType;
}
bool
IsError() const
{
return Type() == ResponseType::Error;
}
// FIXME(nsm): Return with exclude fragment.
void
GetUrl(nsCString& aURL) const
{
aURL.Assign(mURL);
}
void
SetUrl(const nsACString& aURL)
{
mURL.Assign(aURL);
}
uint16_t
GetStatus() const
{
return mStatus;
}
const nsCString&
GetStatusText() const
{
return mStatusText;
}
InternalHeaders*
Headers()
{
return mHeaders;
}
InternalHeaders*
UnfilteredHeaders()
{
if (mWrappedResponse) {
return mWrappedResponse->Headers();
};
return Headers();
}
void
GetInternalBody(nsIInputStream** aStream)
{
if (mWrappedResponse) {
MOZ_ASSERT(!mBody);
return mWrappedResponse->GetBody(aStream);
}
nsCOMPtr<nsIInputStream> stream = mBody;
stream.forget(aStream);
}
void
GetBody(nsIInputStream** aStream)
{
if (Type() == ResponseType::Opaque) {
*aStream = nullptr;
return;
}
return GetInternalBody(aStream);
}
void
SetBody(nsIInputStream* aBody)
{
if (mWrappedResponse) {
return mWrappedResponse->SetBody(aBody);
}
// A request's body may not be reset once set.
MOZ_ASSERT(!mBody);
mBody = aBody;
}
void
InitChannelInfo(nsIChannel* aChannel)
{
mChannelInfo.InitFromChannel(aChannel);
}
void
InitChannelInfo(const mozilla::ipc::IPCChannelInfo& aChannelInfo)
{
mChannelInfo.InitFromIPCChannelInfo(aChannelInfo);
}
void
InitChannelInfo(const ChannelInfo& aChannelInfo)
{
mChannelInfo = aChannelInfo;
}
const ChannelInfo&
GetChannelInfo() const
{
return mChannelInfo;
}
const UniquePtr<mozilla::ipc::PrincipalInfo>&
GetPrincipalInfo() const
{
return mPrincipalInfo;
}
// Takes ownership of the principal info.
void
SetPrincipalInfo(UniquePtr<mozilla::ipc::PrincipalInfo> aPrincipalInfo);
private:
~InternalResponse();
explicit InternalResponse(const InternalResponse& aOther) = delete;
InternalResponse& operator=(const InternalResponse&) = delete;
// Returns an instance of InternalResponse which is a copy of this
// InternalResponse, except headers, body and wrapped response (if any) which
// are left uninitialized. Used for cloning and filtering.
already_AddRefed<InternalResponse> CreateIncompleteCopy();
ResponseType mType;
nsCString mTerminationReason;
nsCString mURL;
const uint16_t mStatus;
const nsCString mStatusText;
nsRefPtr<InternalHeaders> mHeaders;
nsCOMPtr<nsIInputStream> mBody;
ChannelInfo mChannelInfo;
UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
// For filtered responses.
// Cache, and SW interception should always serialize/access the underlying
// unfiltered headers and when deserializing, create an InternalResponse
// with the unfiltered headers followed by wrapping it.
nsRefPtr<InternalResponse> mWrappedResponse;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_InternalResponse_h