netwerk/protocol/http/nsHttpChannel.h

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* vim:set et cin ts=4 sw=4 sts=4: */
     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/. */
     7 #ifndef nsHttpChannel_h__
     8 #define nsHttpChannel_h__
    10 #include "HttpBaseChannel.h"
    11 #include "nsTArray.h"
    12 #include "nsICachingChannel.h"
    13 #include "nsICacheEntry.h"
    14 #include "nsICacheEntryOpenCallback.h"
    15 #include "nsIDNSListener.h"
    16 #include "nsIApplicationCacheChannel.h"
    17 #include "nsIProtocolProxyCallback.h"
    18 #include "nsIHttpAuthenticableChannel.h"
    19 #include "nsIAsyncVerifyRedirectCallback.h"
    20 #include "nsIThreadRetargetableRequest.h"
    21 #include "nsIThreadRetargetableStreamListener.h"
    22 #include "nsWeakReference.h"
    23 #include "TimingStruct.h"
    24 #include "AutoClose.h"
    26 class nsIPrincipal;
    27 class nsDNSPrefetch;
    28 class nsICacheEntryDescriptor;
    29 class nsICancelable;
    30 class nsIHttpChannelAuthProvider;
    31 class nsInputStreamPump;
    32 class nsPerformance;
    34 namespace mozilla { namespace net {
    36 //-----------------------------------------------------------------------------
    37 // nsHttpChannel
    38 //-----------------------------------------------------------------------------
    40 class nsHttpChannel : public HttpBaseChannel
    41                     , public HttpAsyncAborter<nsHttpChannel>
    42                     , public nsIStreamListener
    43                     , public nsICachingChannel
    44                     , public nsICacheEntryOpenCallback
    45                     , public nsITransportEventSink
    46                     , public nsIProtocolProxyCallback
    47                     , public nsIHttpAuthenticableChannel
    48                     , public nsIApplicationCacheChannel
    49                     , public nsIAsyncVerifyRedirectCallback
    50                     , public nsIThreadRetargetableRequest
    51                     , public nsIThreadRetargetableStreamListener
    52                     , public nsIDNSListener
    53                     , public nsSupportsWeakReference
    54 {
    55 public:
    56     NS_DECL_ISUPPORTS_INHERITED
    57     NS_DECL_NSIREQUESTOBSERVER
    58     NS_DECL_NSISTREAMLISTENER
    59     NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
    60     NS_DECL_NSICACHEINFOCHANNEL
    61     NS_DECL_NSICACHINGCHANNEL
    62     NS_DECL_NSICACHEENTRYOPENCALLBACK
    63     NS_DECL_NSITRANSPORTEVENTSINK
    64     NS_DECL_NSIPROTOCOLPROXYCALLBACK
    65     NS_DECL_NSIPROXIEDCHANNEL
    66     NS_DECL_NSIAPPLICATIONCACHECONTAINER
    67     NS_DECL_NSIAPPLICATIONCACHECHANNEL
    68     NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
    69     NS_DECL_NSITHREADRETARGETABLEREQUEST
    70     NS_DECL_NSIDNSLISTENER
    72     // nsIHttpAuthenticableChannel. We can't use
    73     // NS_DECL_NSIHTTPAUTHENTICABLECHANNEL because it duplicates cancel() and
    74     // others.
    75     NS_IMETHOD GetIsSSL(bool *aIsSSL);
    76     NS_IMETHOD GetProxyMethodIsConnect(bool *aProxyMethodIsConnect);
    77     NS_IMETHOD GetServerResponseHeader(nsACString & aServerResponseHeader);
    78     NS_IMETHOD GetProxyChallenges(nsACString & aChallenges);
    79     NS_IMETHOD GetWWWChallenges(nsACString & aChallenges);
    80     NS_IMETHOD SetProxyCredentials(const nsACString & aCredentials);
    81     NS_IMETHOD SetWWWCredentials(const nsACString & aCredentials);
    82     NS_IMETHOD OnAuthAvailable();
    83     NS_IMETHOD OnAuthCancelled(bool userCancel);
    84     // Functions we implement from nsIHttpAuthenticableChannel but are
    85     // declared in HttpBaseChannel must be implemented in this class. We
    86     // just call the HttpBaseChannel:: impls.
    87     NS_IMETHOD GetLoadFlags(nsLoadFlags *aLoadFlags);
    88     NS_IMETHOD GetURI(nsIURI **aURI);
    89     NS_IMETHOD GetNotificationCallbacks(nsIInterfaceRequestor **aCallbacks);
    90     NS_IMETHOD GetLoadGroup(nsILoadGroup **aLoadGroup);
    91     NS_IMETHOD GetRequestMethod(nsACString& aMethod);
    93     nsHttpChannel();
    94     virtual ~nsHttpChannel();
    96     virtual nsresult Init(nsIURI *aURI, uint32_t aCaps, nsProxyInfo *aProxyInfo,
    97                           uint32_t aProxyResolveFlags,
    98                           nsIURI *aProxyURI);
   100     // Methods HttpBaseChannel didn't implement for us or that we override.
   101     //
   102     // nsIRequest
   103     NS_IMETHOD Cancel(nsresult status);
   104     NS_IMETHOD Suspend();
   105     NS_IMETHOD Resume();
   106     NS_IMETHOD IsPending(bool *aIsPending);
   107     // nsIChannel
   108     NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo);
   109     NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext);
   110     // nsIHttpChannelInternal
   111     NS_IMETHOD SetupFallbackChannel(const char *aFallbackKey);
   112     // nsISupportsPriority
   113     NS_IMETHOD SetPriority(int32_t value);
   114     // nsIResumableChannel
   115     NS_IMETHOD ResumeAt(uint64_t startPos, const nsACString& entityID);
   117     NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks);
   118     NS_IMETHOD SetLoadGroup(nsILoadGroup *aLoadGroup);
   119     // nsITimedChannel
   120     NS_IMETHOD GetDomainLookupStart(mozilla::TimeStamp *aDomainLookupStart);
   121     NS_IMETHOD GetDomainLookupEnd(mozilla::TimeStamp *aDomainLookupEnd);
   122     NS_IMETHOD GetConnectStart(mozilla::TimeStamp *aConnectStart);
   123     NS_IMETHOD GetConnectEnd(mozilla::TimeStamp *aConnectEnd);
   124     NS_IMETHOD GetRequestStart(mozilla::TimeStamp *aRequestStart);
   125     NS_IMETHOD GetResponseStart(mozilla::TimeStamp *aResponseStart);
   126     NS_IMETHOD GetResponseEnd(mozilla::TimeStamp *aResponseEnd);
   128 public: /* internal necko use only */
   130     void InternalSetUploadStream(nsIInputStream *uploadStream)
   131       { mUploadStream = uploadStream; }
   132     void SetUploadStreamHasHeaders(bool hasHeaders)
   133       { mUploadStreamHasHeaders = hasHeaders; }
   135     nsresult SetReferrerInternal(nsIURI *referrer) {
   136         nsAutoCString spec;
   137         nsresult rv = referrer->GetAsciiSpec(spec);
   138         if (NS_FAILED(rv)) return rv;
   139         mReferrer = referrer;
   140         mRequestHead.SetHeader(nsHttp::Referer, spec);
   141         return NS_OK;
   142     }
   144     // This allows cache entry to be marked as foreign even after channel itself
   145     // is gone.  Needed for e10s (see HttpChannelParent::RecvDocumentChannelCleanup)
   146     class OfflineCacheEntryAsForeignMarker {
   147         nsCOMPtr<nsIApplicationCache> mApplicationCache;
   148         nsCOMPtr<nsIURI> mCacheURI;
   149     public:
   150         OfflineCacheEntryAsForeignMarker(nsIApplicationCache* appCache,
   151                                          nsIURI* aURI)
   152              : mApplicationCache(appCache)
   153              , mCacheURI(aURI)
   154         {}
   156         nsresult MarkAsForeign();
   157     };
   159     OfflineCacheEntryAsForeignMarker* GetOfflineCacheEntryAsForeignMarker();
   161     // Helper to keep cache callbacks wait flags consistent
   162     class AutoCacheWaitFlags
   163     {
   164     public:
   165       AutoCacheWaitFlags(nsHttpChannel* channel)
   166         : mChannel(channel)
   167         , mKeep(0)
   168       {
   169         // Flags must be set before entering any AsyncOpenCacheEntry call.
   170         mChannel->mCacheEntriesToWaitFor =
   171           nsHttpChannel::WAIT_FOR_CACHE_ENTRY |
   172           nsHttpChannel::WAIT_FOR_OFFLINE_CACHE_ENTRY;
   173       }
   175       void Keep(uint32_t flags)
   176       {
   177         // Called after successful call to appropriate AsyncOpenCacheEntry call.
   178         mKeep |= flags;
   179       }
   181       ~AutoCacheWaitFlags()
   182       {
   183         // Keep only flags those are left to be wait for.
   184         mChannel->mCacheEntriesToWaitFor &= mKeep;
   185       }
   187     private:
   188       nsHttpChannel* mChannel;
   189       uint32_t mKeep : 2;
   190     };
   192     void ForcePending(bool aForcePending);
   194 private:
   195     typedef nsresult (nsHttpChannel::*nsContinueRedirectionFunc)(nsresult result);
   197     bool     RequestIsConditional();
   198     nsresult BeginConnect();
   199     nsresult Connect();
   200     nsresult ContinueConnect();
   201     void     SpeculativeConnect();
   202     nsresult SetupTransaction();
   203     void     SetupTransactionLoadGroupInfo();
   204     nsresult CallOnStartRequest();
   205     nsresult ProcessResponse();
   206     nsresult ContinueProcessResponse(nsresult);
   207     nsresult ProcessNormal();
   208     nsresult ContinueProcessNormal(nsresult);
   209     nsresult ProcessNotModified();
   210     nsresult AsyncProcessRedirection(uint32_t httpStatus);
   211     nsresult ContinueProcessRedirection(nsresult);
   212     nsresult ContinueProcessRedirectionAfterFallback(nsresult);
   213     nsresult ProcessFailedProxyConnect(uint32_t httpStatus);
   214     nsresult ProcessFallback(bool *waitingForRedirectCallback);
   215     nsresult ContinueProcessFallback(nsresult);
   216     void     HandleAsyncAbort();
   217     nsresult EnsureAssocReq();
   218     void     ProcessSSLInformation();
   219     bool     IsHTTPS();
   220     void     RetrieveSSLOptions();
   222     nsresult ContinueOnStartRequest1(nsresult);
   223     nsresult ContinueOnStartRequest2(nsresult);
   224     nsresult ContinueOnStartRequest3(nsresult);
   226     // redirection specific methods
   227     void     HandleAsyncRedirect();
   228     void     HandleAsyncAPIRedirect();
   229     nsresult ContinueHandleAsyncRedirect(nsresult);
   230     void     HandleAsyncNotModified();
   231     void     HandleAsyncFallback();
   232     nsresult ContinueHandleAsyncFallback(nsresult);
   233     nsresult PromptTempRedirect();
   234     nsresult StartRedirectChannelToURI(nsIURI *, uint32_t);
   235     virtual  nsresult SetupReplacementChannel(nsIURI *, nsIChannel *, bool preserveMethod);
   237     // proxy specific methods
   238     nsresult ProxyFailover();
   239     nsresult AsyncDoReplaceWithProxy(nsIProxyInfo *);
   240     nsresult ContinueDoReplaceWithProxy(nsresult);
   241     nsresult ResolveProxy();
   243     // cache specific methods
   244     nsresult OpenCacheEntry(bool usingSSL);
   245     nsresult OnOfflineCacheEntryAvailable(nsICacheEntry *aEntry,
   246                                           bool aNew,
   247                                           nsIApplicationCache* aAppCache,
   248                                           nsresult aResult);
   249     nsresult OnNormalCacheEntryAvailable(nsICacheEntry *aEntry,
   250                                          bool aNew,
   251                                          nsresult aResult);
   252     nsresult OpenOfflineCacheEntryForWriting();
   253     nsresult OnOfflineCacheEntryForWritingAvailable(nsICacheEntry *aEntry,
   254                                                     nsIApplicationCache* aAppCache,
   255                                                     nsresult aResult);
   256     nsresult OnCacheEntryAvailableInternal(nsICacheEntry *entry,
   257                                       bool aNew,
   258                                       nsIApplicationCache* aAppCache,
   259                                       nsresult status);
   260     nsresult GenerateCacheKey(uint32_t postID, nsACString &key);
   261     nsresult UpdateExpirationTime();
   262     nsresult CheckPartial(nsICacheEntry* aEntry, int64_t *aSize, int64_t *aContentLength);
   263     bool ShouldUpdateOfflineCacheEntry();
   264     nsresult ReadFromCache(bool alreadyMarkedValid);
   265     void     CloseCacheEntry(bool doomOnFailure);
   266     void     CloseOfflineCacheEntry();
   267     nsresult InitCacheEntry();
   268     void     UpdateInhibitPersistentCachingFlag();
   269     nsresult InitOfflineCacheEntry();
   270     nsresult AddCacheEntryHeaders(nsICacheEntry *entry);
   271     nsresult StoreAuthorizationMetaData(nsICacheEntry *entry);
   272     nsresult FinalizeCacheEntry();
   273     nsresult InstallCacheListener(int64_t offset = 0);
   274     nsresult InstallOfflineCacheListener(int64_t offset = 0);
   275     void     MaybeInvalidateCacheEntryForSubsequentGet();
   276     void     AsyncOnExamineCachedResponse();
   278     // Handle the bogus Content-Encoding Apache sometimes sends
   279     void ClearBogusContentEncodingIfNeeded();
   281     // byte range request specific methods
   282     nsresult ProcessPartialContent();
   283     nsresult OnDoneReadingPartialCacheEntry(bool *streamDone);
   285     nsresult DoAuthRetry(nsAHttpConnection *);
   287     void     HandleAsyncRedirectChannelToHttps();
   288     nsresult StartRedirectChannelToHttps();
   289     nsresult ContinueAsyncRedirectChannelToURI(nsresult rv);
   290     nsresult OpenRedirectChannel(nsresult rv);
   292     /**
   293      * A function that takes care of reading STS headers and enforcing STS
   294      * load rules.  After a secure channel is erected, STS requires the channel
   295      * to be trusted or any STS header data on the channel is ignored.
   296      * This is called from ProcessResponse.
   297      */
   298     nsresult ProcessSTSHeader();
   300     void InvalidateCacheEntryForLocation(const char *location);
   301     void AssembleCacheKey(const char *spec, uint32_t postID, nsACString &key);
   302     nsresult CreateNewURI(const char *loc, nsIURI **newURI);
   303     void DoInvalidateCacheEntry(nsIURI* aURI);
   305     // Ref RFC2616 13.10: "invalidation... MUST only be performed if
   306     // the host part is the same as in the Request-URI"
   307     inline bool HostPartIsTheSame(nsIURI *uri) {
   308         nsAutoCString tmpHost1, tmpHost2;
   309         return (NS_SUCCEEDED(mURI->GetAsciiHost(tmpHost1)) &&
   310                 NS_SUCCEEDED(uri->GetAsciiHost(tmpHost2)) &&
   311                 (tmpHost1 == tmpHost2));
   312     }
   314     inline static bool DoNotRender3xxBody(nsresult rv) {
   315         return rv == NS_ERROR_REDIRECT_LOOP         ||
   316                rv == NS_ERROR_CORRUPTED_CONTENT     ||
   317                rv == NS_ERROR_UNKNOWN_PROTOCOL      ||
   318                rv == NS_ERROR_MALFORMED_URI;
   319     }
   321     // Create a aggregate set of the current notification callbacks
   322     // and ensure the transaction is updated to use it.
   323     void UpdateAggregateCallbacks();
   325     static bool HasQueryString(nsHttpRequestHead::ParsedMethodType method, nsIURI * uri);
   326     bool ResponseWouldVary(nsICacheEntry* entry) const;
   327     bool MustValidateBasedOnQueryUrl() const;
   328     bool IsResumable(int64_t partialLen, int64_t contentLength,
   329                      bool ignoreMissingPartialLen = false) const;
   330     nsresult MaybeSetupByteRangeRequest(int64_t partialLen, int64_t contentLength);
   331     nsresult SetupByteRangeRequest(int64_t partialLen);
   332     nsresult OpenCacheInputStream(nsICacheEntry* cacheEntry, bool startBuffering);
   334 private:
   335     nsCOMPtr<nsISupports>             mSecurityInfo;
   336     nsCOMPtr<nsICancelable>           mProxyRequest;
   338     nsRefPtr<nsInputStreamPump>       mTransactionPump;
   339     nsRefPtr<nsHttpTransaction>       mTransaction;
   341     uint64_t                          mLogicalOffset;
   343     // cache specific data
   344     nsCOMPtr<nsICacheEntry>           mCacheEntry;
   345     // We must close mCacheInputStream explicitly to avoid leaks.
   346     AutoClose<nsIInputStream>         mCacheInputStream;
   347     nsRefPtr<nsInputStreamPump>       mCachePump;
   348     nsAutoPtr<nsHttpResponseHead>     mCachedResponseHead;
   349     nsCOMPtr<nsISupports>             mCachedSecurityInfo;
   350     uint32_t                          mPostID;
   351     uint32_t                          mRequestTime;
   353     nsCOMPtr<nsICacheEntry> mOfflineCacheEntry;
   354     uint32_t                          mOfflineCacheLastModifiedTime;
   355     nsCOMPtr<nsIApplicationCache>     mApplicationCacheForWrite;
   356     nsCString                         mCacheDomain;
   358     // auth specific data
   359     nsCOMPtr<nsIHttpChannelAuthProvider> mAuthProvider;
   361     // If the channel is associated with a cache, and the URI matched
   362     // a fallback namespace, this will hold the key for the fallback
   363     // cache entry.
   364     nsCString                         mFallbackKey;
   366     friend class AutoRedirectVetoNotifier;
   367     friend class HttpAsyncAborter<nsHttpChannel>;
   369     nsCOMPtr<nsIURI>                  mRedirectURI;
   370     nsCOMPtr<nsIChannel>              mRedirectChannel;
   371     uint32_t                          mRedirectType;
   373     static const uint32_t WAIT_FOR_CACHE_ENTRY = 1;
   374     static const uint32_t WAIT_FOR_OFFLINE_CACHE_ENTRY = 2;
   376     // state flags
   377     uint32_t                          mCachedContentIsValid     : 1;
   378     uint32_t                          mCachedContentIsPartial   : 1;
   379     uint32_t                          mTransactionReplaced      : 1;
   380     uint32_t                          mAuthRetryPending         : 1;
   381     uint32_t                          mProxyAuthPending         : 1;
   382     uint32_t                          mResuming                 : 1;
   383     uint32_t                          mInitedCacheEntry         : 1;
   384     // True if we are loading a fallback cache entry from the
   385     // application cache.
   386     uint32_t                          mFallbackChannel          : 1;
   387     // True if consumer added its own If-None-Match or If-Modified-Since
   388     // headers. In such a case we must not override them in the cache code
   389     // and also we want to pass possible 304 code response through.
   390     uint32_t                          mCustomConditionalRequest : 1;
   391     uint32_t                          mFallingBack              : 1;
   392     uint32_t                          mWaitingForRedirectCallback : 1;
   393     // True if mRequestTime has been set. In such a case it is safe to update
   394     // the cache entry's expiration time. Otherwise, it is not(see bug 567360).
   395     uint32_t                          mRequestTimeInitialized : 1;
   396     uint32_t                          mCacheEntryIsReadOnly : 1;
   397     uint32_t                          mCacheEntryIsWriteOnly : 1;
   398     // see WAIT_FOR_* constants above
   399     uint32_t                          mCacheEntriesToWaitFor : 2;
   400     uint32_t                          mHasQueryString : 1;
   401     // whether cache entry data write was in progress during cache entry check
   402     // when true, after we finish read from cache we must check all data
   403     // had been loaded from cache. If not, then an error has to be propagated
   404     // to the consumer.
   405     uint32_t                          mConcurentCacheAccess : 1;
   406     // whether the request is setup be byte-range
   407     uint32_t                          mIsPartialRequest : 1;
   408     // true iff there is AutoRedirectVetoNotifier on the stack
   409     uint32_t                          mHasAutoRedirectVetoNotifier : 1;
   411     nsTArray<nsContinueRedirectionFunc> mRedirectFuncStack;
   413     // Needed for accurate DNS timing
   414     nsRefPtr<nsDNSPrefetch>           mDNSPrefetch;
   416     nsresult WaitForRedirectCallback();
   417     void PushRedirectAsyncFunc(nsContinueRedirectionFunc func);
   418     void PopRedirectAsyncFunc(nsContinueRedirectionFunc func);
   420 protected:
   421     virtual void DoNotifyListenerCleanup();
   422     nsPerformance* GetPerformance();
   424 private: // cache telemetry
   425     bool mDidReval;
   427 private:
   428     nsIPrincipal *GetPrincipal();
   429     nsCOMPtr<nsIPrincipal> mPrincipal;
   430     bool mForcePending;
   431 };
   433 } } // namespace mozilla::net
   435 #endif // nsHttpChannel_h__

mercurial