Source code

Revision control

Other Tools

1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
* License, v. 2.0. If a copy of the MPL was not distributed with this
5
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "FetchEventOpProxyChild.h"
8
9
#include <utility>
10
11
#include "nsCOMPtr.h"
12
#include "nsDebug.h"
13
#include "nsThreadUtils.h"
14
15
#include "mozilla/Assertions.h"
16
#include "mozilla/RefPtr.h"
17
#include "mozilla/UniquePtr.h"
18
#include "mozilla/Unused.h"
19
#include "mozilla/dom/RemoteWorkerChild.h"
20
#include "mozilla/dom/RemoteWorkerService.h"
21
#include "mozilla/dom/ServiceWorkerOp.h"
22
#include "mozilla/dom/WorkerCommon.h"
23
#include "mozilla/ipc/BackgroundChild.h"
24
#include "mozilla/ipc/IPCStreamUtils.h"
25
26
namespace mozilla {
27
28
using namespace ipc;
29
30
namespace dom {
31
32
namespace {
33
34
nsresult GetIPCSynthesizeResponseArgs(
35
IPCSynthesizeResponseArgs* aIPCArgs, SynthesizeResponseArgs&& aArgs,
36
UniquePtr<AutoIPCStream>& aAutoBodyStream,
37
UniquePtr<AutoIPCStream>& aAutoAlternativeBodyStream) {
38
MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
39
40
PBackgroundChild* bgChild = BackgroundChild::GetOrCreateForCurrentThread();
41
42
if (NS_WARN_IF(!bgChild)) {
43
return NS_ERROR_DOM_INVALID_STATE_ERR;
44
}
45
46
aArgs.first()->ToIPC(&aIPCArgs->internalResponse(), bgChild, aAutoBodyStream,
47
aAutoAlternativeBodyStream);
48
aIPCArgs->closure() = std::move(aArgs.second());
49
50
return NS_OK;
51
}
52
53
} // anonymous namespace
54
55
void FetchEventOpProxyChild::Initialize(
56
const ServiceWorkerFetchEventOpArgs& aArgs) {
57
MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
58
MOZ_ASSERT(!mOp);
59
60
mInternalRequest = new InternalRequest(aArgs.internalRequest());
61
62
RemoteWorkerChild* manager = static_cast<RemoteWorkerChild*>(Manager());
63
MOZ_ASSERT(manager);
64
65
RefPtr<FetchEventOpProxyChild> self = this;
66
67
auto callback = [self](const ServiceWorkerOpResult& aResult) {
68
if (!self->CanSend()) {
69
return;
70
}
71
72
if (NS_WARN_IF(aResult.type() == ServiceWorkerOpResult::Tnsresult)) {
73
Unused << self->Send__delete__(self, aResult.get_nsresult());
74
return;
75
}
76
77
MOZ_ASSERT(aResult.type() ==
78
ServiceWorkerOpResult::TServiceWorkerFetchEventOpResult);
79
80
Unused << self->Send__delete__(self, aResult);
81
};
82
83
RefPtr<FetchEventOp> op = ServiceWorkerOp::Create(aArgs, std::move(callback))
84
.template downcast<FetchEventOp>();
85
86
MOZ_ASSERT(op);
87
88
op->SetActor(this);
89
mOp = op;
90
91
op->GetRespondWithPromise()
92
->Then(GetCurrentThreadSerialEventTarget(), __func__,
93
[self = std::move(self)](
94
FetchEventRespondWithPromise::ResolveOrRejectValue&& aResult) {
95
self->mRespondWithPromiseRequestHolder.Complete();
96
97
if (NS_WARN_IF(aResult.IsReject())) {
98
MOZ_ASSERT(NS_FAILED(aResult.RejectValue()));
99
100
Unused << self->SendRespondWith(
101
CancelInterceptionArgs(aResult.RejectValue()));
102
return;
103
}
104
105
auto& result = aResult.ResolveValue();
106
107
if (result.is<SynthesizeResponseArgs>()) {
108
IPCSynthesizeResponseArgs ipcArgs;
109
UniquePtr<AutoIPCStream> autoBodyStream =
110
MakeUnique<AutoIPCStream>();
111
UniquePtr<AutoIPCStream> autoAlternativeBodyStream =
112
MakeUnique<AutoIPCStream>();
113
nsresult rv = GetIPCSynthesizeResponseArgs(
114
&ipcArgs, result.extract<SynthesizeResponseArgs>(),
115
autoBodyStream, autoAlternativeBodyStream);
116
117
if (NS_WARN_IF(NS_FAILED(rv))) {
118
Unused << self->SendRespondWith(CancelInterceptionArgs(rv));
119
return;
120
}
121
122
Unused << self->SendRespondWith(ipcArgs);
123
autoBodyStream->TakeOptionalValue();
124
autoAlternativeBodyStream->TakeOptionalValue();
125
} else if (result.is<ResetInterceptionArgs>()) {
126
Unused << self->SendRespondWith(
127
result.extract<ResetInterceptionArgs>());
128
} else {
129
Unused << self->SendRespondWith(
130
result.extract<CancelInterceptionArgs>());
131
}
132
})
133
->Track(mRespondWithPromiseRequestHolder);
134
135
manager->MaybeStartOp(std::move(op));
136
}
137
138
RefPtr<InternalRequest> FetchEventOpProxyChild::ExtractInternalRequest() {
139
MOZ_ASSERT(IsCurrentThreadRunningWorker());
140
MOZ_ASSERT(mInternalRequest);
141
142
return RefPtr<InternalRequest>(std::move(mInternalRequest));
143
}
144
145
void FetchEventOpProxyChild::ActorDestroy(ActorDestroyReason) {
146
Unused << NS_WARN_IF(mRespondWithPromiseRequestHolder.Exists());
147
mRespondWithPromiseRequestHolder.DisconnectIfExists();
148
149
mOp->RevokeActor(this);
150
mOp = nullptr;
151
}
152
153
} // namespace dom
154
} // namespace mozilla