netwerk/protocol/http/nsHttpTransaction.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 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef nsHttpTransaction_h__
     7 #define nsHttpTransaction_h__
     9 #include "nsHttp.h"
    10 #include "nsAHttpTransaction.h"
    11 #include "nsAHttpConnection.h"
    12 #include "EventTokenBucket.h"
    13 #include "nsCOMPtr.h"
    14 #include "nsThreadUtils.h"
    15 #include "nsILoadGroup.h"
    16 #include "nsIInterfaceRequestor.h"
    17 #include "TimingStruct.h"
    19 #ifdef MOZ_WIDGET_GONK
    20 #include "nsINetworkManager.h"
    21 #include "nsProxyRelease.h"
    22 #endif
    24 //-----------------------------------------------------------------------------
    26 class nsIHttpActivityObserver;
    27 class nsIEventTarget;
    28 class nsIInputStream;
    29 class nsIOutputStream;
    31 namespace mozilla { namespace net {
    33 class nsHttpChunkedDecoder;
    34 class nsHttpRequestHead;
    35 class nsHttpResponseHead;
    37 //-----------------------------------------------------------------------------
    38 // nsHttpTransaction represents a single HTTP transaction.  It is thread-safe,
    39 // intended to run on the socket thread.
    40 //-----------------------------------------------------------------------------
    42 class nsHttpTransaction : public nsAHttpTransaction
    43                         , public ATokenBucketEvent
    44                         , public nsIInputStreamCallback
    45                         , public nsIOutputStreamCallback
    46 {
    47 public:
    48     NS_DECL_THREADSAFE_ISUPPORTS
    49     NS_DECL_NSAHTTPTRANSACTION
    50     NS_DECL_NSIINPUTSTREAMCALLBACK
    51     NS_DECL_NSIOUTPUTSTREAMCALLBACK
    53     nsHttpTransaction();
    54     virtual ~nsHttpTransaction();
    56     //
    57     // called to initialize the transaction
    58     //
    59     // @param caps
    60     //        the transaction capabilities (see nsHttp.h)
    61     // @param connInfo
    62     //        the connection type for this transaction.
    63     // @param reqHeaders
    64     //        the request header struct
    65     // @param reqBody
    66     //        the request body (POST or PUT data stream)
    67     // @param reqBodyIncludesHeaders
    68     //        fun stuff to support NPAPI plugins.
    69     // @param target
    70     //        the dispatch target were notifications should be sent.
    71     // @param callbacks
    72     //        the notification callbacks to be given to PSM.
    73     // @param responseBody
    74     //        the input stream that will contain the response data.  async
    75     //        wait on this input stream for data.  on first notification,
    76     //        headers should be available (check transaction status).
    77     //
    78     nsresult Init(uint32_t               caps,
    79                   nsHttpConnectionInfo  *connInfo,
    80                   nsHttpRequestHead     *reqHeaders,
    81                   nsIInputStream        *reqBody,
    82                   bool                   reqBodyIncludesHeaders,
    83                   nsIEventTarget        *consumerTarget,
    84                   nsIInterfaceRequestor *callbacks,
    85                   nsITransportEventSink *eventsink,
    86                   nsIAsyncInputStream  **responseBody);
    88     // attributes
    89     nsHttpConnectionInfo  *ConnectionInfo() { return mConnInfo; }
    90     nsHttpResponseHead    *ResponseHead()   { return mHaveAllHeaders ? mResponseHead : nullptr; }
    91     nsISupports           *SecurityInfo()   { return mSecurityInfo; }
    93     nsIEventTarget        *ConsumerTarget() { return mConsumerTarget; }
    95     void SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks);
    97     // Called to take ownership of the response headers; the transaction
    98     // will drop any reference to the response headers after this call.
    99     nsHttpResponseHead *TakeResponseHead();
   101     // Provides a thread safe reference of the connection
   102     // nsHttpTransaction::Connection should only be used on the socket thread
   103     already_AddRefed<nsAHttpConnection> GetConnectionReference();
   105     // Called to find out if the transaction generated a complete response.
   106     bool ResponseIsComplete() { return mResponseIsComplete; }
   108     bool      ProxyConnectFailed() { return mProxyConnectFailed; }
   110     // SetPriority() may only be used by the connection manager.
   111     void    SetPriority(int32_t priority) { mPriority = priority; }
   112     int32_t    Priority()                 { return mPriority; }
   114     const TimingStruct& Timings() const { return mTimings; }
   115     enum Classifier Classification() { return mClassification; }
   117     void PrintDiagnostics(nsCString &log);
   119     // Sets mPendingTime to the current time stamp or to a null time stamp (if now is false)
   120     void SetPendingTime(bool now = true) { mPendingTime = now ? TimeStamp::Now() : TimeStamp(); }
   121     const TimeStamp GetPendingTime() { return mPendingTime; }
   122     bool UsesPipelining() const { return mCaps & NS_HTTP_ALLOW_PIPELINING; }
   124     // overload of nsAHttpTransaction::LoadGroupConnectionInfo()
   125     nsILoadGroupConnectionInfo *LoadGroupConnectionInfo() { return mLoadGroupCI.get(); }
   126     void SetLoadGroupConnectionInfo(nsILoadGroupConnectionInfo *aLoadGroupCI) { mLoadGroupCI = aLoadGroupCI; }
   127     void DispatchedAsBlocking();
   128     void RemoveDispatchedAsBlocking();
   130 private:
   131     nsresult Restart();
   132     nsresult RestartInProgress();
   133     char    *LocateHttpStart(char *buf, uint32_t len,
   134                              bool aAllowPartialMatch);
   135     nsresult ParseLine(char *line);
   136     nsresult ParseLineSegment(char *seg, uint32_t len);
   137     nsresult ParseHead(char *, uint32_t count, uint32_t *countRead);
   138     nsresult HandleContentStart();
   139     nsresult HandleContent(char *, uint32_t count, uint32_t *contentRead, uint32_t *contentRemaining);
   140     nsresult ProcessData(char *, uint32_t, uint32_t *);
   141     void     DeleteSelfOnConsumerThread();
   142     void     ReleaseBlockingTransaction();
   144     Classifier Classify();
   145     void       CancelPipeline(uint32_t reason);
   147     static NS_METHOD ReadRequestSegment(nsIInputStream *, void *, const char *,
   148                                         uint32_t, uint32_t, uint32_t *);
   149     static NS_METHOD WritePipeSegment(nsIOutputStream *, void *, char *,
   150                                       uint32_t, uint32_t, uint32_t *);
   152     bool TimingEnabled() const { return mCaps & NS_HTTP_TIMING_ENABLED; }
   154     bool ResponseTimeoutEnabled() const MOZ_FINAL;
   156 private:
   157     class UpdateSecurityCallbacks : public nsRunnable
   158     {
   159       public:
   160         UpdateSecurityCallbacks(nsHttpTransaction* aTrans,
   161                                 nsIInterfaceRequestor* aCallbacks)
   162         : mTrans(aTrans), mCallbacks(aCallbacks) {}
   164         NS_IMETHOD Run()
   165         {
   166             if (mTrans->mConnection)
   167                 mTrans->mConnection->SetSecurityCallbacks(mCallbacks);
   168             return NS_OK;
   169         }
   170       private:
   171         nsRefPtr<nsHttpTransaction> mTrans;
   172         nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
   173     };
   175     Mutex mLock;
   177     nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
   178     nsCOMPtr<nsITransportEventSink> mTransportSink;
   179     nsCOMPtr<nsIEventTarget>        mConsumerTarget;
   180     nsCOMPtr<nsISupports>           mSecurityInfo;
   181     nsCOMPtr<nsIAsyncInputStream>   mPipeIn;
   182     nsCOMPtr<nsIAsyncOutputStream>  mPipeOut;
   183     nsCOMPtr<nsILoadGroupConnectionInfo> mLoadGroupCI;
   185     nsCOMPtr<nsISupports>             mChannel;
   186     nsCOMPtr<nsIHttpActivityObserver> mActivityDistributor;
   188     nsCString                       mReqHeaderBuf;    // flattened request headers
   189     nsCOMPtr<nsIInputStream>        mRequestStream;
   190     uint64_t                        mRequestSize;
   192     nsAHttpConnection              *mConnection;      // hard ref
   193     nsHttpConnectionInfo           *mConnInfo;        // hard ref
   194     nsHttpRequestHead              *mRequestHead;     // weak ref
   195     nsHttpResponseHead             *mResponseHead;    // hard ref
   197     nsAHttpSegmentReader           *mReader;
   198     nsAHttpSegmentWriter           *mWriter;
   200     nsCString                       mLineBuf;         // may contain a partial line
   202     int64_t                         mContentLength;   // equals -1 if unknown
   203     int64_t                         mContentRead;     // count of consumed content bytes
   205     // After a 304/204 or other "no-content" style response we will skip over
   206     // up to MAX_INVALID_RESPONSE_BODY_SZ bytes when looking for the next
   207     // response header to deal with servers that actually sent a response
   208     // body where they should not have. This member tracks how many bytes have
   209     // so far been skipped.
   210     uint32_t                        mInvalidResponseBytesRead;
   212     nsHttpChunkedDecoder           *mChunkedDecoder;
   214     TimingStruct                    mTimings;
   216     nsresult                        mStatus;
   218     int16_t                         mPriority;
   220     uint16_t                        mRestartCount;        // the number of times this transaction has been restarted
   221     uint32_t                        mCaps;
   222     // mCapsToClear holds flags that should be cleared in mCaps, e.g. unset
   223     // NS_HTTP_REFRESH_DNS when DNS refresh request has completed to avoid
   224     // redundant requests on the network. To deal with raciness, only unsetting
   225     // bitfields should be allowed: 'lost races' will thus err on the
   226     // conservative side, e.g. by going ahead with a 2nd DNS refresh.
   227     uint32_t                        mCapsToClear;
   228     enum Classifier                 mClassification;
   229     int32_t                         mPipelinePosition;
   230     int64_t                         mMaxPipelineObjectSize;
   232     nsHttpVersion                   mHttpVersion;
   234     // state flags, all logically boolean, but not packed together into a
   235     // bitfield so as to avoid bitfield-induced races.  See bug 560579.
   236     bool                            mClosed;
   237     bool                            mConnected;
   238     bool                            mHaveStatusLine;
   239     bool                            mHaveAllHeaders;
   240     bool                            mTransactionDone;
   241     bool                            mResponseIsComplete;
   242     bool                            mDidContentStart;
   243     bool                            mNoContent; // expecting an empty entity body
   244     bool                            mSentData;
   245     bool                            mReceivedData;
   246     bool                            mStatusEventPending;
   247     bool                            mHasRequestBody;
   248     bool                            mProxyConnectFailed;
   249     bool                            mHttpResponseMatched;
   250     bool                            mPreserveStream;
   251     bool                            mDispatchedAsBlocking;
   252     bool                            mResponseTimeoutEnabled;
   254     // mClosed           := transaction has been explicitly closed
   255     // mTransactionDone  := transaction ran to completion or was interrupted
   256     // mResponseComplete := transaction ran to completion
   258     // For Restart-In-Progress Functionality
   259     bool                            mReportedStart;
   260     bool                            mReportedResponseHeader;
   262     // protected by nsHttp::GetLock()
   263     nsHttpResponseHead             *mForTakeResponseHead;
   264     bool                            mResponseHeadTaken;
   266     // The time when the transaction was submitted to the Connection Manager
   267     TimeStamp                       mPendingTime;
   269     class RestartVerifier
   270     {
   272         // When a idemptotent transaction has received part of its response body
   273         // and incurs an error it can be restarted. To do this we mark the place
   274         // where we stopped feeding the body to the consumer and start the
   275         // network call over again. If everything we track (headers, length, etc..)
   276         // matches up to the place where we left off then the consumer starts being
   277         // fed data again with the new information. This can be done N times up
   278         // to the normal restart (i.e. with no response info) limit.
   280     public:
   281         RestartVerifier()
   282             : mContentLength(-1)
   283             , mAlreadyProcessed(0)
   284             , mToReadBeforeRestart(0)
   285             , mSetup(false)
   286         {}
   287         ~RestartVerifier() {}
   289         void Set(int64_t contentLength, nsHttpResponseHead *head);
   290         bool Verify(int64_t contentLength, nsHttpResponseHead *head);
   291         bool IsDiscardingContent() { return mToReadBeforeRestart != 0; }
   292         bool IsSetup() { return mSetup; }
   293         int64_t AlreadyProcessed() { return mAlreadyProcessed; }
   294         void SetAlreadyProcessed(int64_t val) {
   295             mAlreadyProcessed = val;
   296             mToReadBeforeRestart = val;
   297         }
   298         int64_t ToReadBeforeRestart() { return mToReadBeforeRestart; }
   299         void HaveReadBeforeRestart(uint32_t amt)
   300         {
   301             MOZ_ASSERT(amt <= mToReadBeforeRestart,
   302                        "too large of a HaveReadBeforeRestart deduction");
   303             mToReadBeforeRestart -= amt;
   304         }
   306     private:
   307         // This is the data from the first complete response header
   308         // used to make sure that all subsequent response headers match
   310         int64_t                         mContentLength;
   311         nsCString                       mETag;
   312         nsCString                       mLastModified;
   313         nsCString                       mContentRange;
   314         nsCString                       mContentEncoding;
   315         nsCString                       mTransferEncoding;
   317         // This is the amount of data that has been passed to the channel
   318         // from previous iterations of the transaction and must therefore
   319         // be skipped in the new one.
   320         int64_t                         mAlreadyProcessed;
   322         // The amount of data that must be discarded in the current iteration
   323         // (where iteration > 0) to reach the mAlreadyProcessed high water
   324         // mark.
   325         int64_t                         mToReadBeforeRestart;
   327         // true when ::Set has been called with a response header
   328         bool                            mSetup;
   329     } mRestartInProgressVerifier;
   331 // For Rate Pacing via an EventTokenBucket
   332 public:
   333     // called by the connection manager to run this transaction through the
   334     // token bucket. If the token bucket admits the transaction immediately it
   335     // returns true. The function is called repeatedly until it returns true.
   336     bool TryToRunPacedRequest();
   338     // ATokenBucketEvent pure virtual implementation. Called by the token bucket
   339     // when the transaction is ready to run. If this happens asynchrounously to
   340     // token bucket submission the transaction just posts an event that causes
   341     // the pending transaction queue to be rerun (and TryToRunPacedRequest() to
   342     // be run again.
   343     void OnTokenBucketAdmitted(); // ATokenBucketEvent
   345     // CancelPacing() can be used to tell the token bucket to remove this
   346     // transaction from the list of pending transactions. This is used when a
   347     // transaction is believed to be HTTP/1 (and thus subject to rate pacing)
   348     // but later can be dispatched via spdy (not subject to rate pacing).
   349     void CancelPacing(nsresult reason);
   351 private:
   352     bool mSubmittedRatePacing;
   353     bool mPassedRatePacing;
   354     bool mSynchronousRatePaceRequest;
   355     nsCOMPtr<nsICancelable> mTokenBucketCancel;
   357 // These members are used for network per-app metering (bug 746073)
   358 // Currently, they are only available on gonk.
   359     uint64_t                           mCountRecv;
   360     uint64_t                           mCountSent;
   361     uint32_t                           mAppId;
   362 #ifdef MOZ_WIDGET_GONK
   363     nsMainThreadPtrHandle<nsINetworkInterface> mActiveNetwork;
   364 #endif
   365     nsresult                           SaveNetworkStats(bool);
   366     void                               CountRecvBytes(uint64_t recvBytes)
   367     {
   368         mCountRecv += recvBytes;
   369         SaveNetworkStats(false);
   370     }
   371     void                               CountSentBytes(uint64_t sentBytes)
   372     {
   373         mCountSent += sentBytes;
   374         SaveNetworkStats(false);
   375     }
   376 };
   378 }} // namespace mozilla::net
   380 #endif // nsHttpTransaction_h__

mercurial