Line data Source code
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 : /* 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 "ExternalHelperAppChild.h"
8 : #include "mozilla/net/ChannelDiverterChild.h"
9 : #include "mozilla/dom/TabChild.h"
10 : #include "nsIDivertableChannel.h"
11 : #include "nsIInputStream.h"
12 : #include "nsIFTPChannel.h"
13 : #include "nsIRequest.h"
14 : #include "nsIResumableChannel.h"
15 : #include "nsNetUtil.h"
16 :
17 : namespace mozilla {
18 : namespace dom {
19 :
20 0 : NS_IMPL_ISUPPORTS(ExternalHelperAppChild,
21 : nsIStreamListener,
22 : nsIRequestObserver)
23 :
24 0 : ExternalHelperAppChild::ExternalHelperAppChild()
25 0 : : mStatus(NS_OK)
26 : {
27 0 : }
28 :
29 0 : ExternalHelperAppChild::~ExternalHelperAppChild()
30 : {
31 0 : }
32 :
33 : //-----------------------------------------------------------------------------
34 : // nsIStreamListener
35 : //-----------------------------------------------------------------------------
36 : NS_IMETHODIMP
37 0 : ExternalHelperAppChild::OnDataAvailable(nsIRequest *request,
38 : nsISupports *ctx,
39 : nsIInputStream *input,
40 : uint64_t offset,
41 : uint32_t count)
42 : {
43 0 : if (NS_FAILED(mStatus))
44 0 : return mStatus;
45 :
46 0 : nsCString data;
47 0 : nsresult rv = NS_ReadInputStreamToString(input, data, count);
48 0 : if (NS_FAILED(rv))
49 0 : return rv;
50 :
51 0 : if (!SendOnDataAvailable(data, offset, count))
52 0 : return NS_ERROR_UNEXPECTED;
53 :
54 0 : return NS_OK;
55 : }
56 :
57 : //////////////////////////////////////////////////////////////////////////////
58 : // nsIRequestObserver
59 : //////////////////////////////////////////////////////////////////////////////
60 :
61 : NS_IMETHODIMP
62 0 : ExternalHelperAppChild::OnStartRequest(nsIRequest *request, nsISupports *ctx)
63 : {
64 0 : nsresult rv = mHandler->OnStartRequest(request, ctx);
65 0 : NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED);
66 :
67 : // Calling OnStartRequest could cause mHandler to close the window it was
68 : // loaded for. In that case, the TabParent in the parent context might then
69 : // point to the wrong window. Re-send the window context along with either
70 : // DivertToParent or SendOnStartRequest just in case.
71 : nsCOMPtr<nsPIDOMWindowOuter> window =
72 0 : do_GetInterface(mHandler->GetDialogParent());
73 0 : TabChild *tabChild = window ? mozilla::dom::TabChild::GetFrom(window) : nullptr;
74 :
75 0 : nsCOMPtr<nsIDivertableChannel> divertable = do_QueryInterface(request);
76 0 : if (divertable) {
77 0 : return DivertToParent(divertable, request, tabChild);
78 : }
79 :
80 0 : nsCString entityID;
81 0 : nsCOMPtr<nsIResumableChannel> resumable(do_QueryInterface(request));
82 0 : if (resumable) {
83 0 : resumable->GetEntityID(entityID);
84 : }
85 0 : SendOnStartRequest(entityID, tabChild);
86 0 : return NS_OK;
87 : }
88 :
89 : NS_IMETHODIMP
90 0 : ExternalHelperAppChild::OnStopRequest(nsIRequest *request,
91 : nsISupports *ctx,
92 : nsresult status)
93 : {
94 : // mHandler can be null if we diverted the request to the parent
95 0 : if (mHandler) {
96 0 : nsresult rv = mHandler->OnStopRequest(request, ctx, status);
97 0 : SendOnStopRequest(status);
98 0 : NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED);
99 : }
100 :
101 0 : return NS_OK;
102 : }
103 :
104 : nsresult
105 0 : ExternalHelperAppChild::DivertToParent(nsIDivertableChannel *divertable,
106 : nsIRequest *request,
107 : TabChild *tabChild)
108 : {
109 : // nsIDivertable must know about content conversions before being diverted.
110 0 : MOZ_ASSERT(mHandler);
111 0 : mHandler->MaybeApplyDecodingForExtension(request);
112 :
113 0 : mozilla::net::ChannelDiverterChild *diverter = nullptr;
114 0 : nsresult rv = divertable->DivertToParent(&diverter);
115 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
116 0 : return rv;
117 : }
118 0 : MOZ_ASSERT(diverter);
119 :
120 0 : if (SendDivertToParentUsing(diverter, tabChild)) {
121 0 : mHandler->DidDivertRequest(request);
122 0 : mHandler = nullptr;
123 0 : return NS_OK;
124 : }
125 :
126 0 : return NS_ERROR_FAILURE;
127 : }
128 :
129 : mozilla::ipc::IPCResult
130 0 : ExternalHelperAppChild::RecvCancel(const nsresult& aStatus)
131 : {
132 0 : mStatus = aStatus;
133 0 : return IPC_OK();
134 : }
135 :
136 : } // namespace dom
137 : } // namespace mozilla
|