Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/netwerk/base/SimpleChannel.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#include "SimpleChannel.h"
7
8
#include "nsBaseChannel.h"
9
#include "nsIChannel.h"
10
#include "nsIChildChannel.h"
11
#include "nsIInputStream.h"
12
#include "nsIRequest.h"
13
#include "nsISupportsImpl.h"
14
#include "nsNetUtil.h"
15
16
#include "mozilla/Unused.h"
17
#include "mozilla/dom/ContentChild.h"
18
#include "mozilla/net/NeckoChild.h"
19
#include "mozilla/net/PSimpleChannelChild.h"
20
21
namespace mozilla {
22
namespace net {
23
24
class SimpleChannel : public nsBaseChannel
25
{
26
public:
27
  explicit SimpleChannel(UniquePtr<SimpleChannelCallbacks>&& aCallbacks);
28
29
protected:
30
0
  virtual ~SimpleChannel() = default;
31
32
  virtual nsresult OpenContentStream(bool async, nsIInputStream **streamOut,
33
                                     nsIChannel** channel) override;
34
35
  virtual nsresult BeginAsyncRead(nsIStreamListener* listener,
36
                                  nsIRequest** request) override;
37
38
private:
39
  UniquePtr<SimpleChannelCallbacks> mCallbacks;
40
};
41
42
SimpleChannel::SimpleChannel(UniquePtr<SimpleChannelCallbacks>&& aCallbacks)
43
  : mCallbacks(std::move(aCallbacks))
44
0
{
45
0
  EnableSynthesizedProgressEvents(true);
46
0
}
47
48
nsresult
49
SimpleChannel::OpenContentStream(bool async, nsIInputStream **streamOut, nsIChannel** channel)
50
0
{
51
0
  NS_ENSURE_TRUE(mCallbacks, NS_ERROR_UNEXPECTED);
52
0
53
0
  nsCOMPtr<nsIInputStream> stream;
54
0
  MOZ_TRY_VAR(stream, mCallbacks->OpenContentStream(async, this));
55
0
  MOZ_ASSERT(stream);
56
0
57
0
  mCallbacks = nullptr;
58
0
59
0
  *channel = nullptr;
60
0
  stream.forget(streamOut);
61
0
  return NS_OK;
62
0
}
63
64
nsresult
65
SimpleChannel::BeginAsyncRead(nsIStreamListener* listener, nsIRequest** request)
66
0
{
67
0
  NS_ENSURE_TRUE(mCallbacks, NS_ERROR_UNEXPECTED);
68
0
69
0
  nsCOMPtr<nsIRequest> req;
70
0
  MOZ_TRY_VAR(req, mCallbacks->StartAsyncRead(listener, this));
71
0
72
0
  mCallbacks = nullptr;
73
0
74
0
  req.forget(request);
75
0
  return NS_OK;
76
0
}
77
78
class SimpleChannelChild final : public SimpleChannel
79
                               , public nsIChildChannel
80
                               , public PSimpleChannelChild
81
{
82
public:
83
  explicit SimpleChannelChild(UniquePtr<SimpleChannelCallbacks>&& aCallbacks);
84
85
  NS_DECL_ISUPPORTS_INHERITED
86
  NS_DECL_NSICHILDCHANNEL
87
88
protected:
89
  virtual void ActorDestroy(ActorDestroyReason why) override;
90
91
private:
92
0
  virtual ~SimpleChannelChild() = default;
93
94
  void AddIPDLReference();
95
96
  RefPtr<SimpleChannelChild> mIPDLRef;
97
};
98
99
NS_IMPL_ISUPPORTS_INHERITED(SimpleChannelChild, SimpleChannel, nsIChildChannel)
100
101
SimpleChannelChild::SimpleChannelChild(UniquePtr<SimpleChannelCallbacks>&& aCallbacks)
102
  : SimpleChannel(std::move(aCallbacks))
103
  , mIPDLRef(nullptr)
104
0
{
105
0
}
106
107
NS_IMETHODIMP
108
SimpleChannelChild::ConnectParent(uint32_t aId)
109
0
{
110
0
  MOZ_ASSERT(NS_IsMainThread());
111
0
  mozilla::dom::ContentChild* cc =
112
0
    static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager());
113
0
  if (cc->IsShuttingDown()) {
114
0
    return NS_ERROR_FAILURE;
115
0
  }
116
0
117
0
  if (!gNeckoChild->SendPSimpleChannelConstructor(this, aId)) {
118
0
    return NS_ERROR_FAILURE;
119
0
  }
120
0
121
0
  // IPC now has a ref to us.
122
0
  mIPDLRef = this;
123
0
  return NS_OK;
124
0
}
125
126
NS_IMETHODIMP
127
SimpleChannelChild::CompleteRedirectSetup(nsIStreamListener* aListener,
128
                                          nsISupports* aContext)
129
0
{
130
0
  if (mIPDLRef) {
131
0
    MOZ_ASSERT(NS_IsMainThread());
132
0
  }
133
0
134
0
  nsresult rv;
135
0
  if (mLoadInfo && mLoadInfo->GetEnforceSecurity()) {
136
0
    MOZ_ASSERT(!aContext, "aContext should be null!");
137
0
    rv = AsyncOpen2(aListener);
138
0
  } else {
139
0
    rv = AsyncOpen(aListener, aContext);
140
0
  }
141
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
142
0
    return rv;
143
0
  }
144
0
145
0
  if (mIPDLRef) {
146
0
    Unused << Send__delete__(this);
147
0
  }
148
0
  return NS_OK;
149
0
}
150
151
void
152
SimpleChannelChild::ActorDestroy(ActorDestroyReason why)
153
0
{
154
0
  MOZ_ASSERT(mIPDLRef);
155
0
  mIPDLRef = nullptr;
156
0
}
157
158
159
already_AddRefed<nsIChannel>
160
NS_NewSimpleChannelInternal(nsIURI* aURI, nsILoadInfo* aLoadInfo, UniquePtr<SimpleChannelCallbacks>&& aCallbacks)
161
0
{
162
0
  RefPtr<SimpleChannel> chan;
163
0
  if (IsNeckoChild()) {
164
0
    chan = new SimpleChannelChild(std::move(aCallbacks));
165
0
  } else {
166
0
    chan = new SimpleChannel(std::move(aCallbacks));
167
0
  }
168
0
169
0
  chan->SetURI(aURI);
170
0
171
0
  MOZ_ALWAYS_SUCCEEDS(chan->SetLoadInfo(aLoadInfo));
172
0
173
0
  return chan.forget();
174
0
}
175
176
} // namespace net
177
} // namespace mozilla