LCOV - app.info - netwerk/protocol/http/nsHttpConnectionMgr.h

LCOV - code coverage report
| Current view: | directory - netwerk/protocol/http - nsHttpConnectionMgr.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 17 | 16 | 94.1 %
| Date: | 2012-04-21 | Functions: | 7 | 6 | 85.7 %

           1                 : /* vim:set ts=4 sw=4 sts=4 et cin: */
           2                 : /* ***** BEGIN LICENSE BLOCK *****
           3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           4                 :  *
           5                 :  * The contents of this file are subject to the Mozilla Public License Version
           6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           7                 :  * the License. You may obtain a copy of the License at
           8                 :  * http://www.mozilla.org/MPL/
           9                 :  *
          10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          12                 :  * for the specific language governing rights and limitations under the
          13                 :  * License.
          14                 :  *
          15                 :  * The Original Code is Mozilla.
          16                 :  *
          17                 :  * The Initial Developer of the Original Code is
          18                 :  * Netscape Communications Corporation.
          19                 :  * Portions created by the Initial Developer are Copyright (C) 2002
          20                 :  * the Initial Developer. All Rights Reserved.
          21                 :  *
          22                 :  * Contributor(s):
          23                 :  *   Darin Fisher <darin@netscape.com>
          24                 :  *
          25                 :  * Alternatively, the contents of this file may be used under the terms of
          26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          29                 :  * of those above. If you wish to allow use of your version of this file only
          30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          31                 :  * use your version of this file under the terms of the MPL, indicate your
          32                 :  * decision by deleting the provisions above and replace them with the notice
          33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          34                 :  * the provisions above, a recipient may use your version of this file under
          35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          36                 :  *
          37                 :  * ***** END LICENSE BLOCK ***** */
          38                 :
          39                 : #ifndef nsHttpConnectionMgr_h__
          40                 : #define nsHttpConnectionMgr_h__
          41                 :
          42                 : #include "nsHttpConnectionInfo.h"
          43                 : #include "nsHttpConnection.h"
          44                 : #include "nsHttpTransaction.h"
          45                 : #include "nsTArray.h"
          46                 : #include "nsThreadUtils.h"
          47                 : #include "nsClassHashtable.h"
          48                 : #include "nsDataHashtable.h"
          49                 : #include "nsAutoPtr.h"
          50                 : #include "mozilla/ReentrantMonitor.h"
          51                 : #include "nsISocketTransportService.h"
          52                 :
          53                 : #include "nsIObserver.h"
          54                 : #include "nsITimer.h"
          55                 : #include "nsIX509Cert3.h"
          56                 :
          57                 : class nsHttpPipeline;
          58                 :
          59                 : //-----------------------------------------------------------------------------
          60                 :
          61                 : class nsHttpConnectionMgr : public nsIObserver
          62                 : {
          63                 : public:
          64                 :     NS_DECL_ISUPPORTS
          65                 :     NS_DECL_NSIOBSERVER
          66                 :
          67                 :     // parameter names
          68                 :     enum nsParamName {
          69                 :         MAX_CONNECTIONS,
          70                 :         MAX_CONNECTIONS_PER_HOST,
          71                 :         MAX_CONNECTIONS_PER_PROXY,
          72                 :         MAX_PERSISTENT_CONNECTIONS_PER_HOST,
          73                 :         MAX_PERSISTENT_CONNECTIONS_PER_PROXY,
          74                 :         MAX_REQUEST_DELAY,
          75                 :         MAX_PIPELINED_REQUESTS
          76                 :     };
          77                 :
          78                 :     //-------------------------------------------------------------------------
          79                 :     // NOTE: functions below may only be called on the main thread.
          80                 :     //-------------------------------------------------------------------------
          81                 :
          82                 :     nsHttpConnectionMgr();
          83                 :
          84                 :     nsresult Init(PRUint16 maxConnections,
          85                 :                   PRUint16 maxConnectionsPerHost,
          86                 :                   PRUint16 maxConnectionsPerProxy,
          87                 :                   PRUint16 maxPersistentConnectionsPerHost,
          88                 :                   PRUint16 maxPersistentConnectionsPerProxy,
          89                 :                   PRUint16 maxRequestDelay,
          90                 :                   PRUint16 maxPipelinedRequests);
          91                 :     nsresult Shutdown();
          92                 :
          93                 :     //-------------------------------------------------------------------------
          94                 :     // NOTE: functions below may be called on any thread.
          95                 :     //-------------------------------------------------------------------------
          96                 :
          97                 :     // Schedules next pruning of dead connection to happen after
          98                 :     // given time.
          99                 :     void PruneDeadConnectionsAfter(PRUint32 time);
         100                 :
         101                 :     // Stops timer scheduled for next pruning of dead connections if
         102                 :     // there are no more idle connections or active spdy ones
         103                 :     void ConditionallyStopPruneDeadConnectionsTimer();
         104                 :
         105                 :     // Stops timer used for the read timeout tick if there are no currently
         106                 :     // active connections.
         107                 :     void ConditionallyStopReadTimeoutTick();
         108                 :
         109                 :     // adds a transaction to the list of managed transactions.
         110                 :     nsresult AddTransaction(nsHttpTransaction *, PRInt32 priority);
         111                 :
         112                 :     // called to reschedule the given transaction.  it must already have been
         113                 :     // added to the connection manager via AddTransaction.
         114                 :     nsresult RescheduleTransaction(nsHttpTransaction *, PRInt32 priority);
         115                 :
         116                 :     // cancels a transaction w/ the given reason.
         117                 :     nsresult CancelTransaction(nsHttpTransaction *, nsresult reason);
         118                 :
         119                 :     // called to force the connection manager to prune its list of idle
         120                 :     // connections.
         121                 :     nsresult PruneDeadConnections();
         122                 :
         123                 :     // Close all idle persistent connections and prevent any active connections
         124                 :     // from being reused.
         125                 :     nsresult ClosePersistentConnections();
         126                 :
         127                 :     // called to get a reference to the socket transport service.  the socket
         128                 :     // transport service is not available when the connection manager is down.
         129                 :     nsresult GetSocketThreadTarget(nsIEventTarget **);
         130                 :
         131                 :     // called when a connection is done processing a transaction.  if the
         132                 :     // connection can be reused then it will be added to the idle list, else
         133                 :     // it will be closed.
         134                 :     nsresult ReclaimConnection(nsHttpConnection *conn);
         135                 :
         136                 :     // called to update a parameter after the connection manager has already
         137                 :     // been initialized.
         138                 :     nsresult UpdateParam(nsParamName name, PRUint16 value);
         139                 :
         140                 :     // Lookup/Cancel HTTP->SPDY redirections
         141                 :     bool GetSpdyAlternateProtocol(nsACString &key);
         142                 :     void ReportSpdyAlternateProtocol(nsHttpConnection *);
         143                 :     void RemoveSpdyAlternateProtocol(nsACString &key);
         144                 :
         145                 :     //-------------------------------------------------------------------------
         146                 :     // NOTE: functions below may be called only on the socket thread.
         147                 :     //-------------------------------------------------------------------------
         148                 :
         149                 :     // removes the next transaction for the specified connection from the
         150                 :     // pending transaction queue.
         151                 :     void AddTransactionToPipeline(nsHttpPipeline *);
         152                 :
         153                 :     // called to force the transaction queue to be processed once more, giving
         154                 :     // preference to the specified connection.
         155                 :     nsresult ProcessPendingQ(nsHttpConnectionInfo *);
         156                 :
         157                 :     // This is used to force an idle connection to be closed and removed from
         158                 :     // the idle connection list. It is called when the idle connection detects
         159                 :     // that the network peer has closed the transport.
         160                 :     nsresult CloseIdleConnection(nsHttpConnection *);
         161                 :
         162                 :     // The connection manager needs to know when a normal HTTP connection has been
         163                 :     // upgraded to SPDY because the dispatch and idle semantics are a little
         164                 :     // bit different.
         165                 :     void ReportSpdyConnection(nsHttpConnection *, bool usingSpdy);
         166                 :
         167                 : private:
         168                 :     virtual ~nsHttpConnectionMgr();
         169                 :     class nsHalfOpenSocket;
         170                 :
         171                 :     // nsConnectionEntry
         172                 :     //
         173                 :     // mCT maps connection info hash key to nsConnectionEntry object, which
         174                 :     // contains list of active and idle connections as well as the list of
         175                 :     // pending transactions.
         176                 :     //
         177                 :     struct nsConnectionEntry
         178                 :     {
         179             291 :         nsConnectionEntry(nsHttpConnectionInfo *ci)
         180                 :           : mConnInfo(ci),
         181                 :             mUsingSpdy(false),
         182                 :             mTestedSpdy(false),
         183             291 :             mSpdyPreferred(false)
         184                 :         {
         185             291 :             NS_ADDREF(mConnInfo);
         186             291 :         }
         187                 :         ~nsConnectionEntry();
         188                 :
         189                 :         nsHttpConnectionInfo        *mConnInfo;
         190                 :         nsTArray<nsHttpTransaction*> mPendingQ;    // pending transaction queue
         191                 :         nsTArray<nsHttpConnection*>  mActiveConns; // active connections
         192                 :         nsTArray<nsHttpConnection*>  mIdleConns;   // idle persistent connections
         193                 :         nsTArray<nsHalfOpenSocket*>  mHalfOpens;
         194                 :
         195                 :         // Spdy sometimes resolves the address in the socket manager in order
         196                 :         // to re-coalesce sharded HTTP hosts. The dotted decimal address is
         197                 :         // combined with the Anonymous flag from the connection information
         198                 :         // to build the hash key for hosts in the same ip pool.
         199                 :         //
         200                 :         // When a set of hosts are coalesced together one of them is marked
         201                 :         // mSpdyPreferred. The mapping is maintained in the connection mananger
         202                 :         // mSpdyPreferred hash.
         203                 :         //
         204                 :         nsCString mCoalescingKey;
         205                 :
         206                 :         // To have the UsingSpdy flag means some host with the same connection
         207                 :         // entry has done NPN=spdy/2 at some point. It does not mean every
         208                 :         // connection is currently using spdy.
         209                 :         bool mUsingSpdy;
         210                 :
         211                 :         // mTestedSpdy is set after NPN negotiation has occurred and we know
         212                 :         // with confidence whether a host speaks spdy or not (which is reflected
         213                 :         // in mUsingSpdy). Before mTestedSpdy is set, handshake parallelism is
         214                 :         // minimized so that we can multiplex on a single spdy connection.
         215                 :         bool mTestedSpdy;
         216                 :
         217                 :         bool mSpdyPreferred;
         218                 :     };
         219                 :
         220                 :     // nsConnectionHandle
         221                 :     //
         222                 :     // thin wrapper around a real connection, used to keep track of references
         223                 :     // to the connection to determine when the connection may be reused.  the
         224                 :     // transaction (or pipeline) owns a reference to this handle.  this extra
         225                 :     // layer of indirection greatly simplifies consumer code, avoiding the
         226                 :     // need for consumer code to know when to give the connection back to the
         227                 :     // connection manager.
         228                 :     //
         229                 :     class nsConnectionHandle : public nsAHttpConnection
         230                 :     {
         231                 :     public:
         232                 :         NS_DECL_ISUPPORTS
         233                 :         NS_DECL_NSAHTTPCONNECTION
         234                 :
         235            2988 :         nsConnectionHandle(nsHttpConnection *conn) { NS_ADDREF(mConn = conn); }
         236                 :         virtual ~nsConnectionHandle();
         237                 :
         238                 :         nsHttpConnection *mConn;
         239                 :     };
         240                 :
         241                 :     // nsHalfOpenSocket is used to hold the state of an opening TCP socket
         242                 :     // while we wait for it to establish and bind it to a connection
         243                 :
         244                 :     class nsHalfOpenSocket : public nsIOutputStreamCallback,
         245                 :                              public nsITransportEventSink,
         246                 :                              public nsIInterfaceRequestor,
         247                 :                              public nsITimerCallback
         248                 :     {
         249                 :     public:
         250                 :         NS_DECL_ISUPPORTS
         251                 :         NS_DECL_NSIOUTPUTSTREAMCALLBACK
         252                 :         NS_DECL_NSITRANSPORTEVENTSINK
         253                 :         NS_DECL_NSIINTERFACEREQUESTOR
         254                 :         NS_DECL_NSITIMERCALLBACK
         255                 :
         256                 :         nsHalfOpenSocket(nsConnectionEntry *ent,
         257                 :                          nsHttpTransaction *trans);
         258                 :         ~nsHalfOpenSocket();
         259                 :
         260                 :         nsresult SetupStreams(nsISocketTransport **,
         261                 :                               nsIAsyncInputStream **,
         262                 :                               nsIAsyncOutputStream **,
         263                 :                               bool isBackup);
         264                 :         nsresult SetupPrimaryStreams();
         265                 :         nsresult SetupBackupStreams();
         266                 :         void     SetupBackupTimer();
         267                 :         void     CancelBackupTimer();
         268                 :         void     Abandon();
         269                 :
         270               0 :         nsHttpTransaction *Transaction() { return mTransaction; }
         271                 :
         272                 :     private:
         273                 :         nsConnectionEntry              *mEnt;
         274                 :         nsRefPtr<nsHttpTransaction>    mTransaction;
         275                 :         nsCOMPtr<nsISocketTransport>   mSocketTransport;
         276                 :         nsCOMPtr<nsIAsyncOutputStream> mStreamOut;
         277                 :         nsCOMPtr<nsIAsyncInputStream>  mStreamIn;
         278                 :
         279                 :         // for syn retry
         280                 :         nsCOMPtr<nsITimer>             mSynTimer;
         281                 :         nsCOMPtr<nsISocketTransport>   mBackupTransport;
         282                 :         nsCOMPtr<nsIAsyncOutputStream> mBackupStreamOut;
         283                 :         nsCOMPtr<nsIAsyncInputStream>  mBackupStreamIn;
         284                 :     };
         285                 :     friend class nsHalfOpenSocket;
         286                 :
         287                 :     //-------------------------------------------------------------------------
         288                 :     // NOTE: these members may be accessed from any thread (use mReentrantMonitor)
         289                 :     //-------------------------------------------------------------------------
         290                 :
         291                 :     PRInt32                      mRef;
         292                 :     mozilla::ReentrantMonitor    mReentrantMonitor;
         293                 :     nsCOMPtr<nsIEventTarget>     mSocketThreadTarget;
         294                 :
         295                 :     // connection limits
         296                 :     PRUint16 mMaxConns;
         297                 :     PRUint16 mMaxConnsPerHost;
         298                 :     PRUint16 mMaxConnsPerProxy;
         299                 :     PRUint16 mMaxPersistConnsPerHost;
         300                 :     PRUint16 mMaxPersistConnsPerProxy;
         301                 :     PRUint16 mMaxRequestDelay; // in seconds
         302                 :     PRUint16 mMaxPipelinedRequests;
         303                 :
         304                 :     bool mIsShuttingDown;
         305                 :
         306                 :     //-------------------------------------------------------------------------
         307                 :     // NOTE: these members are only accessed on the socket transport thread
         308                 :     //-------------------------------------------------------------------------
         309                 :
         310                 :     static PLDHashOperator ProcessOneTransactionCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
         311                 :
         312                 :     static PLDHashOperator PruneDeadConnectionsCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
         313                 :     static PLDHashOperator ShutdownPassCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
         314                 :     static PLDHashOperator PurgeExcessIdleConnectionsCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
         315                 :     static PLDHashOperator ClosePersistentConnectionsCB(const nsACString &, nsAutoPtr<nsConnectionEntry> &, void *);
         316                 :     bool     ProcessPendingQForEntry(nsConnectionEntry *);
         317                 :     bool     AtActiveConnectionLimit(nsConnectionEntry *, PRUint8 caps);
         318                 :     void     GetConnection(nsConnectionEntry *, nsHttpTransaction *,
         319                 :                            bool, nsHttpConnection **);
         320                 :     nsresult DispatchTransaction(nsConnectionEntry *, nsHttpTransaction *,
         321                 :                                  PRUint8 caps, nsHttpConnection *);
         322                 :     bool     BuildPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **);
         323                 :     nsresult ProcessNewTransaction(nsHttpTransaction *);
         324                 :     nsresult EnsureSocketThreadTargetIfOnline();
         325                 :     void     ClosePersistentConnections(nsConnectionEntry *ent);
         326                 :     nsresult CreateTransport(nsConnectionEntry *, nsHttpTransaction *);
         327                 :     void     AddActiveConn(nsHttpConnection *, nsConnectionEntry *);
         328                 :     void     StartedConnect();
         329                 :     void     RecvdConnect();
         330                 :
         331                 :     // Manage the preferred spdy connection entry for this address
         332                 :     nsConnectionEntry *GetSpdyPreferredEnt(nsConnectionEntry *aOriginalEntry);
         333                 :     void               RemoveSpdyPreferredEnt(nsACString &aDottedDecimal);
         334                 :     nsHttpConnection  *GetSpdyPreferredConn(nsConnectionEntry *ent);
         335                 :     nsDataHashtable<nsCStringHashKey, nsConnectionEntry *>   mSpdyPreferredHash;
         336                 :     nsConnectionEntry *LookupConnectionEntry(nsHttpConnectionInfo *ci,
         337                 :                                              nsHttpConnection *conn,
         338                 :                                              nsHttpTransaction *trans);
         339                 :
         340                 :     void               ProcessSpdyPendingQ(nsConnectionEntry *ent);
         341                 :     void               ProcessAllSpdyPendingQ();
         342                 :     static PLDHashOperator ProcessSpdyPendingQCB(
         343                 :         const nsACString &key, nsAutoPtr<nsConnectionEntry> &ent,
         344                 :         void *closure);
         345                 :
         346                 :     // message handlers have this signature
         347                 :     typedef void (nsHttpConnectionMgr:: *nsConnEventHandler)(PRInt32, void *);
         348                 :
         349                 :     // nsConnEvent
         350                 :     //
         351                 :     // subclass of nsRunnable used to marshall events to the socket transport
         352                 :     // thread.  this class is used to implement PostEvent.
         353                 :     //
         354                 :     class nsConnEvent;
         355                 :     friend class nsConnEvent;
         356                 :     class nsConnEvent : public nsRunnable
         357                 :     {
         358                 :     public:
         359            7060 :         nsConnEvent(nsHttpConnectionMgr *mgr,
         360                 :                     nsConnEventHandler handler,
         361                 :                     PRInt32 iparam,
         362                 :                     void *vparam)
         363                 :             : mMgr(mgr)
         364                 :             , mHandler(handler)
         365                 :             , mIParam(iparam)
         366            7060 :             , mVParam(vparam)
         367                 :         {
         368            7060 :             NS_ADDREF(mMgr);
         369            7060 :         }
         370                 :
         371            7060 :         NS_IMETHOD Run()
         372                 :         {
         373            7060 :             (mMgr->*mHandler)(mIParam, mVParam);
         374            7060 :             return NS_OK;
         375                 :         }
         376                 :
         377                 :     private:
         378           14120 :         virtual ~nsConnEvent()
         379           14120 :         {
         380            7060 :             NS_RELEASE(mMgr);
         381           28240 :         }
         382                 :
         383                 :         nsHttpConnectionMgr *mMgr;
         384                 :         nsConnEventHandler   mHandler;
         385                 :         PRInt32              mIParam;
         386                 :         void                *mVParam;
         387                 :     };
         388                 :
         389                 :     nsresult PostEvent(nsConnEventHandler  handler,
         390                 :                        PRInt32             iparam = 0,
         391                 :                        void               *vparam = nsnull);
         392                 :
         393                 :     // message handlers
         394                 :     void OnMsgShutdown             (PRInt32, void *);
         395                 :     void OnMsgNewTransaction       (PRInt32, void *);
         396                 :     void OnMsgReschedTransaction   (PRInt32, void *);
         397                 :     void OnMsgCancelTransaction    (PRInt32, void *);
         398                 :     void OnMsgProcessPendingQ      (PRInt32, void *);
         399                 :     void OnMsgPruneDeadConnections (PRInt32, void *);
         400                 :     void OnMsgReclaimConnection    (PRInt32, void *);
         401                 :     void OnMsgUpdateParam          (PRInt32, void *);
         402                 :     void OnMsgClosePersistentConnections (PRInt32, void *);
         403                 :
         404                 :     // Total number of active connections in all of the ConnectionEntry objects
         405                 :     // that are accessed from mCT connection table.
         406                 :     PRUint16 mNumActiveConns;
         407                 :     // Total number of idle connections in all of the ConnectionEntry objects
         408                 :     // that are accessed from mCT connection table.
         409                 :     PRUint16 mNumIdleConns;
         410                 :
         411                 :     // Holds time in seconds for next wake-up to prune dead connections.
         412                 :     PRUint64 mTimeOfNextWakeUp;
         413                 :     // Timer for next pruning of dead connections.
         414                 :     nsCOMPtr<nsITimer> mTimer;
         415                 :
         416                 :     // A 1s tick to call nsHttpConnection::ReadTimeoutTick on
         417                 :     // active http/1 connections. Disabled when there are no
         418                 :     // active connections.
         419                 :     nsCOMPtr<nsITimer> mReadTimeoutTick;
         420                 :     bool mReadTimeoutTickArmed;
         421                 :
         422                 :     //
         423                 :     // the connection table
         424                 :     //
         425                 :     // this table is indexed by connection key.  each entry is a
         426                 :     // nsConnectionEntry object.
         427                 :     //
         428                 :     nsClassHashtable<nsCStringHashKey, nsConnectionEntry> mCT;
         429                 :
         430                 :     // mAlternateProtocolHash is used only for spdy/2 upgrades for now
         431                 :     // protected by the monitor
         432                 :     nsTHashtable<nsCStringHashKey> mAlternateProtocolHash;
         433                 :     static PLDHashOperator TrimAlternateProtocolHash(nsCStringHashKey *entry,
         434                 :                                                      void *closure);
         435                 :     // Read Timeout Tick handlers
         436                 :     void ActivateTimeoutTick();
         437                 :     void ReadTimeoutTick();
         438                 :     static PLDHashOperator ReadTimeoutTickCB(const nsACString &key,
         439                 :                                              nsAutoPtr<nsConnectionEntry> &ent,
         440                 :                                              void *closure);
         441                 : };
         442                 :
         443                 : #endif // !nsHttpConnectionMgr_h__

Generated by: LCOV version 1.7