Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/netwerk/base/nsSecCheckWrapChannel.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 "nsContentSecurityManager.h"
7
#include "nsSecCheckWrapChannel.h"
8
#include "nsIForcePendingChannel.h"
9
#include "nsIStreamListener.h"
10
#include "mozilla/Logging.h"
11
#include "nsCOMPtr.h"
12
13
namespace mozilla {
14
namespace net {
15
16
static LazyLogModule gChannelWrapperLog("ChannelWrapper");
17
0
#define CHANNELWRAPPERLOG(args) MOZ_LOG(gChannelWrapperLog, LogLevel::Debug, args)
18
19
NS_IMPL_ADDREF(nsSecCheckWrapChannelBase)
20
NS_IMPL_RELEASE(nsSecCheckWrapChannelBase)
21
22
0
NS_INTERFACE_MAP_BEGIN(nsSecCheckWrapChannelBase)
23
0
  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannel, mHttpChannel)
24
0
  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannelInternal, mHttpChannelInternal)
25
0
  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHttpChannel)
26
0
  NS_INTERFACE_MAP_ENTRY(nsIRequest)
27
0
  NS_INTERFACE_MAP_ENTRY(nsIChannel)
28
0
  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel, mUploadChannel)
29
0
  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel2, mUploadChannel2)
30
0
  NS_INTERFACE_MAP_ENTRY(nsISecCheckWrapChannel)
31
0
NS_INTERFACE_MAP_END
32
33
//---------------------------------------------------------
34
// nsSecCheckWrapChannelBase implementation
35
//---------------------------------------------------------
36
37
nsSecCheckWrapChannelBase::nsSecCheckWrapChannelBase(nsIChannel* aChannel)
38
 : mChannel(aChannel)
39
 , mHttpChannel(do_QueryInterface(aChannel))
40
 , mHttpChannelInternal(do_QueryInterface(aChannel))
41
 , mRequest(do_QueryInterface(aChannel))
42
 , mUploadChannel(do_QueryInterface(aChannel))
43
 , mUploadChannel2(do_QueryInterface(aChannel))
44
0
{
45
0
  MOZ_ASSERT(mChannel, "can not create a channel wrapper without a channel");
46
0
}
47
48
//---------------------------------------------------------
49
// nsISecCheckWrapChannel implementation
50
//---------------------------------------------------------
51
52
NS_IMETHODIMP
53
nsSecCheckWrapChannelBase::GetInnerChannel(nsIChannel **aInnerChannel)
54
0
{
55
0
  NS_IF_ADDREF(*aInnerChannel = mChannel);
56
0
  return NS_OK;
57
0
}
58
59
//---------------------------------------------------------
60
// nsSecCheckWrapChannel implementation
61
//---------------------------------------------------------
62
63
nsSecCheckWrapChannel::nsSecCheckWrapChannel(nsIChannel* aChannel,
64
                                             nsILoadInfo* aLoadInfo)
65
 : nsSecCheckWrapChannelBase(aChannel)
66
 , mLoadInfo(aLoadInfo)
67
0
{
68
0
  {
69
0
    nsCOMPtr<nsIURI> uri;
70
0
    mChannel->GetURI(getter_AddRefs(uri));
71
0
    CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::nsSecCheckWrapChannel [%p] (%s)",
72
0
                       this, uri ? uri->GetSpecOrDefault().get() : ""));
73
0
  }
74
0
}
75
76
// static
77
already_AddRefed<nsIChannel>
78
nsSecCheckWrapChannel::MaybeWrap(nsIChannel* aChannel, nsILoadInfo* aLoadInfo)
79
0
{
80
0
  // Maybe a custom protocol handler actually returns a gecko
81
0
  // http/ftpChannel - To check this we will check whether the channel
82
0
  // implements a gecko non-scriptable interface e.g. nsIForcePendingChannel.
83
0
  nsCOMPtr<nsIForcePendingChannel> isGeckoChannel = do_QueryInterface(aChannel);
84
0
85
0
  nsCOMPtr<nsIChannel> channel;
86
0
  if (isGeckoChannel) {
87
0
    // If it is a gecko channel (ftp or http) we do not need to wrap it.
88
0
    channel = aChannel;
89
0
    channel->SetLoadInfo(aLoadInfo);
90
0
  } else {
91
0
    channel = new nsSecCheckWrapChannel(aChannel, aLoadInfo);
92
0
  }
93
0
  return channel.forget();
94
0
}
95
96
//---------------------------------------------------------
97
// SecWrapChannelStreamListener helper
98
//---------------------------------------------------------
99
100
class SecWrapChannelStreamListener final : public nsIStreamListener
101
{
102
  public:
103
    SecWrapChannelStreamListener(nsIRequest *aRequest,
104
                                 nsIStreamListener *aStreamListener)
105
    : mRequest(aRequest)
106
0
    , mListener(aStreamListener) {}
107
108
    NS_DECL_ISUPPORTS
109
    NS_DECL_NSISTREAMLISTENER
110
    NS_DECL_NSIREQUESTOBSERVER
111
112
  private:
113
0
    ~SecWrapChannelStreamListener() = default;
114
115
    nsCOMPtr<nsIRequest>        mRequest;
116
    nsCOMPtr<nsIStreamListener> mListener;
117
};
118
119
NS_IMPL_ISUPPORTS(SecWrapChannelStreamListener,
120
                  nsIStreamListener,
121
                  nsIRequestObserver)
122
123
NS_IMETHODIMP
124
SecWrapChannelStreamListener::OnStartRequest(nsIRequest *aRequest,
125
                                             nsISupports *aContext)
126
0
{
127
0
  return mListener->OnStartRequest(mRequest, aContext);
128
0
}
129
130
NS_IMETHODIMP
131
SecWrapChannelStreamListener::OnStopRequest(nsIRequest *aRequest,
132
                                            nsISupports *aContext,
133
                                            nsresult aStatus)
134
0
{
135
0
  return mListener->OnStopRequest(mRequest, aContext, aStatus);
136
0
}
137
138
NS_IMETHODIMP
139
SecWrapChannelStreamListener::OnDataAvailable(nsIRequest *aRequest,
140
                                              nsISupports *aContext,
141
                                              nsIInputStream *aInStream,
142
                                              uint64_t aOffset,
143
                                              uint32_t aCount)
144
0
{
145
0
  return mListener->OnDataAvailable(mRequest, aContext, aInStream, aOffset, aCount);
146
0
}
147
148
//---------------------------------------------------------
149
// nsIChannel implementation
150
//---------------------------------------------------------
151
152
NS_IMETHODIMP
153
nsSecCheckWrapChannel::GetLoadInfo(nsILoadInfo** aLoadInfo)
154
0
{
155
0
  CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::GetLoadInfo() [%p]",this));
156
0
  NS_IF_ADDREF(*aLoadInfo = mLoadInfo);
157
0
  return NS_OK;
158
0
}
159
160
NS_IMETHODIMP
161
nsSecCheckWrapChannel::SetLoadInfo(nsILoadInfo* aLoadInfo)
162
0
{
163
0
  CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::SetLoadInfo() [%p]", this));
164
0
  mLoadInfo = aLoadInfo;
165
0
  return NS_OK;
166
0
}
167
168
NS_IMETHODIMP
169
nsSecCheckWrapChannel::AsyncOpen2(nsIStreamListener *aListener)
170
0
{
171
0
  nsCOMPtr<nsIStreamListener> secWrapChannelListener =
172
0
    new SecWrapChannelStreamListener(this, aListener);
173
0
  nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, secWrapChannelListener);
174
0
  NS_ENSURE_SUCCESS(rv, rv);
175
0
  return AsyncOpen(secWrapChannelListener, nullptr);
176
0
}
177
178
NS_IMETHODIMP
179
nsSecCheckWrapChannel::Open2(nsIInputStream** aStream)
180
0
{
181
0
  nsCOMPtr<nsIStreamListener> listener;
182
0
  nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
183
0
  NS_ENSURE_SUCCESS(rv, rv);
184
0
  return Open(aStream);
185
0
}
186
187
} // namespace net
188
} // namespace mozilla