1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 ts=8 et tw=80 : */
3
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7
8 #ifndef mozilla_net_HttpBaseChannel_h
9 #define mozilla_net_HttpBaseChannel_h
10
11 #include "mozilla/Atomics.h"
12 #include "nsHttp.h"
13 #include "nsAutoPtr.h"
14 #include "nsHashPropertyBag.h"
15 #include "nsProxyInfo.h"
16 #include "nsHttpRequestHead.h"
17 #include "nsHttpResponseHead.h"
18 #include "nsHttpConnectionInfo.h"
19 #include "nsIConsoleReportCollector.h"
20 #include "nsIEncodedChannel.h"
21 #include "nsIHttpChannel.h"
22 #include "nsHttpHandler.h"
23 #include "nsIHttpChannelInternal.h"
24 #include "nsIForcePendingChannel.h"
25 #include "nsIFormPOSTActionChannel.h"
26 #include "nsIUploadChannel2.h"
27 #include "nsIProgressEventSink.h"
28 #include "nsIURI.h"
29 #include "nsIEffectiveTLDService.h"
30 #include "nsIStringEnumerator.h"
31 #include "nsISupportsPriority.h"
32 #include "nsIClassOfService.h"
33 #include "nsIClassifiedChannel.h"
34 #include "nsIApplicationCache.h"
35 #include "nsIResumableChannel.h"
36 #include "nsITraceableChannel.h"
37 #include "nsILoadContext.h"
38 #include "nsILoadInfo.h"
39 #include "mozilla/net/NeckoCommon.h"
40 #include "nsThreadUtils.h"
41 #include "PrivateBrowsingChannel.h"
42 #include "mozilla/net/DNS.h"
43 #include "nsITimedChannel.h"
44 #include "nsIHttpChannel.h"
45 #include "nsISecurityConsoleMessage.h"
46 #include "nsCOMArray.h"
47 #include "mozilla/net/ChannelEventQueue.h"
48 #include "mozilla/Move.h"
49 #include "nsIThrottledInputChannel.h"
50 #include "nsTArray.h"
51 #include "nsCOMPtr.h"
52 #include "mozilla/IntegerPrintfMacros.h"
53
54 #define HTTP_BASE_CHANNEL_IID \
55 { \
56 0x9d5cde03, 0xe6e9, 0x4612, { \
57 0xbf, 0xef, 0xbb, 0x66, 0xf3, 0xbb, 0x74, 0x46 \
58 } \
59 }
60
61 class nsISecurityConsoleMessage;
62 class nsIPrincipal;
63
64 namespace mozilla {
65
66 namespace dom {
67 class PerformanceStorage;
68 }
69
70 class LogCollector;
71
72 namespace net {
73 extern mozilla::LazyLogModule gHttpLog;
74
75 /*
76 * This class is a partial implementation of nsIHttpChannel. It contains code
77 * shared by nsHttpChannel and HttpChannelChild.
78 * - Note that this class has nothing to do with nsBaseChannel, which is an
79 * earlier effort at a base class for channels that somehow never made it all
80 * the way to the HTTP channel.
81 */
82 class HttpBaseChannel : public nsHashPropertyBag,
83 public nsIEncodedChannel,
84 public nsIHttpChannel,
85 public nsIHttpChannelInternal,
86 public nsIFormPOSTActionChannel,
87 public nsIUploadChannel2,
88 public nsISupportsPriority,
89 public nsIClassOfService,
90 public nsIResumableChannel,
91 public nsITraceableChannel,
92 public PrivateBrowsingChannel<HttpBaseChannel>,
93 public nsITimedChannel,
94 public nsIForcePendingChannel,
95 public nsIConsoleReportCollector,
96 public nsIThrottledInputChannel,
97 public nsIClassifiedChannel {
98 protected:
99 virtual ~HttpBaseChannel();
100
101 public:
102 NS_DECL_ISUPPORTS_INHERITED
103 NS_DECL_NSIUPLOADCHANNEL
104 NS_DECL_NSIFORMPOSTACTIONCHANNEL
105 NS_DECL_NSIUPLOADCHANNEL2
106 NS_DECL_NSITRACEABLECHANNEL
107 NS_DECL_NSITIMEDCHANNEL
108 NS_DECL_NSITHROTTLEDINPUTCHANNEL
109 NS_DECL_NSICLASSIFIEDCHANNEL
110
111 NS_DECLARE_STATIC_IID_ACCESSOR(HTTP_BASE_CHANNEL_IID)
112
113 HttpBaseChannel();
114
115 virtual MOZ_MUST_USE nsresult Init(nsIURI *aURI, uint32_t aCaps,
116 nsProxyInfo *aProxyInfo,
117 uint32_t aProxyResolveFlags,
118 nsIURI *aProxyURI, uint64_t aChannelId);
119
120 // nsIRequest
121 NS_IMETHOD GetName(nsACString &aName) override;
122 NS_IMETHOD IsPending(bool *aIsPending) override;
123 NS_IMETHOD GetStatus(nsresult *aStatus) override;
124 NS_IMETHOD GetLoadGroup(nsILoadGroup **aLoadGroup) override;
125 NS_IMETHOD SetLoadGroup(nsILoadGroup *aLoadGroup) override;
126 NS_IMETHOD GetLoadFlags(nsLoadFlags *aLoadFlags) override;
127 NS_IMETHOD SetLoadFlags(nsLoadFlags aLoadFlags) override;
128 NS_IMETHOD SetDocshellUserAgentOverride();
129
130 // nsIChannel
131 NS_IMETHOD GetOriginalURI(nsIURI **aOriginalURI) override;
132 NS_IMETHOD SetOriginalURI(nsIURI *aOriginalURI) override;
133 NS_IMETHOD GetURI(nsIURI **aURI) override;
134 NS_IMETHOD GetOwner(nsISupports **aOwner) override;
135 NS_IMETHOD SetOwner(nsISupports *aOwner) override;
136 NS_IMETHOD GetLoadInfo(nsILoadInfo **aLoadInfo) override;
137 NS_IMETHOD SetLoadInfo(nsILoadInfo *aLoadInfo) override;
138 NS_IMETHOD GetIsDocument(bool *aIsDocument) override;
139 NS_IMETHOD GetNotificationCallbacks(
140 nsIInterfaceRequestor **aCallbacks) override;
141 NS_IMETHOD SetNotificationCallbacks(
142 nsIInterfaceRequestor *aCallbacks) override;
143 NS_IMETHOD GetContentType(nsACString &aContentType) override;
144 NS_IMETHOD SetContentType(const nsACString &aContentType) override;
145 NS_IMETHOD GetContentCharset(nsACString &aContentCharset) override;
146 NS_IMETHOD SetContentCharset(const nsACString &aContentCharset) override;
147 NS_IMETHOD GetContentDisposition(uint32_t *aContentDisposition) override;
148 NS_IMETHOD SetContentDisposition(uint32_t aContentDisposition) override;
149 NS_IMETHOD GetContentDispositionFilename(
150 nsAString &aContentDispositionFilename) override;
151 NS_IMETHOD SetContentDispositionFilename(
152 const nsAString &aContentDispositionFilename) override;
153 NS_IMETHOD GetContentDispositionHeader(
154 nsACString &aContentDispositionHeader) override;
155 NS_IMETHOD GetContentLength(int64_t *aContentLength) override;
156 NS_IMETHOD SetContentLength(int64_t aContentLength) override;
157 NS_IMETHOD Open(nsIInputStream **aResult) override;
158 NS_IMETHOD Open2(nsIInputStream **aResult) override;
159 NS_IMETHOD GetBlockAuthPrompt(bool *aValue) override;
160 NS_IMETHOD SetBlockAuthPrompt(bool aValue) override;
161
162 // nsIEncodedChannel
163 NS_IMETHOD GetApplyConversion(bool *value) override;
164 NS_IMETHOD SetApplyConversion(bool value) override;
165 NS_IMETHOD GetContentEncodings(nsIUTF8StringEnumerator **aEncodings) override;
166 NS_IMETHOD DoApplyContentConversions(nsIStreamListener *aNextListener,
167 nsIStreamListener **aNewNextListener,
168 nsISupports *aCtxt) override;
169
170 // HttpBaseChannel::nsIHttpChannel
171 NS_IMETHOD GetRequestMethod(nsACString &aMethod) override;
172 NS_IMETHOD SetRequestMethod(const nsACString &aMethod) override;
173 NS_IMETHOD GetReferrer(nsIURI **referrer) override;
174 NS_IMETHOD SetReferrer(nsIURI *referrer) override;
175 NS_IMETHOD GetReferrerPolicy(uint32_t *referrerPolicy) override;
176 NS_IMETHOD SetReferrerWithPolicy(nsIURI *referrer,
177 uint32_t referrerPolicy) override;
178 NS_IMETHOD GetRequestHeader(const nsACString &aHeader,
179 nsACString &aValue) override;
180 NS_IMETHOD SetRequestHeader(const nsACString &aHeader,
181 const nsACString &aValue, bool aMerge) override;
182 NS_IMETHOD SetEmptyRequestHeader(const nsACString &aHeader) override;
183 NS_IMETHOD VisitRequestHeaders(nsIHttpHeaderVisitor *visitor) override;
184 NS_IMETHOD VisitNonDefaultRequestHeaders(
185 nsIHttpHeaderVisitor *visitor) override;
186 NS_IMETHOD GetResponseHeader(const nsACString &header,
187 nsACString &value) override;
188 NS_IMETHOD SetResponseHeader(const nsACString &header,
189 const nsACString &value, bool merge) override;
190 NS_IMETHOD VisitResponseHeaders(nsIHttpHeaderVisitor *visitor) override;
191 NS_IMETHOD GetOriginalResponseHeader(const nsACString &aHeader,
192 nsIHttpHeaderVisitor *aVisitor) override;
193 NS_IMETHOD VisitOriginalResponseHeaders(
194 nsIHttpHeaderVisitor *aVisitor) override;
195 NS_IMETHOD GetAllowPipelining(bool *value) override; // deprecated
196 NS_IMETHOD SetAllowPipelining(bool value) override; // deprecated
197 NS_IMETHOD GetAllowSTS(bool *value) override;
198 NS_IMETHOD SetAllowSTS(bool value) override;
199 NS_IMETHOD GetRedirectionLimit(uint32_t *value) override;
200 NS_IMETHOD SetRedirectionLimit(uint32_t value) override;
201 NS_IMETHOD IsNoStoreResponse(bool *value) override;
202 NS_IMETHOD IsNoCacheResponse(bool *value) override;
203 NS_IMETHOD IsPrivateResponse(bool *value) override;
204 NS_IMETHOD GetResponseStatus(uint32_t *aValue) override;
205 NS_IMETHOD GetResponseStatusText(nsACString &aValue) override;
206 NS_IMETHOD GetRequestSucceeded(bool *aValue) override;
207 NS_IMETHOD RedirectTo(nsIURI *newURI) override;
208 NS_IMETHOD UpgradeToSecure() override;
209 NS_IMETHOD GetRequestContextID(uint64_t *aRCID) override;
210 NS_IMETHOD GetTransferSize(uint64_t *aTransferSize) override;
211 NS_IMETHOD GetDecodedBodySize(uint64_t *aDecodedBodySize) override;
212 NS_IMETHOD GetEncodedBodySize(uint64_t *aEncodedBodySize) override;
213 NS_IMETHOD SetRequestContextID(uint64_t aRCID) override;
214 NS_IMETHOD GetIsMainDocumentChannel(bool *aValue) override;
215 NS_IMETHOD SetIsMainDocumentChannel(bool aValue) override;
216 NS_IMETHOD GetProtocolVersion(nsACString &aProtocolVersion) override;
217 NS_IMETHOD GetChannelId(uint64_t *aChannelId) override;
218 NS_IMETHOD SetChannelId(uint64_t aChannelId) override;
219 NS_IMETHOD GetTopLevelContentWindowId(uint64_t *aContentWindowId) override;
220 NS_IMETHOD SetTopLevelContentWindowId(uint64_t aContentWindowId) override;
221 NS_IMETHOD GetTopLevelOuterContentWindowId(uint64_t *aWindowId) override;
222 NS_IMETHOD SetTopLevelOuterContentWindowId(uint64_t aWindowId) override;
223 NS_IMETHOD GetIsTrackingResource(bool *aIsTrackingResource) override;
224
225 // nsIHttpChannelInternal
226 NS_IMETHOD GetDocumentURI(nsIURI **aDocumentURI) override;
227 NS_IMETHOD SetDocumentURI(nsIURI *aDocumentURI) override;
228 NS_IMETHOD GetRequestVersion(uint32_t *major, uint32_t *minor) override;
229 NS_IMETHOD GetResponseVersion(uint32_t *major, uint32_t *minor) override;
230 NS_IMETHOD SetCookie(const char *aCookieHeader) override;
231 NS_IMETHOD GetThirdPartyFlags(uint32_t *aForce) override;
232 NS_IMETHOD SetThirdPartyFlags(uint32_t aForce) override;
233 NS_IMETHOD GetForceAllowThirdPartyCookie(bool *aForce) override;
234 NS_IMETHOD SetForceAllowThirdPartyCookie(bool aForce) override;
235 NS_IMETHOD GetCanceled(bool *aCanceled) override;
236 NS_IMETHOD GetChannelIsForDownload(bool *aChannelIsForDownload) override;
237 NS_IMETHOD SetChannelIsForDownload(bool aChannelIsForDownload) override;
238 NS_IMETHOD SetCacheKeysRedirectChain(nsTArray<nsCString> *cacheKeys) override;
239 NS_IMETHOD GetLocalAddress(nsACString &addr) override;
240 NS_IMETHOD GetLocalPort(int32_t *port) override;
241 NS_IMETHOD GetRemoteAddress(nsACString &addr) override;
242 NS_IMETHOD GetRemotePort(int32_t *port) override;
243 NS_IMETHOD GetAllowSpdy(bool *aAllowSpdy) override;
244 NS_IMETHOD SetAllowSpdy(bool aAllowSpdy) override;
245 NS_IMETHOD GetAllowAltSvc(bool *aAllowAltSvc) override;
246 NS_IMETHOD SetAllowAltSvc(bool aAllowAltSvc) override;
247 NS_IMETHOD GetBeConservative(bool *aBeConservative) override;
248 NS_IMETHOD SetBeConservative(bool aBeConservative) override;
249 NS_IMETHOD GetTrr(bool *aTRR) override;
250 NS_IMETHOD SetTrr(bool aTRR) override;
251 NS_IMETHOD GetTlsFlags(uint32_t *aTlsFlags) override;
252 NS_IMETHOD SetTlsFlags(uint32_t aTlsFlags) override;
253 NS_IMETHOD GetApiRedirectToURI(nsIURI **aApiRedirectToURI) override;
254 virtual MOZ_MUST_USE nsresult AddSecurityMessage(
255 const nsAString &aMessageTag, const nsAString &aMessageCategory);
256 NS_IMETHOD TakeAllSecurityMessages(
257 nsCOMArray<nsISecurityConsoleMessage> &aMessages) override;
258 NS_IMETHOD GetResponseTimeoutEnabled(bool *aEnable) override;
259 NS_IMETHOD SetResponseTimeoutEnabled(bool aEnable) override;
260 NS_IMETHOD GetInitialRwin(uint32_t *aRwin) override;
261 NS_IMETHOD SetInitialRwin(uint32_t aRwin) override;
262 NS_IMETHOD GetNetworkInterfaceId(nsACString &aNetworkInterfaceId) override;
263 NS_IMETHOD SetNetworkInterfaceId(
264 const nsACString &aNetworkInterfaceId) override;
265 NS_IMETHOD ForcePending(bool aForcePending) override;
266 NS_IMETHOD GetLastModifiedTime(PRTime *lastModifiedTime) override;
267 NS_IMETHOD GetCorsIncludeCredentials(bool *aInclude) override;
268 NS_IMETHOD SetCorsIncludeCredentials(bool aInclude) override;
269 NS_IMETHOD GetCorsMode(uint32_t *aCorsMode) override;
270 NS_IMETHOD SetCorsMode(uint32_t aCorsMode) override;
271 NS_IMETHOD GetRedirectMode(uint32_t *aRedirectMode) override;
272 NS_IMETHOD SetRedirectMode(uint32_t aRedirectMode) override;
273 NS_IMETHOD GetFetchCacheMode(uint32_t *aFetchCacheMode) override;
274 NS_IMETHOD SetFetchCacheMode(uint32_t aFetchCacheMode) override;
275 NS_IMETHOD GetTopWindowURI(nsIURI **aTopWindowURI) override;
276 NS_IMETHOD SetTopWindowURIIfUnknown(nsIURI *aTopWindowURI) override;
277 NS_IMETHOD GetProxyURI(nsIURI **proxyURI) override;
278 virtual void SetCorsPreflightParameters(
279 const nsTArray<nsCString> &unsafeHeaders) override;
280 virtual void SetAltDataForChild(bool aIsForChild) override;
281 NS_IMETHOD GetConnectionInfoHashKey(
282 nsACString &aConnectionInfoHashKey) override;
283 NS_IMETHOD GetIntegrityMetadata(nsAString &aIntegrityMetadata) override;
284 NS_IMETHOD SetIntegrityMetadata(const nsAString &aIntegrityMetadata) override;
285 NS_IMETHOD GetLastRedirectFlags(uint32_t *aValue) override;
286 NS_IMETHOD SetLastRedirectFlags(uint32_t aValue) override;
287
CleanRedirectCacheChainIfNecessary()288 inline void CleanRedirectCacheChainIfNecessary() {
289 mRedirectedCachekeys = nullptr;
290 }
291 NS_IMETHOD HTTPUpgrade(const nsACString &aProtocolName,
292 nsIHttpUpgradeListener *aListener) override;
293
294 // nsISupportsPriority
295 NS_IMETHOD GetPriority(int32_t *value) override;
296 NS_IMETHOD AdjustPriority(int32_t delta) override;
297
298 // nsIClassOfService
GetClassFlags(uint32_t * outFlags)299 NS_IMETHOD GetClassFlags(uint32_t *outFlags) override {
300 *outFlags = mClassOfService;
301 return NS_OK;
302 }
303
304 // nsIResumableChannel
305 NS_IMETHOD GetEntityID(nsACString &aEntityID) override;
306
307 // nsIConsoleReportCollector
308 void AddConsoleReport(uint32_t aErrorFlags, const nsACString &aCategory,
309 nsContentUtils::PropertiesFile aPropertiesFile,
310 const nsACString &aSourceFileURI, uint32_t aLineNumber,
311 uint32_t aColumnNumber, const nsACString &aMessageName,
312 const nsTArray<nsString> &aStringParams) override;
313
314 void FlushReportsToConsole(
315 uint64_t aInnerWindowID,
316 ReportAction aAction = ReportAction::Forget) override;
317
318 void FlushReportsToConsoleForServiceWorkerScope(
319 const nsACString &aScope,
320 ReportAction aAction = ReportAction::Forget) override;
321
322 void FlushConsoleReports(
323 nsIDocument *aDocument,
324 ReportAction aAction = ReportAction::Forget) override;
325
326 void FlushConsoleReports(
327 nsILoadGroup *aLoadGroup,
328 ReportAction aAction = ReportAction::Forget) override;
329
330 void FlushConsoleReports(nsIConsoleReportCollector *aCollector) override;
331
332 void ClearConsoleReports() override;
333
334 class nsContentEncodings : public nsIUTF8StringEnumerator {
335 public:
336 NS_DECL_ISUPPORTS
337 NS_DECL_NSIUTF8STRINGENUMERATOR
338
339 nsContentEncodings(nsIHttpChannel *aChannel, const char *aEncodingHeader);
340
341 private:
342 virtual ~nsContentEncodings();
343
344 MOZ_MUST_USE nsresult PrepareForNext(void);
345
346 // We do not own the buffer. The channel owns it.
347 const char *mEncodingHeader;
348 const char *mCurStart; // points to start of current header
349 const char *mCurEnd; // points to end of current header
350
351 // Hold a ref to our channel so that it can't go away and take the
352 // header with it.
353 nsCOMPtr<nsIHttpChannel> mChannel;
354
355 bool mReady;
356 };
357
GetResponseHead()358 nsHttpResponseHead *GetResponseHead() const { return mResponseHead; }
GetRequestHead()359 nsHttpRequestHead *GetRequestHead() { return &mRequestHead; }
GetResponseTrailers()360 nsHttpHeaderArray *GetResponseTrailers() const { return mResponseTrailers; }
361
GetSelfAddr()362 const NetAddr &GetSelfAddr() { return mSelfAddr; }
GetPeerAddr()363 const NetAddr &GetPeerAddr() { return mPeerAddr; }
364
365 MOZ_MUST_USE nsresult OverrideSecurityInfo(nsISupports *aSecurityInfo);
366
367 public: /* Necko internal use only... */
GetAltDataLength()368 int64_t GetAltDataLength() { return mAltDataLength; }
369 bool IsNavigation();
370
371 static bool IsReferrerSchemeAllowed(nsIURI *aReferrer);
372
373 static void PropagateReferenceIfNeeded(nsIURI *aURI,
374 nsCOMPtr<nsIURI> &aRedirectURI);
375
376 // Return whether upon a redirect code of httpStatus for method, the
377 // request method should be rewritten to GET.
378 static bool ShouldRewriteRedirectToGET(
379 uint32_t httpStatus, nsHttpRequestHead::ParsedMethodType method);
380
381 // Like nsIEncodedChannel::DoApplyConversions except context is set to
382 // mListenerContext.
383 MOZ_MUST_USE nsresult DoApplyContentConversions(
384 nsIStreamListener *aNextListener, nsIStreamListener **aNewNextListener);
385
386 // Callback on STS thread called by CopyComplete when NS_AsyncCopy()
387 // is finished. This function works as a proxy function to dispatch
388 // |EnsureUploadStreamIsCloneableComplete| to main thread.
389 virtual void OnCopyComplete(nsresult aStatus);
390
391 void SetIsTrackingResource();
392
ChannelId()393 const uint64_t &ChannelId() const { return mChannelId; }
394
InternalSetUploadStream(nsIInputStream * uploadStream)395 void InternalSetUploadStream(nsIInputStream *uploadStream) {
396 mUploadStream = uploadStream;
397 }
398
SetUploadStreamHasHeaders(bool hasHeaders)399 void SetUploadStreamHasHeaders(bool hasHeaders) {
400 mUploadStreamHasHeaders = hasHeaders;
401 }
402
SetReferrerWithPolicyInternal(nsIURI * referrer,uint32_t referrerPolicy)403 MOZ_MUST_USE nsresult SetReferrerWithPolicyInternal(nsIURI *referrer,
404 uint32_t referrerPolicy) {
405 nsAutoCString spec;
406 nsresult rv = referrer->GetAsciiSpec(spec);
407 if (NS_FAILED(rv)) {
408 return rv;
409 }
410 mReferrer = referrer;
411 mReferrerPolicy = referrerPolicy;
412 rv = mRequestHead.SetHeader(nsHttp::Referer, spec);
413 return rv;
414 }
415
SetTopWindowURI(nsIURI * aTopWindowURI)416 MOZ_MUST_USE nsresult SetTopWindowURI(nsIURI *aTopWindowURI) {
417 mTopWindowURI = aTopWindowURI;
418 return NS_OK;
419 }
420
421 protected:
422 // Handle notifying listener, removing from loadgroup if request failed.
423 void DoNotifyListener();
424 virtual void DoNotifyListenerCleanup() = 0;
425
426 // drop reference to listener, its callbacks, and the progress sink
427 virtual void ReleaseListeners();
428
429 // This is fired only when a cookie is created due to the presence of
430 // Set-Cookie header in the response header of any network request.
431 // This notification will come only after the "http-on-examine-response"
432 // was fired.
433 void NotifySetCookie(char const *aCookie);
434
435 mozilla::dom::PerformanceStorage *GetPerformanceStorage();
436 nsIURI *GetReferringPage();
437 nsPIDOMWindowInner *GetInnerDOMWindow();
438
439 void AddCookiesToRequest();
440 virtual MOZ_MUST_USE nsresult SetupReplacementChannel(nsIURI *, nsIChannel *,
441 bool preserveMethod,
442 uint32_t redirectFlags);
443
444 // bundle calling OMR observers and marking flag into one function
CallOnModifyRequestObservers()445 inline void CallOnModifyRequestObservers() {
446 gHttpHandler->OnModifyRequest(this);
447 mRequestObserversCalled = true;
448 }
449
450 // Helper function to simplify getting notification callbacks.
451 template <class T>
GetCallback(nsCOMPtr<T> & aResult)452 void GetCallback(nsCOMPtr<T> &aResult) {
453 NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
454 NS_GET_TEMPLATE_IID(T),
455 getter_AddRefs(aResult));
456 }
457
458 // Redirect tracking
459 // Checks whether or not aURI and mOriginalURI share the same domain.
460 bool SameOriginWithOriginalUri(nsIURI *aURI);
461
462 // GetPrincipal Returns the channel's URI principal.
463 nsIPrincipal *GetURIPrincipal();
464
465 MOZ_MUST_USE bool BypassServiceWorker() const;
466
467 // Returns true if this channel should intercept the network request and
468 // prepare for a possible synthesized response instead.
469 bool ShouldIntercept(nsIURI *aURI = nullptr);
470
471 // Callback on main thread when NS_AsyncCopy() is finished populating
472 // the new mUploadStream.
473 void EnsureUploadStreamIsCloneableComplete(nsresult aStatus);
474
475 #ifdef DEBUG
476 // Check if mPrivateBrowsingId matches between LoadInfo and LoadContext.
477 void AssertPrivateBrowsingId();
478 #endif
479
480 // Called before we create the redirect target channel.
481 already_AddRefed<nsILoadInfo> CloneLoadInfoForRedirect(
482 nsIURI *newURI, uint32_t redirectFlags);
483
484 static void CallTypeSniffers(void *aClosure, const uint8_t *aData,
485 uint32_t aCount);
486
487 nsresult CheckRedirectLimit(uint32_t aRedirectFlags) const;
488
489 friend class PrivateBrowsingChannel<HttpBaseChannel>;
490 friend class InterceptFailedOnStop;
491
492 protected:
493 // this section is for main-thread-only object
494 // all the references need to be proxy released on main thread.
495 nsCOMPtr<nsIURI> mURI;
496 nsCOMPtr<nsIURI> mOriginalURI;
497 nsCOMPtr<nsIURI> mDocumentURI;
498 nsCOMPtr<nsILoadGroup> mLoadGroup;
499 nsCOMPtr<nsILoadInfo> mLoadInfo;
500 nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
501 nsCOMPtr<nsIProgressEventSink> mProgressSink;
502 nsCOMPtr<nsIURI> mReferrer;
503 nsCOMPtr<nsIApplicationCache> mApplicationCache;
504 nsCOMPtr<nsIURI> mAPIRedirectToURI;
505 nsCOMPtr<nsIURI> mProxyURI;
506 nsCOMPtr<nsIPrincipal> mPrincipal;
507 nsCOMPtr<nsIURI> mTopWindowURI;
508 nsCOMPtr<nsIStreamListener> mListener;
509 nsCOMPtr<nsISupports> mListenerContext;
510 // An instance of nsHTTPCompressConv
511 nsCOMPtr<nsIStreamListener> mCompressListener;
512
513 private:
514 // Proxy release all members above on main thread.
515 void ReleaseMainThreadOnlyReferences();
516
517 bool IsCrossOriginWithReferrer();
518
519 protected:
520 // Use Release-Acquire ordering to ensure the OMT ODA is ignored while channel
521 // is canceled on main thread.
522 Atomic<bool, ReleaseAcquire> mCanceled;
523
524 nsTArray<Pair<nsString, nsString>> mSecurityConsoleMessages;
525
526 nsCOMPtr<nsISupports> mOwner;
527
528 nsHttpRequestHead mRequestHead;
529 // Upload throttling.
530 nsCOMPtr<nsIInputChannelThrottleQueue> mThrottleQueue;
531 nsCOMPtr<nsIInputStream> mUploadStream;
532 nsCOMPtr<nsIRunnable> mUploadCloneableCallback;
533 nsAutoPtr<nsHttpResponseHead> mResponseHead;
534 nsAutoPtr<nsHttpHeaderArray> mResponseTrailers;
535 RefPtr<nsHttpConnectionInfo> mConnectionInfo;
536 nsCOMPtr<nsIProxyInfo> mProxyInfo;
537 nsCOMPtr<nsISupports> mSecurityInfo;
538
539 nsCString mSpec; // ASCII encoded URL spec
540 nsCString mContentTypeHint;
541 nsCString mContentCharsetHint;
542 nsCString mUserSetCookieHeader;
543
544 NetAddr mSelfAddr;
545 NetAddr mPeerAddr;
546
547 // HTTP Upgrade Data
548 nsCString mUpgradeProtocol;
549 nsCOMPtr<nsIHttpUpgradeListener> mUpgradeProtocolCallback;
550
551 // Resumable channel specific data
552 nsCString mEntityID;
553 uint64_t mStartPos;
554
555 Atomic<nsresult, ReleaseAcquire> mStatus;
556 uint32_t mLoadFlags;
557 uint32_t mCaps;
558 uint32_t mClassOfService;
559 int16_t mPriority;
560 uint8_t mRedirectionLimit;
561
562 uint32_t mUpgradeToSecure : 1;
563 uint32_t mApplyConversion : 1;
564 uint32_t mIsPending : 1;
565 uint32_t mWasOpened : 1;
566 // if 1 all "http-on-{opening|modify|etc}-request" observers have been called
567 uint32_t mRequestObserversCalled : 1;
568 uint32_t mResponseHeadersModified : 1;
569 uint32_t mAllowSTS : 1;
570 uint32_t mThirdPartyFlags : 3;
571 uint32_t mUploadStreamHasHeaders : 1;
572 uint32_t mInheritApplicationCache : 1;
573 uint32_t mChooseApplicationCache : 1;
574 uint32_t mLoadedFromApplicationCache : 1;
575 uint32_t mChannelIsForDownload : 1;
576 uint32_t mTracingEnabled : 1;
577 // True if timing collection is enabled
578 uint32_t mTimingEnabled : 1;
579 uint32_t mReportTiming : 1;
580 uint32_t mAllowSpdy : 1;
581 uint32_t mAllowAltSvc : 1;
582 uint32_t mBeConservative : 1;
583 uint32_t mTRR : 1;
584 uint32_t mResponseTimeoutEnabled : 1;
585 // A flag that should be false only if a cross-domain redirect occurred
586 uint32_t mAllRedirectsSameOrigin : 1;
587
588 // Is 1 if no redirects have occured or if all redirects
589 // pass the Resource Timing timing-allow-check
590 uint32_t mAllRedirectsPassTimingAllowCheck : 1;
591
592 // True if this channel was intercepted and could receive a synthesized
593 // response.
594 uint32_t mResponseCouldBeSynthesized : 1;
595
596 uint32_t mBlockAuthPrompt : 1;
597
598 // If true, we behave as if the LOAD_FROM_CACHE flag has been set.
599 // Used to enforce that flag's behavior but not expose it externally.
600 uint32_t mAllowStaleCacheContent : 1;
601
602 // True iff this request has been calculated in its request context as
603 // a non tail request. We must remove it again when this channel is done.
604 uint32_t mAddedAsNonTailRequest : 1;
605
606 // An opaque flags for non-standard behavior of the TLS system.
607 // It is unlikely this will need to be set outside of telemetry studies
608 // relating to the TLS implementation.
609 uint32_t mTlsFlags;
610
611 // Current suspension depth for this channel object
612 uint32_t mSuspendCount;
613
614 // Per channel transport window override (0 means no override)
615 uint32_t mInitialRwin;
616
617 nsAutoPtr<nsTArray<nsCString>> mRedirectedCachekeys;
618
619 uint32_t mProxyResolveFlags;
620
621 uint32_t mContentDispositionHint;
622 nsAutoPtr<nsString> mContentDispositionFilename;
623
624 RefPtr<nsHttpHandler> mHttpHandler; // keep gHttpHandler alive
625
626 uint32_t mReferrerPolicy;
627
628 // Performance tracking
629 // The initiator type (for this resource) - how was the resource referenced in
630 // the HTML file.
631 nsString mInitiatorType;
632 // Number of redirects that has occurred.
633 int8_t mRedirectCount;
634 // Number of internal redirects that has occurred.
635 int8_t mInternalRedirectCount;
636 // A time value equal to the starting time of the fetch that initiates the
637 // redirect.
638 mozilla::TimeStamp mRedirectStartTimeStamp;
639 // A time value equal to the time immediately after receiving the last byte of
640 // the response of the last redirect.
641 mozilla::TimeStamp mRedirectEndTimeStamp;
642
643 PRTime mChannelCreationTime;
644 TimeStamp mChannelCreationTimestamp;
645 TimeStamp mAsyncOpenTime;
646 TimeStamp mCacheReadStart;
647 TimeStamp mCacheReadEnd;
648 TimeStamp mLaunchServiceWorkerStart;
649 TimeStamp mLaunchServiceWorkerEnd;
650 TimeStamp mDispatchFetchEventStart;
651 TimeStamp mDispatchFetchEventEnd;
652 TimeStamp mHandleFetchEventStart;
653 TimeStamp mHandleFetchEventEnd;
654 // copied from the transaction before we null out mTransaction
655 // so that the timing can still be queried from OnStopRequest
656 TimingStruct mTransactionTimings;
657
658 bool mForcePending;
659
660 bool mCorsIncludeCredentials;
661 uint32_t mCorsMode;
662 uint32_t mRedirectMode;
663
664 // These parameters are used to ensure that we do not call OnStartRequest and
665 // OnStopRequest more than once.
666 bool mOnStartRequestCalled;
667 bool mOnStopRequestCalled;
668
669 // Defaults to true. This is set to false when it is no longer possible
670 // to upgrade the request to a secure channel.
671 uint32_t mUpgradableToSecure : 1;
672
673 // Defaults to false. Is set to true at the begining of OnStartRequest.
674 // Used to ensure methods can't be called before OnStartRequest.
675 bool mAfterOnStartRequestBegun;
676
677 uint64_t mTransferSize;
678 uint64_t mDecodedBodySize;
679 uint64_t mEncodedBodySize;
680
681 // The network interface id that's associated with this channel.
682 nsCString mNetworkInterfaceId;
683
684 uint64_t mRequestContextID;
685 bool EnsureRequestContextID();
686 nsCOMPtr<nsIRequestContext> mRequestContext;
687 bool EnsureRequestContext();
688
689 // Adds/removes this channel as a non-tailed request in its request context
690 // these helpers ensure we add it only once and remove it only when added
691 // via mAddedAsNonTailRequest member tracking.
692 void AddAsNonTailRequest();
693 void RemoveAsNonTailRequest();
694
695 // ID of the top-level document's inner window this channel is being
696 // originated from.
697 uint64_t mContentWindowId;
698
699 uint64_t mTopLevelOuterContentWindowId;
700 void EnsureTopLevelOuterContentWindowId();
701
702 bool mRequireCORSPreflight;
703 nsTArray<nsCString> mUnsafeHeaders;
704
705 nsCOMPtr<nsIConsoleReportCollector> mReportCollector;
706
707 // Holds the name of the preferred alt-data type.
708 nsCString mPreferredCachedAltDataType;
709 // Holds the name of the alternative data type the channel returned.
710 nsCString mAvailableCachedAltDataType;
711 int64_t mAltDataLength;
712 // This flag will be true if the consumer is requesting alt-data AND the
713 // consumer is in the child process.
714 bool mAltDataForChild;
715
716 bool mForceMainDocumentChannel;
717 Atomic<bool, ReleaseAcquire> mIsTrackingResource;
718
719 uint64_t mChannelId;
720
721 // If this channel was created as the result of a redirect, then this value
722 // will reflect the redirect flags passed to the SetupReplacementChannel()
723 // method.
724 uint32_t mLastRedirectFlags;
725
726 uint64_t mReqContentLength;
727 bool mReqContentLengthDetermined;
728
729 nsString mIntegrityMetadata;
730
731 // Classified channel's matched information
732 nsCString mMatchedList;
733 nsCString mMatchedProvider;
734 nsCString mMatchedFullHash;
735 };
736
NS_DEFINE_STATIC_IID_ACCESSOR(HttpBaseChannel,HTTP_BASE_CHANNEL_IID)737 NS_DEFINE_STATIC_IID_ACCESSOR(HttpBaseChannel, HTTP_BASE_CHANNEL_IID)
738
739 // Share some code while working around C++'s absurd inability to handle casting
740 // of member functions between base/derived types.
741 // - We want to store member function pointer to call at resume time, but one
742 // such function--HandleAsyncAbort--we want to share between the
743 // nsHttpChannel/HttpChannelChild. Can't define it in base class, because
744 // then we'd have to cast member function ptr between base/derived class
745 // types. Sigh...
746 template <class T>
747 class HttpAsyncAborter {
748 public:
749 explicit HttpAsyncAborter(T *derived) : mThis(derived), mCallOnResume(0) {}
750
751 // Aborts channel: calls OnStart/Stop with provided status, removes channel
752 // from loadGroup.
753 MOZ_MUST_USE nsresult AsyncAbort(nsresult status);
754
755 // Does most the actual work.
756 void HandleAsyncAbort();
757
758 // AsyncCall calls a member function asynchronously (via an event).
759 // retval isn't refcounted and is set only when event was successfully
760 // posted, the event is returned for the purpose of cancelling when needed
761 MOZ_MUST_USE virtual nsresult AsyncCall(
762 void (T::*funcPtr)(), nsRunnableMethod<T> **retval = nullptr);
763
764 private:
765 T *mThis;
766
767 protected:
768 // Function to be called at resume time
769 void (T::*mCallOnResume)(void);
770 };
771
772 template <class T>
AsyncAbort(nsresult status)773 MOZ_MUST_USE nsresult HttpAsyncAborter<T>::AsyncAbort(nsresult status) {
774 MOZ_LOG(gHttpLog, LogLevel::Debug,
775 ("HttpAsyncAborter::AsyncAbort [this=%p status=%" PRIx32 "]\n", mThis,
776 static_cast<uint32_t>(status)));
777
778 mThis->mStatus = status;
779
780 // if this fails? Callers ignore our return value anyway....
781 return AsyncCall(&T::HandleAsyncAbort);
782 }
783
784 // Each subclass needs to define its own version of this (which just calls this
785 // base version), else we wind up casting base/derived member function ptrs
786 template <class T>
HandleAsyncAbort()787 inline void HttpAsyncAborter<T>::HandleAsyncAbort() {
788 NS_PRECONDITION(!mCallOnResume, "How did that happen?");
789
790 if (mThis->mSuspendCount) {
791 MOZ_LOG(
792 gHttpLog, LogLevel::Debug,
793 ("Waiting until resume to do async notification [this=%p]\n", mThis));
794 mCallOnResume = &T::HandleAsyncAbort;
795 return;
796 }
797
798 mThis->DoNotifyListener();
799
800 // finally remove ourselves from the load group.
801 if (mThis->mLoadGroup)
802 mThis->mLoadGroup->RemoveRequest(mThis, nullptr, mThis->mStatus);
803 }
804
805 template <class T>
AsyncCall(void (T::* funcPtr)(),nsRunnableMethod<T> ** retval)806 nsresult HttpAsyncAborter<T>::AsyncCall(void (T::*funcPtr)(),
807 nsRunnableMethod<T> **retval) {
808 nsresult rv;
809
810 RefPtr<nsRunnableMethod<T>> event =
811 NewRunnableMethod("net::HttpAsyncAborter::AsyncCall", mThis, funcPtr);
812 rv = NS_DispatchToCurrentThread(event);
813 if (NS_SUCCEEDED(rv) && retval) {
814 *retval = event;
815 }
816
817 return rv;
818 }
819
820 class ProxyReleaseRunnable final : public mozilla::Runnable {
821 public:
ProxyReleaseRunnable(nsTArray<nsCOMPtr<nsISupports>> && aDoomed)822 explicit ProxyReleaseRunnable(nsTArray<nsCOMPtr<nsISupports>> &&aDoomed)
823 : Runnable("ProxyReleaseRunnable"), mDoomed(Move(aDoomed)) {}
824
825 NS_IMETHOD
Run()826 Run() override {
827 mDoomed.Clear();
828 return NS_OK;
829 }
830
831 private:
~ProxyReleaseRunnable()832 virtual ~ProxyReleaseRunnable() {}
833
834 nsTArray<nsCOMPtr<nsISupports>> mDoomed;
835 };
836
837 } // namespace net
838 } // namespace mozilla
839
840 #endif // mozilla_net_HttpBaseChannel_h
841