Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim:set expandtab ts=2 sw=2 sts=2 cin: */
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 : #ifndef InterceptedChannel_h
8 : #define InterceptedChannel_h
9 :
10 : #include "nsINetworkInterceptController.h"
11 : #include "mozilla/RefPtr.h"
12 : #include "mozilla/Maybe.h"
13 :
14 : class nsICacheEntry;
15 : class nsInputStreamPump;
16 : class nsIStreamListener;
17 :
18 : namespace mozilla {
19 : namespace net {
20 :
21 : class nsHttpChannel;
22 : class HttpChannelChild;
23 : class nsHttpResponseHead;
24 : class InterceptStreamListener;
25 :
26 : // An object representing a channel that has been intercepted. This avoids complicating
27 : // the actual channel implementation with the details of synthesizing responses.
28 : class InterceptedChannelBase : public nsIInterceptedChannel {
29 : protected:
30 : // The interception controller to notify about the successful channel interception
31 : nsCOMPtr<nsINetworkInterceptController> mController;
32 :
33 : // The stream to write the body of the synthesized response
34 : nsCOMPtr<nsIOutputStream> mResponseBody;
35 :
36 : // Response head for use when synthesizing
37 : Maybe<nsAutoPtr<nsHttpResponseHead>> mSynthesizedResponseHead;
38 :
39 : nsCOMPtr<nsIConsoleReportCollector> mReportCollector;
40 : nsCOMPtr<nsISupports> mReleaseHandle;
41 :
42 : bool mClosed;
43 :
44 : void EnsureSynthesizedResponse();
45 : void DoNotifyController();
46 : MOZ_MUST_USE nsresult DoSynthesizeStatus(uint16_t aStatus,
47 : const nsACString& aReason);
48 : MOZ_MUST_USE nsresult DoSynthesizeHeader(const nsACString& aName,
49 : const nsACString& aValue);
50 :
51 : TimeStamp mLaunchServiceWorkerStart;
52 : TimeStamp mLaunchServiceWorkerEnd;
53 : TimeStamp mDispatchFetchEventStart;
54 : TimeStamp mDispatchFetchEventEnd;
55 : TimeStamp mHandleFetchEventStart;
56 : TimeStamp mHandleFetchEventEnd;
57 :
58 : TimeStamp mFinishResponseStart;
59 : TimeStamp mFinishResponseEnd;
60 : enum {
61 : Invalid = 0,
62 : Synthesized,
63 : Reset
64 : } mSynthesizedOrReset;
65 :
66 : virtual ~InterceptedChannelBase();
67 : public:
68 : explicit InterceptedChannelBase(nsINetworkInterceptController* aController);
69 :
70 : // Notify the interception controller that the channel has been intercepted
71 : // and prepare the response body output stream.
72 : virtual void NotifyController() = 0;
73 :
74 : NS_DECL_ISUPPORTS
75 :
76 : NS_IMETHOD GetResponseBody(nsIOutputStream** aOutput) override;
77 : NS_IMETHOD GetConsoleReportCollector(nsIConsoleReportCollector** aCollectorOut) override;
78 : NS_IMETHOD SetReleaseHandle(nsISupports* aHandle) override;
79 :
80 : NS_IMETHODIMP
81 0 : SetLaunchServiceWorkerStart(TimeStamp aTimeStamp) override
82 : {
83 0 : mLaunchServiceWorkerStart = aTimeStamp;
84 0 : return NS_OK;
85 : }
86 :
87 : NS_IMETHODIMP
88 0 : SetLaunchServiceWorkerEnd(TimeStamp aTimeStamp) override
89 : {
90 0 : mLaunchServiceWorkerEnd = aTimeStamp;
91 0 : return NS_OK;
92 : }
93 :
94 : NS_IMETHODIMP
95 0 : SetDispatchFetchEventStart(TimeStamp aTimeStamp) override
96 : {
97 0 : mDispatchFetchEventStart = aTimeStamp;
98 0 : return NS_OK;
99 : }
100 :
101 : NS_IMETHODIMP
102 0 : SetDispatchFetchEventEnd(TimeStamp aTimeStamp) override
103 : {
104 0 : mDispatchFetchEventEnd = aTimeStamp;
105 0 : return NS_OK;
106 : }
107 :
108 : NS_IMETHODIMP
109 0 : SetHandleFetchEventStart(TimeStamp aTimeStamp) override
110 : {
111 0 : mHandleFetchEventStart = aTimeStamp;
112 0 : return NS_OK;
113 : }
114 :
115 : NS_IMETHODIMP
116 0 : SetHandleFetchEventEnd(TimeStamp aTimeStamp) override
117 : {
118 0 : mHandleFetchEventEnd = aTimeStamp;
119 0 : return NS_OK;
120 : }
121 :
122 : NS_IMETHODIMP
123 0 : SetFinishResponseStart(TimeStamp aTimeStamp) override
124 : {
125 0 : mFinishResponseStart = aTimeStamp;
126 0 : return NS_OK;
127 : }
128 :
129 : NS_IMETHODIMP
130 0 : SetFinishSynthesizedResponseEnd(TimeStamp aTimeStamp) override
131 : {
132 0 : MOZ_ASSERT(mSynthesizedOrReset == Invalid);
133 0 : mSynthesizedOrReset = Synthesized;
134 0 : mFinishResponseEnd = aTimeStamp;
135 0 : return NS_OK;
136 : }
137 :
138 : NS_IMETHODIMP
139 0 : SetChannelResetEnd(TimeStamp aTimeStamp) override
140 : {
141 0 : MOZ_ASSERT(mSynthesizedOrReset == Invalid);
142 0 : mSynthesizedOrReset = Reset;
143 0 : mFinishResponseEnd = aTimeStamp;
144 0 : return NS_OK;
145 : }
146 :
147 : NS_IMETHODIMP SaveTimeStamps() override;
148 :
149 : static already_AddRefed<nsIURI>
150 : SecureUpgradeChannelURI(nsIChannel* aChannel);
151 : };
152 :
153 0 : class InterceptedChannelChrome : public InterceptedChannelBase
154 : {
155 : // The actual channel being intercepted.
156 : RefPtr<nsHttpChannel> mChannel;
157 :
158 : // Writeable cache entry for use when synthesizing a response in a parent process
159 : nsCOMPtr<nsICacheEntry> mSynthesizedCacheEntry;
160 :
161 : // When a channel is intercepted, content decoding is disabled since the
162 : // ServiceWorker will have already extracted the decoded data. For parent
163 : // process channels we need to preserve the earlier value in case
164 : // ResetInterception is called.
165 : bool mOldApplyConversion;
166 : public:
167 : InterceptedChannelChrome(nsHttpChannel* aChannel,
168 : nsINetworkInterceptController* aController,
169 : nsICacheEntry* aEntry);
170 :
171 : NS_IMETHOD ResetInterception() override;
172 : NS_IMETHOD FinishSynthesizedResponse(const nsACString& aFinalURLSpec) override;
173 : NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
174 : NS_IMETHOD GetSecureUpgradedChannelURI(nsIURI** aURI) override;
175 : NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override;
176 : NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override;
177 : NS_IMETHOD Cancel(nsresult aStatus) override;
178 : NS_IMETHOD SetChannelInfo(mozilla::dom::ChannelInfo* aChannelInfo) override;
179 : NS_IMETHOD GetInternalContentPolicyType(nsContentPolicyType *aInternalContentPolicyType) override;
180 :
181 : virtual void NotifyController() override;
182 : };
183 :
184 0 : class InterceptedChannelContent : public InterceptedChannelBase
185 : {
186 : // The actual channel being intercepted.
187 : RefPtr<HttpChannelChild> mChannel;
188 :
189 : // Reader-side of the response body when synthesizing in a child proces
190 : nsCOMPtr<nsIInputStream> mSynthesizedInput;
191 :
192 : // Listener for the synthesized response to fix up the notifications before they reach
193 : // the actual channel.
194 : RefPtr<InterceptStreamListener> mStreamListener;
195 :
196 : // Set for intercepted channels that have gone through a secure upgrade.
197 : bool mSecureUpgrade;
198 : public:
199 : InterceptedChannelContent(HttpChannelChild* aChannel,
200 : nsINetworkInterceptController* aController,
201 : InterceptStreamListener* aListener,
202 : bool aSecureUpgrade);
203 :
204 : NS_IMETHOD ResetInterception() override;
205 : NS_IMETHOD FinishSynthesizedResponse(const nsACString& aFinalURLSpec) override;
206 : NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
207 : NS_IMETHOD GetSecureUpgradedChannelURI(nsIURI** aURI) override;
208 : NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override;
209 : NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override;
210 : NS_IMETHOD Cancel(nsresult aStatus) override;
211 : NS_IMETHOD SetChannelInfo(mozilla::dom::ChannelInfo* aChannelInfo) override;
212 : NS_IMETHOD GetInternalContentPolicyType(nsContentPolicyType *aInternalContentPolicyType) override;
213 :
214 : virtual void NotifyController() override;
215 : };
216 :
217 : } // namespace net
218 : } // namespace mozilla
219 :
220 : #endif // InterceptedChannel_h
|