/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 |