1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=2 et sw=2 tw=80: */
3 : /****** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is IPC External Helper App module.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Brian Crowder <crowderbt@gmail.com>.
20 : * Portions created by the Initial Developer are Copyright (C) 2010
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "ExternalHelperAppParent.h"
40 : #include "nsIContent.h"
41 : #include "nsIDocument.h"
42 : #include "nsCExternalHandlerService.h"
43 : #include "nsIExternalHelperAppService.h"
44 : #include "mozilla/dom/ContentParent.h"
45 : #include "nsIBrowserDOMWindow.h"
46 : #include "nsStringStream.h"
47 :
48 : #include "mozilla/unused.h"
49 : #include "mozilla/Util.h" // for DebugOnly
50 :
51 : namespace mozilla {
52 : namespace dom {
53 :
54 0 : NS_IMPL_ISUPPORTS_INHERITED4(ExternalHelperAppParent,
55 : nsHashPropertyBag,
56 : nsIRequest,
57 : nsIChannel,
58 : nsIMultiPartChannel,
59 : nsIResumableChannel)
60 :
61 0 : ExternalHelperAppParent::ExternalHelperAppParent(
62 : const IPC::URI& uri,
63 : const PRInt64& aContentLength)
64 : : mURI(uri)
65 : , mPending(false)
66 : , mLoadFlags(0)
67 : , mStatus(NS_OK)
68 0 : , mContentLength(aContentLength)
69 : {
70 0 : }
71 :
72 : void
73 0 : ExternalHelperAppParent::Init(ContentParent *parent,
74 : const nsCString& aMimeContentType,
75 : const nsCString& aContentDispositionHeader,
76 : const bool& aForceSave,
77 : const IPC::URI& aReferrer)
78 : {
79 0 : nsHashPropertyBag::Init();
80 :
81 : nsCOMPtr<nsIExternalHelperAppService> helperAppService =
82 0 : do_GetService(NS_EXTERNALHELPERAPPSERVICE_CONTRACTID);
83 0 : NS_ASSERTION(helperAppService, "No Helper App Service!");
84 :
85 0 : SetPropertyAsInt64(NS_CHANNEL_PROP_CONTENT_LENGTH, mContentLength);
86 0 : if (aReferrer)
87 0 : SetPropertyAsInterface(NS_LITERAL_STRING("docshell.internalReferrer"), aReferrer);
88 0 : mContentDispositionHeader = aContentDispositionHeader;
89 0 : NS_GetFilenameFromDisposition(mContentDispositionFilename, mContentDispositionHeader, mURI);
90 0 : mContentDisposition = NS_GetContentDispositionFromHeader(mContentDispositionHeader, this);
91 0 : helperAppService->DoContent(aMimeContentType, this, nsnull,
92 0 : aForceSave, getter_AddRefs(mListener));
93 0 : }
94 :
95 : bool
96 0 : ExternalHelperAppParent::RecvOnStartRequest(const nsCString& entityID)
97 : {
98 0 : mEntityID = entityID;
99 0 : mPending = true;
100 0 : mStatus = mListener->OnStartRequest(this, nsnull);
101 0 : return true;
102 : }
103 :
104 : bool
105 0 : ExternalHelperAppParent::RecvOnDataAvailable(const nsCString& data,
106 : const PRUint32& offset,
107 : const PRUint32& count)
108 : {
109 0 : if (NS_FAILED(mStatus))
110 0 : return true;
111 :
112 0 : NS_ASSERTION(mPending, "must be pending!");
113 0 : nsCOMPtr<nsIInputStream> stringStream;
114 0 : DebugOnly<nsresult> rv = NS_NewByteInputStream(getter_AddRefs(stringStream), data.get(), count, NS_ASSIGNMENT_DEPEND);
115 0 : NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create dependent string!");
116 0 : mStatus = mListener->OnDataAvailable(this, nsnull, stringStream, offset, count);
117 :
118 0 : return true;
119 : }
120 :
121 : bool
122 0 : ExternalHelperAppParent::RecvOnStopRequest(const nsresult& code)
123 : {
124 0 : mPending = false;
125 0 : mListener->OnStopRequest(this, nsnull,
126 0 : (NS_SUCCEEDED(code) && NS_FAILED(mStatus)) ? mStatus : code);
127 0 : unused << Send__delete__(this);
128 0 : return true;
129 : }
130 :
131 0 : ExternalHelperAppParent::~ExternalHelperAppParent()
132 : {
133 0 : }
134 :
135 : //
136 : // nsIRequest implementation...
137 : //
138 :
139 : NS_IMETHODIMP
140 0 : ExternalHelperAppParent::GetName(nsACString& aResult)
141 : {
142 0 : mURI->GetAsciiSpec(aResult);
143 0 : return NS_OK;
144 : }
145 :
146 : NS_IMETHODIMP
147 0 : ExternalHelperAppParent::IsPending(bool *aResult)
148 : {
149 0 : *aResult = mPending;
150 0 : return NS_OK;
151 : }
152 :
153 : NS_IMETHODIMP
154 0 : ExternalHelperAppParent::GetStatus(nsresult *aResult)
155 : {
156 0 : *aResult = mStatus;
157 0 : return NS_OK;
158 : }
159 :
160 : NS_IMETHODIMP
161 0 : ExternalHelperAppParent::Cancel(nsresult aStatus)
162 : {
163 0 : mStatus = aStatus;
164 0 : unused << SendCancel(aStatus);
165 0 : return NS_OK;
166 : }
167 :
168 : NS_IMETHODIMP
169 0 : ExternalHelperAppParent::Suspend()
170 : {
171 0 : return NS_ERROR_NOT_IMPLEMENTED;
172 : }
173 :
174 : NS_IMETHODIMP
175 0 : ExternalHelperAppParent::Resume()
176 : {
177 0 : return NS_ERROR_NOT_IMPLEMENTED;
178 : }
179 :
180 : //
181 : // nsIChannel implementation
182 : //
183 :
184 : NS_IMETHODIMP
185 0 : ExternalHelperAppParent::GetOriginalURI(nsIURI * *aURI)
186 : {
187 0 : NS_IF_ADDREF(*aURI = mURI);
188 0 : return NS_OK;
189 : }
190 :
191 : NS_IMETHODIMP
192 0 : ExternalHelperAppParent::SetOriginalURI(nsIURI *aURI)
193 : {
194 0 : return NS_ERROR_NOT_IMPLEMENTED;
195 : }
196 :
197 : NS_IMETHODIMP
198 0 : ExternalHelperAppParent::GetURI(nsIURI **aURI)
199 : {
200 0 : NS_IF_ADDREF(*aURI = mURI);
201 0 : return NS_OK;
202 : }
203 :
204 : NS_IMETHODIMP
205 0 : ExternalHelperAppParent::Open(nsIInputStream **aResult)
206 : {
207 0 : return NS_ERROR_NOT_IMPLEMENTED;
208 : }
209 :
210 : NS_IMETHODIMP
211 0 : ExternalHelperAppParent::AsyncOpen(nsIStreamListener *aListener,
212 : nsISupports *aContext)
213 : {
214 0 : return NS_ERROR_NOT_IMPLEMENTED;
215 : }
216 :
217 :
218 : NS_IMETHODIMP
219 0 : ExternalHelperAppParent::GetLoadFlags(nsLoadFlags *aLoadFlags)
220 : {
221 0 : *aLoadFlags = mLoadFlags;
222 0 : return NS_OK;
223 : }
224 :
225 : NS_IMETHODIMP
226 0 : ExternalHelperAppParent::SetLoadFlags(nsLoadFlags aLoadFlags)
227 : {
228 0 : mLoadFlags = aLoadFlags;
229 0 : return NS_OK;
230 : }
231 :
232 : NS_IMETHODIMP
233 0 : ExternalHelperAppParent::GetLoadGroup(nsILoadGroup* *aLoadGroup)
234 : {
235 0 : *aLoadGroup = nsnull;
236 0 : return NS_OK;
237 : }
238 :
239 : NS_IMETHODIMP
240 0 : ExternalHelperAppParent::SetLoadGroup(nsILoadGroup* aLoadGroup)
241 : {
242 0 : return NS_ERROR_NOT_IMPLEMENTED;
243 : }
244 :
245 : NS_IMETHODIMP
246 0 : ExternalHelperAppParent::GetOwner(nsISupports* *aOwner)
247 : {
248 0 : *aOwner = nsnull;
249 0 : return NS_OK;
250 : }
251 :
252 : NS_IMETHODIMP
253 0 : ExternalHelperAppParent::SetOwner(nsISupports* aOwner)
254 : {
255 0 : return NS_ERROR_NOT_IMPLEMENTED;
256 : }
257 :
258 : NS_IMETHODIMP
259 0 : ExternalHelperAppParent::GetNotificationCallbacks(nsIInterfaceRequestor* *aCallbacks)
260 : {
261 0 : *aCallbacks = nsnull;
262 0 : return NS_OK;
263 : }
264 :
265 : NS_IMETHODIMP
266 0 : ExternalHelperAppParent::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks)
267 : {
268 0 : return NS_ERROR_NOT_IMPLEMENTED;
269 : }
270 :
271 : NS_IMETHODIMP
272 0 : ExternalHelperAppParent::GetSecurityInfo(nsISupports * *aSecurityInfo)
273 : {
274 0 : *aSecurityInfo = nsnull;
275 0 : return NS_OK;
276 : }
277 :
278 : NS_IMETHODIMP
279 0 : ExternalHelperAppParent::GetContentType(nsACString& aContentType)
280 : {
281 0 : aContentType.Truncate();
282 0 : return NS_OK;
283 : }
284 :
285 : NS_IMETHODIMP
286 0 : ExternalHelperAppParent::SetContentType(const nsACString& aContentType)
287 : {
288 0 : return NS_ERROR_NOT_IMPLEMENTED;
289 : }
290 :
291 : NS_IMETHODIMP
292 0 : ExternalHelperAppParent::GetContentCharset(nsACString& aContentCharset)
293 : {
294 0 : aContentCharset.Truncate();
295 0 : return NS_OK;
296 : }
297 :
298 : NS_IMETHODIMP
299 0 : ExternalHelperAppParent::SetContentCharset(const nsACString& aContentCharset)
300 : {
301 0 : return NS_ERROR_NOT_IMPLEMENTED;
302 : }
303 :
304 : NS_IMETHODIMP
305 0 : ExternalHelperAppParent::GetContentDisposition(PRUint32 *aContentDisposition)
306 : {
307 0 : if (mContentDispositionHeader.IsEmpty())
308 0 : return NS_ERROR_NOT_AVAILABLE;
309 :
310 0 : *aContentDisposition = mContentDisposition;
311 0 : return NS_OK;
312 : }
313 :
314 : NS_IMETHODIMP
315 0 : ExternalHelperAppParent::GetContentDispositionFilename(nsAString& aContentDispositionFilename)
316 : {
317 0 : if (mContentDispositionFilename.IsEmpty())
318 0 : return NS_ERROR_NOT_AVAILABLE;
319 :
320 0 : aContentDispositionFilename = mContentDispositionFilename;
321 0 : return NS_OK;
322 : }
323 :
324 : NS_IMETHODIMP
325 0 : ExternalHelperAppParent::GetContentDispositionHeader(nsACString& aContentDispositionHeader)
326 : {
327 0 : if (mContentDispositionHeader.IsEmpty())
328 0 : return NS_ERROR_NOT_AVAILABLE;
329 :
330 0 : aContentDispositionHeader = mContentDispositionHeader;
331 0 : return NS_OK;
332 : }
333 :
334 : NS_IMETHODIMP
335 0 : ExternalHelperAppParent::GetContentLength(PRInt32 *aContentLength)
336 : {
337 0 : if (mContentLength > PR_INT32_MAX || mContentLength < 0)
338 0 : *aContentLength = -1;
339 : else
340 0 : *aContentLength = (PRInt32)mContentLength;
341 0 : return NS_OK;
342 : }
343 :
344 : NS_IMETHODIMP
345 0 : ExternalHelperAppParent::SetContentLength(PRInt32 aContentLength)
346 : {
347 0 : mContentLength = aContentLength;
348 0 : return NS_OK;
349 : }
350 :
351 : //
352 : // nsIResumableChannel implementation
353 : //
354 :
355 : NS_IMETHODIMP
356 0 : ExternalHelperAppParent::ResumeAt(PRUint64 startPos, const nsACString& entityID)
357 : {
358 0 : return NS_ERROR_NOT_IMPLEMENTED;
359 : }
360 :
361 : NS_IMETHODIMP
362 0 : ExternalHelperAppParent::GetEntityID(nsACString& aEntityID)
363 : {
364 0 : aEntityID = mEntityID;
365 0 : return NS_OK;
366 : }
367 :
368 : //
369 : // nsIMultiPartChannel implementation
370 : //
371 :
372 : NS_IMETHODIMP
373 0 : ExternalHelperAppParent::GetBaseChannel(nsIChannel* *aChannel)
374 : {
375 0 : return NS_ERROR_NOT_IMPLEMENTED;
376 : }
377 :
378 : NS_IMETHODIMP
379 0 : ExternalHelperAppParent::GetPartID(PRUint32* aPartID)
380 : {
381 0 : return NS_ERROR_NOT_IMPLEMENTED;
382 : }
383 :
384 : NS_IMETHODIMP
385 0 : ExternalHelperAppParent::GetIsLastPart(bool* aIsLastPart)
386 : {
387 0 : return NS_ERROR_NOT_IMPLEMENTED;
388 : }
389 :
390 : } // namespace dom
391 : } // namespace mozilla
|