mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
34074a23ec
- missing of Bug 1130096 - Convert embedding/components/windowwatcher/ to Gecko style (883cc280e) - Bug 1114299 - Pass window features up from the content process via nsCString. r=smaug (017de6dc8) - Bug 1114299 - Be more strict about which window chromeFlags we compute from content. r=smaug (71e9f4959) - Bug 1159034 - Only fake no-alpha for the backbuffer. - r=kamidphish (2bc4bcf14) - Bug 1184786 - Fix LastColorAttachment(). r=jgilber (b320f23de) - Bug 1184786 - Fix ReadBuffer parameter validation. r=jgilber (7c6fac544) - Bug 1151736 - More information to pick up with crash reports. r=jgilbert (cd26cb6cb) - Bug 1151736 - Lose context on OOM instead of crashing. r=jgilbert (904e2d98a) - Bug 1176153. Have binding code grab the array buffer view type for ArrayBufferView arguments, so consumers don't have to manually use JSAPI to do it. Use the new setup in WebGL code. r=smau (3a93669ee) - Bug 1182347 - Implement OriginAttributesPattern. r=sicking,f=allstars.chh (10eb6487c) - Bug 922212 - Add console.dirxml. r=bgrins, r=mrbkap (85ebd7e39) - Bug 1176341 - De-holder nsIXPConnect::CreateSandbox. r=baku,gabor (d27b571d5) - Bug 1156005 - Mark the nsIAtom members of NodeInfo::NodeInfoInner as MOZ_NON_OWNING_REF; r=baku (3c17318c4) - Bug 1156006 - Mark NodeInfo::mDocument as MOZ_NON_OWNING_REF; r=baku (67ad08801) - Bug 1169129 - Make DOMException::Create(nsresult, nsCString) accept nsACString. r=bholley (22e2f4e5e) - Bug 1156099 - Mark the atom members of NodeInfo as nsCOMPtr's; r=baku (83dca3dde) - Bug 1176757 - Throw a DataCloneError when attempting to invoke 'cloneNode' on a 'ShadowRoot' and associated mochitest. r=wchen (decac1493) - Bug 1169044 - Patch 6 - Update web-platform-tests expected data. r=jgraham (def441a11) - Bug 1169044 - Patch 7 - Set mObserver in URLSearchParams. a=bustage. (80bd7a589) - Bug 1181259 Remove stray debugging printf from Cache API. r=froydnj (8b030de0a) - Bug 1173439 P1 Store URLs as UTF8 strings in Cache instead of UTF16. r=ehsan (ad3120be5) - Bug 1180765 - Bump the caches.sqlite version numbers because of the field that was added in bug 1169044; r=jdm (c40b57eab) - Bug 1173439 P2 Parse Response URL query as a separate field. r=ehsan (3b5c9641b) - Bug 1173439 P3 Use url query field for database matching and Request creation. r=ehsan (18969bd6c) - Bug 1173439 P4 Remove Request url field from Cache API database. r=ehsan (00e45614d) - Bug 1173439 P5 Cache should index on a hash instead of the url itself. r=ehsan (eafb8d1a1) - Bug 1177916 - URLSearchParams::GetParentObject should not return nullptr, r=smaug (c44513ab6) - Bug 1177916 - URL should be a nsWrapperCache object, r=smaug (67c3f7221) - Bug 1121773 - Conditionally include SiteSpecificUserAgent files on mobile/android. (37db816f1)
569 lines
16 KiB
C++
569 lines
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/. */
|
|
|
|
#include "mozilla/dom/cache/TypeUtils.h"
|
|
|
|
#include "mozilla/unused.h"
|
|
#include "mozilla/dom/CacheBinding.h"
|
|
#include "mozilla/dom/InternalRequest.h"
|
|
#include "mozilla/dom/Request.h"
|
|
#include "mozilla/dom/Response.h"
|
|
#include "mozilla/dom/cache/CachePushStreamChild.h"
|
|
#include "mozilla/dom/cache/CacheTypes.h"
|
|
#include "mozilla/dom/cache/ReadStream.h"
|
|
#include "mozilla/ipc/BackgroundChild.h"
|
|
#include "mozilla/ipc/PBackgroundChild.h"
|
|
#include "mozilla/ipc/PFileDescriptorSetChild.h"
|
|
#include "mozilla/ipc/InputStreamUtils.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsIAsyncInputStream.h"
|
|
#include "nsIAsyncOutputStream.h"
|
|
#include "nsIIPCSerializableInputStream.h"
|
|
#include "nsQueryObject.h"
|
|
#include "nsPromiseFlatString.h"
|
|
#include "nsStreamUtils.h"
|
|
#include "nsString.h"
|
|
#include "nsURLParsers.h"
|
|
#include "nsCRT.h"
|
|
#include "nsHttp.h"
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
namespace cache {
|
|
|
|
using mozilla::ipc::BackgroundChild;
|
|
using mozilla::ipc::FileDescriptor;
|
|
using mozilla::ipc::PBackgroundChild;
|
|
using mozilla::ipc::PFileDescriptorSetChild;
|
|
|
|
namespace {
|
|
|
|
static bool
|
|
HasVaryStar(mozilla::dom::InternalHeaders* aHeaders)
|
|
{
|
|
nsAutoTArray<nsCString, 16> varyHeaders;
|
|
ErrorResult rv;
|
|
aHeaders->GetAll(NS_LITERAL_CSTRING("vary"), varyHeaders, rv);
|
|
MOZ_ALWAYS_TRUE(!rv.Failed());
|
|
|
|
for (uint32_t i = 0; i < varyHeaders.Length(); ++i) {
|
|
nsAutoCString varyValue(varyHeaders[i]);
|
|
char* rawBuffer = varyValue.BeginWriting();
|
|
char* token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer);
|
|
for (; token;
|
|
token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer)) {
|
|
nsDependentCString header(token);
|
|
if (header.EqualsLiteral("*")) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void
|
|
SerializeNormalStream(nsIInputStream* aStream, CacheReadStream& aReadStreamOut)
|
|
{
|
|
nsAutoTArray<FileDescriptor, 4> fds;
|
|
SerializeInputStream(aStream, aReadStreamOut.params(), fds);
|
|
|
|
PFileDescriptorSetChild* fdSet = nullptr;
|
|
if (!fds.IsEmpty()) {
|
|
// We should not be serializing until we have an actor ready
|
|
PBackgroundChild* manager = BackgroundChild::GetForCurrentThread();
|
|
MOZ_ASSERT(manager);
|
|
|
|
fdSet = manager->SendPFileDescriptorSetConstructor(fds[0]);
|
|
for (uint32_t i = 1; i < fds.Length(); ++i) {
|
|
unused << fdSet->SendAddFileDescriptor(fds[i]);
|
|
}
|
|
}
|
|
|
|
if (fdSet) {
|
|
aReadStreamOut.fds() = fdSet;
|
|
} else {
|
|
aReadStreamOut.fds() = void_t();
|
|
}
|
|
}
|
|
|
|
void
|
|
ToHeadersEntryList(nsTArray<HeadersEntry>& aOut, InternalHeaders* aHeaders)
|
|
{
|
|
MOZ_ASSERT(aHeaders);
|
|
|
|
nsAutoTArray<InternalHeaders::Entry, 16> entryList;
|
|
aHeaders->GetEntries(entryList);
|
|
|
|
for (uint32_t i = 0; i < entryList.Length(); ++i) {
|
|
InternalHeaders::Entry& entry = entryList[i];
|
|
aOut.AppendElement(HeadersEntry(entry.mName, entry.mValue));
|
|
}
|
|
}
|
|
|
|
} // namespace
|
|
|
|
already_AddRefed<InternalRequest>
|
|
TypeUtils::ToInternalRequest(const RequestOrUSVString& aIn,
|
|
BodyAction aBodyAction, ErrorResult& aRv)
|
|
{
|
|
if (aIn.IsRequest()) {
|
|
Request& request = aIn.GetAsRequest();
|
|
|
|
// Check and set bodyUsed flag immediately because its on Request
|
|
// instead of InternalRequest.
|
|
CheckAndSetBodyUsed(&request, aBodyAction, aRv);
|
|
if (aRv.Failed()) { return nullptr; }
|
|
|
|
return request.GetInternalRequest();
|
|
}
|
|
|
|
return ToInternalRequest(aIn.GetAsUSVString(), aRv);
|
|
}
|
|
|
|
already_AddRefed<InternalRequest>
|
|
TypeUtils::ToInternalRequest(const OwningRequestOrUSVString& aIn,
|
|
BodyAction aBodyAction, ErrorResult& aRv)
|
|
{
|
|
|
|
if (aIn.IsRequest()) {
|
|
nsRefPtr<Request> request = aIn.GetAsRequest().get();
|
|
|
|
// Check and set bodyUsed flag immediately because its on Request
|
|
// instead of InternalRequest.
|
|
CheckAndSetBodyUsed(request, aBodyAction, aRv);
|
|
if (aRv.Failed()) { return nullptr; }
|
|
|
|
return request->GetInternalRequest();
|
|
}
|
|
|
|
return ToInternalRequest(aIn.GetAsUSVString(), aRv);
|
|
}
|
|
|
|
void
|
|
TypeUtils::ToCacheRequest(CacheRequest& aOut, InternalRequest* aIn,
|
|
BodyAction aBodyAction, SchemeAction aSchemeAction,
|
|
ErrorResult& aRv)
|
|
{
|
|
MOZ_ASSERT(aIn);
|
|
|
|
aIn->GetMethod(aOut.method());
|
|
|
|
nsAutoCString url;
|
|
aIn->GetURL(url);
|
|
|
|
bool schemeValid;
|
|
ProcessURL(url, &schemeValid, &aOut.urlWithoutQuery(), &aOut.urlQuery(), aRv);
|
|
if (aRv.Failed()) {
|
|
return;
|
|
}
|
|
|
|
if (!schemeValid) {
|
|
if (aSchemeAction == TypeErrorOnInvalidScheme) {
|
|
NS_NAMED_LITERAL_STRING(label, "Request");
|
|
NS_ConvertUTF8toUTF16 urlUTF16(url);
|
|
aRv.ThrowTypeError(MSG_INVALID_URL_SCHEME, &label, &urlUTF16);
|
|
return;
|
|
}
|
|
}
|
|
|
|
aIn->GetReferrer(aOut.referrer());
|
|
|
|
nsRefPtr<InternalHeaders> headers = aIn->Headers();
|
|
MOZ_ASSERT(headers);
|
|
ToHeadersEntryList(aOut.headers(), headers);
|
|
aOut.headersGuard() = headers->Guard();
|
|
aOut.mode() = aIn->Mode();
|
|
aOut.credentials() = aIn->GetCredentialsMode();
|
|
aOut.contentPolicyType() = aIn->ContentPolicyType();
|
|
aOut.requestCache() = aIn->GetCacheMode();
|
|
|
|
if (aBodyAction == IgnoreBody) {
|
|
aOut.body() = void_t();
|
|
return;
|
|
}
|
|
|
|
// BodyUsed flag is checked and set previously in ToInternalRequest()
|
|
|
|
nsCOMPtr<nsIInputStream> stream;
|
|
aIn->GetBody(getter_AddRefs(stream));
|
|
SerializeCacheStream(stream, &aOut.body(), aRv);
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
void
|
|
TypeUtils::ToCacheResponseWithoutBody(CacheResponse& aOut,
|
|
InternalResponse& aIn, ErrorResult& aRv)
|
|
{
|
|
aOut.type() = aIn.Type();
|
|
|
|
aIn.GetUrl(aOut.url());
|
|
|
|
if (aOut.url() != EmptyCString()) {
|
|
// Pass all Response URL schemes through... The spec only requires we take
|
|
// action on invalid schemes for Request objects.
|
|
ProcessURL(aOut.url(), nullptr, nullptr, nullptr, aRv);
|
|
if (aRv.Failed()) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
aOut.status() = aIn.GetStatus();
|
|
aOut.statusText() = aIn.GetStatusText();
|
|
nsRefPtr<InternalHeaders> headers = aIn.UnfilteredHeaders();
|
|
MOZ_ASSERT(headers);
|
|
if (HasVaryStar(headers)) {
|
|
aRv.ThrowTypeError(MSG_RESPONSE_HAS_VARY_STAR);
|
|
return;
|
|
}
|
|
ToHeadersEntryList(aOut.headers(), headers);
|
|
aOut.headersGuard() = headers->Guard();
|
|
aOut.channelInfo() = aIn.GetChannelInfo().AsIPCChannelInfo();
|
|
if (aIn.GetPrincipalInfo()) {
|
|
aOut.principalInfo() = *aIn.GetPrincipalInfo();
|
|
} else {
|
|
aOut.principalInfo() = void_t();
|
|
}
|
|
}
|
|
|
|
void
|
|
TypeUtils::ToCacheResponse(CacheResponse& aOut, Response& aIn, ErrorResult& aRv)
|
|
{
|
|
if (aIn.BodyUsed()) {
|
|
aRv.ThrowTypeError(MSG_FETCH_BODY_CONSUMED_ERROR);
|
|
return;
|
|
}
|
|
|
|
nsRefPtr<InternalResponse> ir = aIn.GetInternalResponse();
|
|
ToCacheResponseWithoutBody(aOut, *ir, aRv);
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return;
|
|
}
|
|
|
|
nsCOMPtr<nsIInputStream> stream;
|
|
ir->GetInternalBody(getter_AddRefs(stream));
|
|
if (stream) {
|
|
aIn.SetBodyUsed();
|
|
}
|
|
|
|
SerializeCacheStream(stream, &aOut.body(), aRv);
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// static
|
|
void
|
|
TypeUtils::ToCacheQueryParams(CacheQueryParams& aOut,
|
|
const CacheQueryOptions& aIn)
|
|
{
|
|
aOut.ignoreSearch() = aIn.mIgnoreSearch;
|
|
aOut.ignoreMethod() = aIn.mIgnoreMethod;
|
|
aOut.ignoreVary() = aIn.mIgnoreVary;
|
|
aOut.cacheNameSet() = aIn.mCacheName.WasPassed();
|
|
if (aOut.cacheNameSet()) {
|
|
aOut.cacheName() = aIn.mCacheName.Value();
|
|
} else {
|
|
aOut.cacheName() = NS_LITERAL_STRING("");
|
|
}
|
|
}
|
|
|
|
already_AddRefed<Response>
|
|
TypeUtils::ToResponse(const CacheResponse& aIn)
|
|
{
|
|
if (aIn.type() == ResponseType::Error) {
|
|
nsRefPtr<InternalResponse> error = InternalResponse::NetworkError();
|
|
nsRefPtr<Response> r = new Response(GetGlobalObject(), error);
|
|
return r.forget();
|
|
}
|
|
|
|
nsRefPtr<InternalResponse> ir = new InternalResponse(aIn.status(),
|
|
aIn.statusText());
|
|
ir->SetUrl(aIn.url());
|
|
|
|
nsRefPtr<InternalHeaders> internalHeaders =
|
|
ToInternalHeaders(aIn.headers(), aIn.headersGuard());
|
|
ErrorResult result;
|
|
ir->Headers()->SetGuard(aIn.headersGuard(), result);
|
|
MOZ_ASSERT(!result.Failed());
|
|
ir->Headers()->Fill(*internalHeaders, result);
|
|
MOZ_ASSERT(!result.Failed());
|
|
|
|
ir->InitChannelInfo(aIn.channelInfo());
|
|
if (aIn.principalInfo().type() == mozilla::ipc::OptionalPrincipalInfo::TPrincipalInfo) {
|
|
UniquePtr<mozilla::ipc::PrincipalInfo> info(new mozilla::ipc::PrincipalInfo(aIn.principalInfo().get_PrincipalInfo()));
|
|
ir->SetPrincipalInfo(Move(info));
|
|
}
|
|
|
|
nsCOMPtr<nsIInputStream> stream = ReadStream::Create(aIn.body());
|
|
ir->SetBody(stream);
|
|
|
|
switch (aIn.type())
|
|
{
|
|
case ResponseType::Default:
|
|
break;
|
|
case ResponseType::Opaque:
|
|
ir = ir->OpaqueResponse();
|
|
break;
|
|
case ResponseType::Basic:
|
|
ir = ir->BasicResponse();
|
|
break;
|
|
case ResponseType::Cors:
|
|
ir = ir->CORSResponse();
|
|
break;
|
|
default:
|
|
MOZ_CRASH("Unexpected ResponseType!");
|
|
}
|
|
MOZ_ASSERT(ir);
|
|
|
|
nsRefPtr<Response> ref = new Response(GetGlobalObject(), ir);
|
|
return ref.forget();
|
|
}
|
|
|
|
already_AddRefed<InternalRequest>
|
|
TypeUtils::ToInternalRequest(const CacheRequest& aIn)
|
|
{
|
|
nsRefPtr<InternalRequest> internalRequest = new InternalRequest();
|
|
|
|
internalRequest->SetMethod(aIn.method());
|
|
|
|
nsAutoCString url(aIn.urlWithoutQuery());
|
|
url.Append(aIn.urlQuery());
|
|
internalRequest->SetURL(url);
|
|
|
|
internalRequest->SetReferrer(aIn.referrer());
|
|
internalRequest->SetMode(aIn.mode());
|
|
internalRequest->SetCredentialsMode(aIn.credentials());
|
|
internalRequest->SetContentPolicyType(aIn.contentPolicyType());
|
|
internalRequest->SetCacheMode(aIn.requestCache());
|
|
|
|
nsRefPtr<InternalHeaders> internalHeaders =
|
|
ToInternalHeaders(aIn.headers(), aIn.headersGuard());
|
|
ErrorResult result;
|
|
internalRequest->Headers()->SetGuard(aIn.headersGuard(), result);
|
|
MOZ_ASSERT(!result.Failed());
|
|
internalRequest->Headers()->Fill(*internalHeaders, result);
|
|
MOZ_ASSERT(!result.Failed());
|
|
|
|
nsCOMPtr<nsIInputStream> stream = ReadStream::Create(aIn.body());
|
|
|
|
internalRequest->SetBody(stream);
|
|
|
|
return internalRequest.forget();
|
|
}
|
|
|
|
already_AddRefed<Request>
|
|
TypeUtils::ToRequest(const CacheRequest& aIn)
|
|
{
|
|
nsRefPtr<InternalRequest> internalRequest = ToInternalRequest(aIn);
|
|
nsRefPtr<Request> request = new Request(GetGlobalObject(), internalRequest);
|
|
return request.forget();
|
|
}
|
|
|
|
// static
|
|
already_AddRefed<InternalHeaders>
|
|
TypeUtils::ToInternalHeaders(const nsTArray<HeadersEntry>& aHeadersEntryList,
|
|
HeadersGuardEnum aGuard)
|
|
{
|
|
nsTArray<InternalHeaders::Entry> entryList(aHeadersEntryList.Length());
|
|
|
|
for (uint32_t i = 0; i < aHeadersEntryList.Length(); ++i) {
|
|
const HeadersEntry& headersEntry = aHeadersEntryList[i];
|
|
entryList.AppendElement(InternalHeaders::Entry(headersEntry.name(),
|
|
headersEntry.value()));
|
|
}
|
|
|
|
nsRefPtr<InternalHeaders> ref = new InternalHeaders(Move(entryList), aGuard);
|
|
return ref.forget();
|
|
}
|
|
|
|
// Utility function to remove the fragment from a URL, check its scheme, and optionally
|
|
// provide a URL without the query. We're not using nsIURL or URL to do this because
|
|
// they require going to the main thread.
|
|
// static
|
|
void
|
|
TypeUtils::ProcessURL(nsACString& aUrl, bool* aSchemeValidOut,
|
|
nsACString* aUrlWithoutQueryOut,nsACString* aUrlQueryOut,
|
|
ErrorResult& aRv)
|
|
{
|
|
const nsAFlatCString& flatURL = PromiseFlatCString(aUrl);
|
|
const char* url = flatURL.get();
|
|
|
|
// off the main thread URL parsing using nsStdURLParser.
|
|
nsCOMPtr<nsIURLParser> urlParser = new nsStdURLParser();
|
|
|
|
uint32_t pathPos;
|
|
int32_t pathLen;
|
|
uint32_t schemePos;
|
|
int32_t schemeLen;
|
|
aRv = urlParser->ParseURL(url, flatURL.Length(), &schemePos, &schemeLen,
|
|
nullptr, nullptr, // ignore authority
|
|
&pathPos, &pathLen);
|
|
if (NS_WARN_IF(aRv.Failed())) { return; }
|
|
|
|
if (aSchemeValidOut) {
|
|
nsAutoCString scheme(Substring(flatURL, schemePos, schemeLen));
|
|
*aSchemeValidOut = scheme.LowerCaseEqualsLiteral("http") ||
|
|
scheme.LowerCaseEqualsLiteral("https");
|
|
}
|
|
|
|
uint32_t queryPos;
|
|
int32_t queryLen;
|
|
uint32_t refPos;
|
|
int32_t refLen;
|
|
|
|
aRv = urlParser->ParsePath(url + pathPos, flatURL.Length() - pathPos,
|
|
nullptr, nullptr, // ignore filepath
|
|
&queryPos, &queryLen,
|
|
&refPos, &refLen);
|
|
if (NS_WARN_IF(aRv.Failed())) {
|
|
return;
|
|
}
|
|
|
|
// TODO: Remove this once Request/Response properly strip the fragment (bug 1110476)
|
|
if (refLen >= 0) {
|
|
// ParsePath gives us ref position relative to the start of the path
|
|
refPos += pathPos;
|
|
|
|
aUrl = Substring(aUrl, 0, refPos - 1);
|
|
}
|
|
|
|
if (!aUrlWithoutQueryOut) {
|
|
return;
|
|
}
|
|
|
|
MOZ_ASSERT(aUrlQueryOut);
|
|
|
|
if (queryLen < 0) {
|
|
*aUrlWithoutQueryOut = aUrl;
|
|
*aUrlQueryOut = EmptyCString();
|
|
return;
|
|
}
|
|
|
|
// ParsePath gives us query position relative to the start of the path
|
|
queryPos += pathPos;
|
|
|
|
*aUrlWithoutQueryOut = Substring(aUrl, 0, queryPos - 1);
|
|
*aUrlQueryOut = Substring(aUrl, queryPos - 1, queryLen + 1);
|
|
}
|
|
|
|
void
|
|
TypeUtils::CheckAndSetBodyUsed(Request* aRequest, BodyAction aBodyAction,
|
|
ErrorResult& aRv)
|
|
{
|
|
MOZ_ASSERT(aRequest);
|
|
|
|
if (aBodyAction == IgnoreBody) {
|
|
return;
|
|
}
|
|
|
|
if (aRequest->BodyUsed()) {
|
|
aRv.ThrowTypeError(MSG_FETCH_BODY_CONSUMED_ERROR);
|
|
return;
|
|
}
|
|
|
|
nsCOMPtr<nsIInputStream> stream;
|
|
aRequest->GetBody(getter_AddRefs(stream));
|
|
if (stream) {
|
|
aRequest->SetBodyUsed();
|
|
}
|
|
}
|
|
|
|
already_AddRefed<InternalRequest>
|
|
TypeUtils::ToInternalRequest(const nsAString& aIn, ErrorResult& aRv)
|
|
{
|
|
RequestOrUSVString requestOrString;
|
|
requestOrString.SetAsUSVString().Rebind(aIn.Data(), aIn.Length());
|
|
|
|
// Re-create a GlobalObject stack object so we can use webidl Constructors.
|
|
AutoJSAPI jsapi;
|
|
if (NS_WARN_IF(!jsapi.Init(GetGlobalObject()))) {
|
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
return nullptr;
|
|
}
|
|
JSContext* cx = jsapi.cx();
|
|
GlobalObject global(cx, GetGlobalObject()->GetGlobalJSObject());
|
|
MOZ_ASSERT(!global.Failed());
|
|
|
|
nsRefPtr<Request> request = Request::Constructor(global, requestOrString,
|
|
RequestInit(), aRv);
|
|
if (NS_WARN_IF(aRv.Failed())) { return nullptr; }
|
|
|
|
return request->GetInternalRequest();
|
|
}
|
|
|
|
void
|
|
TypeUtils::SerializeCacheStream(nsIInputStream* aStream,
|
|
CacheReadStreamOrVoid* aStreamOut,
|
|
ErrorResult& aRv)
|
|
{
|
|
*aStreamOut = void_t();
|
|
if (!aStream) {
|
|
return;
|
|
}
|
|
|
|
// Option 1: Send a cache-specific ReadStream if we can.
|
|
nsRefPtr<ReadStream> controlled = do_QueryObject(aStream);
|
|
if (controlled) {
|
|
controlled->Serialize(aStreamOut);
|
|
return;
|
|
}
|
|
|
|
CacheReadStream readStream;
|
|
readStream.controlChild() = nullptr;
|
|
readStream.controlParent() = nullptr;
|
|
readStream.pushStreamChild() = nullptr;
|
|
readStream.pushStreamParent() = nullptr;
|
|
|
|
// Option 2: Do normal stream serialization if its supported.
|
|
nsCOMPtr<nsIIPCSerializableInputStream> serial = do_QueryInterface(aStream);
|
|
if (serial) {
|
|
SerializeNormalStream(aStream, readStream);
|
|
|
|
// Option 3: As a last resort push data across manually. Should only be
|
|
// needed for nsPipe input stream. Only works for async,
|
|
// non-blocking streams.
|
|
} else {
|
|
SerializePushStream(aStream, readStream, aRv);
|
|
if (NS_WARN_IF(aRv.Failed())) { return; }
|
|
}
|
|
|
|
*aStreamOut = readStream;
|
|
}
|
|
|
|
void
|
|
TypeUtils::SerializePushStream(nsIInputStream* aStream,
|
|
CacheReadStream& aReadStreamOut,
|
|
ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(aStream);
|
|
if (NS_WARN_IF(!asyncStream)) {
|
|
aRv = NS_ERROR_FAILURE;
|
|
return;
|
|
}
|
|
|
|
bool nonBlocking = false;
|
|
aRv = asyncStream->IsNonBlocking(&nonBlocking);
|
|
if (NS_WARN_IF(aRv.Failed())) { return; }
|
|
if (NS_WARN_IF(!nonBlocking)) {
|
|
aRv = NS_ERROR_FAILURE;
|
|
return;
|
|
}
|
|
|
|
aReadStreamOut.pushStreamChild() = CreatePushStream(asyncStream);
|
|
MOZ_ASSERT(aReadStreamOut.pushStreamChild());
|
|
aReadStreamOut.params() = void_t();
|
|
aReadStreamOut.fds() = void_t();
|
|
|
|
// CachePushStreamChild::Start() must be called after sending the stream
|
|
// across to the parent side.
|
|
}
|
|
|
|
} // namespace cache
|
|
} // namespace dom
|
|
} // namespace mozilla
|