netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp

branch
TOR_BUG_9701
changeset 14
925c144e1f1f
equal deleted inserted replaced
-1:000000000000 0:5f9acaf7237f
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 #include "nsWyciwyg.h"
6
7 #include "mozilla/net/WyciwygChannelParent.h"
8 #include "nsWyciwygChannel.h"
9 #include "nsNetUtil.h"
10 #include "nsCharsetSource.h"
11 #include "nsISerializable.h"
12 #include "nsSerializationHelper.h"
13 #include "mozilla/ipc/URIUtils.h"
14 #include "mozilla/net/NeckoParent.h"
15 #include "SerializedLoadContext.h"
16
17 using namespace mozilla::ipc;
18
19 namespace mozilla {
20 namespace net {
21
22 WyciwygChannelParent::WyciwygChannelParent()
23 : mIPCClosed(false)
24 , mReceivedAppData(false)
25 {
26 #if defined(PR_LOGGING)
27 if (!gWyciwygLog)
28 gWyciwygLog = PR_NewLogModule("nsWyciwygChannel");
29 #endif
30 }
31
32 WyciwygChannelParent::~WyciwygChannelParent()
33 {
34 }
35
36 void
37 WyciwygChannelParent::ActorDestroy(ActorDestroyReason why)
38 {
39 // We may still have refcount>0 if the channel hasn't called OnStopRequest
40 // yet, but we must not send any more msgs to child.
41 mIPCClosed = true;
42
43 // We need to force the cycle to break here
44 mChannel->SetNotificationCallbacks(nullptr);
45 }
46
47 //-----------------------------------------------------------------------------
48 // WyciwygChannelParent::nsISupports
49 //-----------------------------------------------------------------------------
50
51 NS_IMPL_ISUPPORTS(WyciwygChannelParent,
52 nsIStreamListener,
53 nsIInterfaceRequestor,
54 nsIRequestObserver)
55
56 //-----------------------------------------------------------------------------
57 // WyciwygChannelParent::PWyciwygChannelParent
58 //-----------------------------------------------------------------------------
59
60 bool
61 WyciwygChannelParent::RecvInit(const URIParams& aURI)
62 {
63 nsresult rv;
64
65 nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
66 if (!uri)
67 return false;
68
69 nsCString uriSpec;
70 uri->GetSpec(uriSpec);
71 LOG(("WyciwygChannelParent RecvInit [this=%p uri=%s]\n",
72 this, uriSpec.get()));
73
74 nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
75 if (NS_FAILED(rv))
76 return SendCancelEarly(rv);
77
78 nsCOMPtr<nsIChannel> chan;
79 rv = NS_NewChannel(getter_AddRefs(chan), uri, ios);
80 if (NS_FAILED(rv))
81 return SendCancelEarly(rv);
82
83 mChannel = do_QueryInterface(chan, &rv);
84 if (NS_FAILED(rv))
85 return SendCancelEarly(rv);
86
87 return true;
88 }
89
90 bool
91 WyciwygChannelParent::RecvAppData(const IPC::SerializedLoadContext& loadContext,
92 PBrowserParent* parent)
93 {
94 LOG(("WyciwygChannelParent RecvAppData [this=%p]\n", this));
95
96 if (!SetupAppData(loadContext, parent))
97 return false;
98
99 mChannel->SetNotificationCallbacks(this);
100 return true;
101 }
102
103 bool
104 WyciwygChannelParent::SetupAppData(const IPC::SerializedLoadContext& loadContext,
105 PBrowserParent* aParent)
106 {
107 if (!mChannel)
108 return true;
109
110 const char* error = NeckoParent::CreateChannelLoadContext(aParent,
111 Manager()->Manager(),
112 loadContext,
113 mLoadContext);
114 if (error) {
115 printf_stderr("WyciwygChannelParent::SetupAppData: FATAL ERROR: %s\n",
116 error);
117 return false;
118 }
119
120 if (!mLoadContext && loadContext.IsPrivateBitValid()) {
121 nsCOMPtr<nsIPrivateBrowsingChannel> pbChannel = do_QueryInterface(mChannel);
122 if (pbChannel)
123 pbChannel->SetPrivate(loadContext.mUsePrivateBrowsing);
124 }
125
126 mReceivedAppData = true;
127 return true;
128 }
129
130 bool
131 WyciwygChannelParent::RecvAsyncOpen(const URIParams& aOriginal,
132 const uint32_t& aLoadFlags,
133 const IPC::SerializedLoadContext& loadContext,
134 PBrowserParent* aParent)
135 {
136 nsCOMPtr<nsIURI> original = DeserializeURI(aOriginal);
137 if (!original)
138 return false;
139
140 LOG(("WyciwygChannelParent RecvAsyncOpen [this=%p]\n", this));
141
142 if (!mChannel)
143 return true;
144
145 nsresult rv;
146
147 rv = mChannel->SetOriginalURI(original);
148 if (NS_FAILED(rv))
149 return SendCancelEarly(rv);
150
151 rv = mChannel->SetLoadFlags(aLoadFlags);
152 if (NS_FAILED(rv))
153 return SendCancelEarly(rv);
154
155 if (!mReceivedAppData && !SetupAppData(loadContext, aParent)) {
156 return false;
157 }
158
159 rv = mChannel->SetNotificationCallbacks(this);
160 if (NS_FAILED(rv))
161 return SendCancelEarly(rv);
162
163 rv = mChannel->AsyncOpen(this, nullptr);
164 if (NS_FAILED(rv))
165 return SendCancelEarly(rv);
166
167 return true;
168 }
169
170 bool
171 WyciwygChannelParent::RecvWriteToCacheEntry(const nsString& data)
172 {
173 if (!mReceivedAppData) {
174 printf_stderr("WyciwygChannelParent::RecvWriteToCacheEntry: FATAL ERROR: didn't receive app data\n");
175 return false;
176 }
177
178 if (mChannel)
179 mChannel->WriteToCacheEntry(data);
180
181 return true;
182 }
183
184 bool
185 WyciwygChannelParent::RecvCloseCacheEntry(const nsresult& reason)
186 {
187 if (mChannel) {
188 mChannel->CloseCacheEntry(reason);
189 }
190
191 return true;
192 }
193
194 bool
195 WyciwygChannelParent::RecvSetCharsetAndSource(const int32_t& aCharsetSource,
196 const nsCString& aCharset)
197 {
198 if (mChannel)
199 mChannel->SetCharsetAndSource(aCharsetSource, aCharset);
200
201 return true;
202 }
203
204 bool
205 WyciwygChannelParent::RecvSetSecurityInfo(const nsCString& aSecurityInfo)
206 {
207 if (mChannel) {
208 nsCOMPtr<nsISupports> securityInfo;
209 NS_DeserializeObject(aSecurityInfo, getter_AddRefs(securityInfo));
210 mChannel->SetSecurityInfo(securityInfo);
211 }
212
213 return true;
214 }
215
216 bool
217 WyciwygChannelParent::RecvCancel(const nsresult& aStatusCode)
218 {
219 if (mChannel)
220 mChannel->Cancel(aStatusCode);
221 return true;
222 }
223
224 //-----------------------------------------------------------------------------
225 // WyciwygChannelParent::nsIRequestObserver
226 //-----------------------------------------------------------------------------
227
228 NS_IMETHODIMP
229 WyciwygChannelParent::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
230 {
231 LOG(("WyciwygChannelParent::OnStartRequest [this=%p]\n", this));
232
233 nsresult rv;
234
235 nsCOMPtr<nsIWyciwygChannel> chan = do_QueryInterface(aRequest, &rv);
236 NS_ENSURE_SUCCESS(rv, rv);
237
238 nsresult status;
239 chan->GetStatus(&status);
240
241 int64_t contentLength = -1;
242 chan->GetContentLength(&contentLength);
243
244 int32_t charsetSource = kCharsetUninitialized;
245 nsAutoCString charset;
246 chan->GetCharsetAndSource(&charsetSource, charset);
247
248 nsCOMPtr<nsISupports> securityInfo;
249 chan->GetSecurityInfo(getter_AddRefs(securityInfo));
250 nsCString secInfoStr;
251 if (securityInfo) {
252 nsCOMPtr<nsISerializable> serializable = do_QueryInterface(securityInfo);
253 if (serializable)
254 NS_SerializeToString(serializable, secInfoStr);
255 else {
256 NS_ERROR("Can't serialize security info");
257 return NS_ERROR_UNEXPECTED;
258 }
259 }
260
261 if (mIPCClosed ||
262 !SendOnStartRequest(status, contentLength, charsetSource, charset, secInfoStr)) {
263 return NS_ERROR_UNEXPECTED;
264 }
265
266 return NS_OK;
267 }
268
269 NS_IMETHODIMP
270 WyciwygChannelParent::OnStopRequest(nsIRequest *aRequest,
271 nsISupports *aContext,
272 nsresult aStatusCode)
273 {
274 LOG(("WyciwygChannelParent::OnStopRequest: [this=%p status=%ul]\n",
275 this, aStatusCode));
276
277 if (mIPCClosed || !SendOnStopRequest(aStatusCode)) {
278 return NS_ERROR_UNEXPECTED;
279 }
280
281 return NS_OK;
282 }
283
284 //-----------------------------------------------------------------------------
285 // WyciwygChannelParent::nsIStreamListener
286 //-----------------------------------------------------------------------------
287
288 NS_IMETHODIMP
289 WyciwygChannelParent::OnDataAvailable(nsIRequest *aRequest,
290 nsISupports *aContext,
291 nsIInputStream *aInputStream,
292 uint64_t aOffset,
293 uint32_t aCount)
294 {
295 LOG(("WyciwygChannelParent::OnDataAvailable [this=%p]\n", this));
296
297 nsCString data;
298 nsresult rv = NS_ReadInputStreamToString(aInputStream, data, aCount);
299 if (NS_FAILED(rv))
300 return rv;
301
302 if (mIPCClosed || !SendOnDataAvailable(data, aOffset)) {
303 return NS_ERROR_UNEXPECTED;
304 }
305
306 return NS_OK;
307 }
308
309 //-----------------------------------------------------------------------------
310 // WyciwygChannelParent::nsIInterfaceRequestor
311 //-----------------------------------------------------------------------------
312
313 NS_IMETHODIMP
314 WyciwygChannelParent::GetInterface(const nsIID& uuid, void** result)
315 {
316 // Only support nsILoadContext if child channel's callbacks did too
317 if (uuid.Equals(NS_GET_IID(nsILoadContext)) && mLoadContext) {
318 NS_ADDREF(mLoadContext);
319 *result = static_cast<nsILoadContext*>(mLoadContext);
320 return NS_OK;
321 }
322
323 return QueryInterface(uuid, result);
324 }
325
326
327 }} // mozilla::net

mercurial