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