Backed out 2 changesets (bug 1943998) for causing wd failures @ phases.py CLOSED...
[gecko.git] / netwerk / protocol / res / RemoteStreamGetter.cpp
blob8bad84ef5e1533d58121d2638624aac9d2173fd0
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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "RemoteStreamGetter.h"
8 #include "mozilla/MozPromise.h"
9 #include "mozilla/net/NeckoChild.h"
10 #include "mozilla/RefPtr.h"
11 #include "mozilla/ResultExtensions.h"
12 #include "nsContentUtils.h"
13 #include "nsIInputStreamPump.h"
15 namespace mozilla {
16 namespace net {
18 NS_IMPL_ISUPPORTS(RemoteStreamGetter, nsICancelable)
20 RemoteStreamGetter::RemoteStreamGetter(nsIURI* aURI, nsILoadInfo* aLoadInfo)
21 : mURI(aURI), mLoadInfo(aLoadInfo) {
22 MOZ_ASSERT(aURI);
23 MOZ_ASSERT(aLoadInfo);
26 // Request an input stream from the parent.
27 RequestOrReason RemoteStreamGetter::GetAsync(nsIStreamListener* aListener,
28 nsIChannel* aChannel,
29 Method aMethod) {
30 MOZ_ASSERT(IsNeckoChild());
31 MOZ_ASSERT(aMethod);
33 mListener = aListener;
34 mChannel = aChannel;
36 nsCOMPtr<nsICancelable> cancelableRequest(this);
38 RefPtr<RemoteStreamGetter> self = this;
39 LoadInfoArgs loadInfoArgs;
40 nsresult rv = ipc::LoadInfoToLoadInfoArgs(mLoadInfo, &loadInfoArgs);
41 if (NS_FAILED(rv)) {
42 return Err(rv);
45 (gNeckoChild->*aMethod)(mURI, loadInfoArgs)
46 ->Then(
47 GetMainThreadSerialEventTarget(), __func__,
48 [self](const Maybe<RemoteStreamInfo>& info) { self->OnStream(info); },
49 [self](const mozilla::ipc::ResponseRejectReason) {
50 self->OnStream(Nothing());
51 });
52 return RequestOrCancelable(WrapNotNull(cancelableRequest));
55 // Called to cancel the ongoing async request.
56 NS_IMETHODIMP
57 RemoteStreamGetter::Cancel(nsresult aStatus) {
58 if (mCanceled) {
59 return NS_OK;
62 mCanceled = true;
63 mStatus = aStatus;
65 if (mPump) {
66 mPump->Cancel(aStatus);
67 mPump = nullptr;
70 return NS_OK;
73 // static
74 void RemoteStreamGetter::CancelRequest(nsIStreamListener* aListener,
75 nsIChannel* aChannel, nsresult aResult) {
76 MOZ_ASSERT(aListener);
77 MOZ_ASSERT(aChannel);
79 aListener->OnStartRequest(aChannel);
80 aListener->OnStopRequest(aChannel, aResult);
81 aChannel->CancelWithReason(NS_BINDING_ABORTED,
82 "RemoteStreamGetter::CancelRequest"_ns);
85 // Handle an input stream sent from the parent.
86 void RemoteStreamGetter::OnStream(const Maybe<RemoteStreamInfo>& aStreamInfo) {
87 MOZ_ASSERT(IsNeckoChild());
88 MOZ_ASSERT(mChannel);
89 MOZ_ASSERT(mListener);
91 nsCOMPtr<nsIChannel> channel = std::move(mChannel);
93 // We must keep an owning reference to the listener until we pass it on
94 // to AsyncRead.
95 nsCOMPtr<nsIStreamListener> listener = mListener.forget();
97 if (aStreamInfo.isNothing()) {
98 // The parent didn't send us back a stream.
99 CancelRequest(listener, channel, NS_ERROR_FILE_ACCESS_DENIED);
100 return;
103 if (mCanceled) {
104 // The channel that has created this stream getter has been canceled.
105 CancelRequest(listener, channel, mStatus);
106 return;
109 nsCOMPtr<nsIInputStream> stream = std::move(aStreamInfo.ref().inputStream());
110 if (!stream) {
111 // We somehow failed to get a stream, so just cancel the request.
112 CancelRequest(listener, channel, mStatus);
113 return;
116 nsCOMPtr<nsIInputStreamPump> pump;
117 nsresult rv =
118 NS_NewInputStreamPump(getter_AddRefs(pump), stream.forget(), 0, 0, false,
119 GetMainThreadSerialEventTarget());
120 if (NS_FAILED(rv)) {
121 CancelRequest(listener, channel, rv);
122 return;
125 channel->SetContentType(aStreamInfo.ref().contentType());
126 channel->SetContentLength(aStreamInfo.ref().contentLength());
128 rv = pump->AsyncRead(listener);
129 if (NS_FAILED(rv)) {
130 CancelRequest(listener, channel, rv);
131 return;
134 mPump = pump;
137 } // namespace net
138 } // namespace mozilla