Source code

Revision control

Other Tools

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/BrowserChild.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
NS_IMPL_ISUPPORTS(ExternalHelperAppChild, nsIStreamListener, nsIRequestObserver)
21
22
ExternalHelperAppChild::ExternalHelperAppChild() : mStatus(NS_OK) {}
23
24
ExternalHelperAppChild::~ExternalHelperAppChild() {}
25
26
//-----------------------------------------------------------------------------
27
// nsIStreamListener
28
//-----------------------------------------------------------------------------
29
NS_IMETHODIMP
30
ExternalHelperAppChild::OnDataAvailable(nsIRequest* request,
31
nsIInputStream* input, uint64_t offset,
32
uint32_t count) {
33
if (NS_FAILED(mStatus)) return mStatus;
34
35
static uint32_t const kCopyChunkSize = 128 * 1024;
36
uint32_t toRead = std::min<uint32_t>(count, kCopyChunkSize);
37
38
nsCString data;
39
40
while (count) {
41
nsresult rv = NS_ReadInputStreamToString(input, data, toRead);
42
if (NS_WARN_IF(NS_FAILED(rv))) {
43
return rv;
44
}
45
46
if (NS_WARN_IF(!SendOnDataAvailable(data, offset, toRead))) {
47
return NS_ERROR_UNEXPECTED;
48
}
49
50
count -= toRead;
51
offset += toRead;
52
toRead = std::min<uint32_t>(count, kCopyChunkSize);
53
}
54
55
return NS_OK;
56
}
57
58
//////////////////////////////////////////////////////////////////////////////
59
// nsIRequestObserver
60
//////////////////////////////////////////////////////////////////////////////
61
62
NS_IMETHODIMP
63
ExternalHelperAppChild::OnStartRequest(nsIRequest* request) {
64
nsresult rv = mHandler->OnStartRequest(request);
65
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 BrowserParent in the parent context might
69
// then point to the wrong window. Re-send the window context along with
70
// either DivertToParent or SendOnStartRequest just in case.
71
nsCOMPtr<nsPIDOMWindowOuter> window =
72
do_GetInterface(mHandler->GetDialogParent());
73
NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE);
74
75
BrowserChild* browserChild = mozilla::dom::BrowserChild::GetFrom(window);
76
NS_ENSURE_TRUE(browserChild, NS_ERROR_NOT_AVAILABLE);
77
78
nsCOMPtr<nsIDivertableChannel> divertable = do_QueryInterface(request);
79
if (divertable) {
80
return DivertToParent(divertable, request, browserChild);
81
}
82
83
nsCString entityID;
84
nsCOMPtr<nsIResumableChannel> resumable(do_QueryInterface(request));
85
if (resumable) {
86
resumable->GetEntityID(entityID);
87
}
88
SendOnStartRequest(entityID, browserChild);
89
return NS_OK;
90
}
91
92
NS_IMETHODIMP
93
ExternalHelperAppChild::OnStopRequest(nsIRequest* request, nsresult status) {
94
// mHandler can be null if we diverted the request to the parent
95
if (mHandler) {
96
nsresult rv = mHandler->OnStopRequest(request, status);
97
SendOnStopRequest(status);
98
NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED);
99
}
100
101
return NS_OK;
102
}
103
104
nsresult ExternalHelperAppChild::DivertToParent(
105
nsIDivertableChannel* divertable, nsIRequest* request,
106
BrowserChild* browserChild) {
107
// nsIDivertable must know about content conversions before being diverted.
108
MOZ_ASSERT(mHandler);
109
mHandler->MaybeApplyDecodingForExtension(request);
110
111
mozilla::net::ChannelDiverterChild* diverter = nullptr;
112
nsresult rv = divertable->DivertToParent(&diverter);
113
if (NS_WARN_IF(NS_FAILED(rv))) {
114
return rv;
115
}
116
MOZ_ASSERT(diverter);
117
118
if (SendDivertToParentUsing(diverter, browserChild)) {
119
mHandler->DidDivertRequest(request);
120
mHandler = nullptr;
121
return NS_OK;
122
}
123
124
return NS_ERROR_FAILURE;
125
}
126
127
mozilla::ipc::IPCResult ExternalHelperAppChild::RecvCancel(
128
const nsresult& aStatus) {
129
mStatus = aStatus;
130
return IPC_OK();
131
}
132
133
} // namespace dom
134
} // namespace mozilla