1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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.
19 : * Portions created by the Initial Developer are Copyright (C) 2001
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Darin Fisher <darin@netscape.com> (original author)
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 nsHttpConnection_h__
40 : #define nsHttpConnection_h__
41 :
42 : #include "nsHttp.h"
43 : #include "nsHttpConnectionInfo.h"
44 : #include "nsAHttpConnection.h"
45 : #include "nsAHttpTransaction.h"
46 : #include "nsXPIDLString.h"
47 : #include "nsCOMPtr.h"
48 : #include "nsAutoPtr.h"
49 : #include "prinrval.h"
50 : #include "SpdySession.h"
51 :
52 : #include "nsIStreamListener.h"
53 : #include "nsISocketTransport.h"
54 : #include "nsIAsyncInputStream.h"
55 : #include "nsIAsyncOutputStream.h"
56 : #include "nsIInterfaceRequestor.h"
57 : #include "nsIEventTarget.h"
58 :
59 : //-----------------------------------------------------------------------------
60 : // nsHttpConnection - represents a connection to a HTTP server (or proxy)
61 : //
62 : // NOTE: this objects lives on the socket thread only. it should not be
63 : // accessed from any other thread.
64 : //-----------------------------------------------------------------------------
65 :
66 : class nsHttpConnection : public nsAHttpSegmentReader
67 : , public nsAHttpSegmentWriter
68 : , public nsIInputStreamCallback
69 : , public nsIOutputStreamCallback
70 : , public nsITransportEventSink
71 : , public nsIInterfaceRequestor
72 : {
73 : public:
74 : NS_DECL_ISUPPORTS
75 : NS_DECL_NSAHTTPSEGMENTREADER
76 : NS_DECL_NSAHTTPSEGMENTWRITER
77 : NS_DECL_NSIINPUTSTREAMCALLBACK
78 : NS_DECL_NSIOUTPUTSTREAMCALLBACK
79 : NS_DECL_NSITRANSPORTEVENTSINK
80 : NS_DECL_NSIINTERFACEREQUESTOR
81 :
82 : nsHttpConnection();
83 : virtual ~nsHttpConnection();
84 :
85 : // Initialize the connection:
86 : // info - specifies the connection parameters.
87 : // maxHangTime - limits the amount of time this connection can spend on a
88 : // single transaction before it should no longer be kept
89 : // alive. a value of 0xffff indicates no limit.
90 : nsresult Init(nsHttpConnectionInfo *info, PRUint16 maxHangTime,
91 : nsISocketTransport *, nsIAsyncInputStream *,
92 : nsIAsyncOutputStream *, nsIInterfaceRequestor *,
93 : nsIEventTarget *);
94 :
95 : // Activate causes the given transaction to be processed on this
96 : // connection. It fails if there is already an existing transaction unless
97 : // a multiplexing protocol such as SPDY is being used
98 : nsresult Activate(nsAHttpTransaction *, PRUint8 caps, PRInt32 pri);
99 :
100 : // Close the underlying socket transport.
101 : void Close(nsresult reason);
102 :
103 : //-------------------------------------------------------------------------
104 : // XXX document when these are ok to call
105 :
106 2988 : bool SupportsPipelining() { return mSupportsPipelining; }
107 8977 : bool IsKeepAlive() { return mUsingSpdy ||
108 8977 : (mKeepAliveMask && mKeepAlive); }
109 : bool CanReuse(); // can this connection be reused?
110 : bool CanDirectlyActivate();
111 :
112 : // Returns time in seconds for how long connection can be reused.
113 : PRUint32 TimeToLive();
114 :
115 : void DontReuse();
116 : void DropTransport() { DontReuse(); mSocketTransport = 0; }
117 :
118 2843 : bool LastTransactionExpectedNoContent()
119 : {
120 2843 : return mLastTransactionExpectedNoContent;
121 : }
122 :
123 2832 : void SetLastTransactionExpectedNoContent(bool val)
124 : {
125 2832 : mLastTransactionExpectedNoContent = val;
126 2832 : }
127 :
128 0 : nsISocketTransport *Transport() { return mSocketTransport; }
129 0 : nsAHttpTransaction *Transaction() { return mTransaction; }
130 5977 : nsHttpConnectionInfo *ConnectionInfo() { return mConnInfo; }
131 :
132 : // nsAHttpConnection compatible methods (non-virtual):
133 : nsresult OnHeadersAvailable(nsAHttpTransaction *, nsHttpRequestHead *, nsHttpResponseHead *, bool *reset);
134 : void CloseTransaction(nsAHttpTransaction *, nsresult reason);
135 0 : void GetConnectionInfo(nsHttpConnectionInfo **ci) { NS_IF_ADDREF(*ci = mConnInfo); }
136 : nsresult TakeTransport(nsISocketTransport **,
137 : nsIAsyncInputStream **,
138 : nsIAsyncOutputStream **);
139 : void GetSecurityInfo(nsISupports **);
140 5558 : bool IsPersistent() { return IsKeepAlive(); }
141 : bool IsReused();
142 : void SetIsReusedAfter(PRUint32 afterMilliseconds);
143 1 : void SetIdleTimeout(PRIntervalTime val) {mIdleTimeout = val;}
144 : nsresult PushBack(const char *data, PRUint32 length);
145 : nsresult ResumeSend();
146 : nsresult ResumeRecv();
147 0 : PRInt64 MaxBytesRead() {return mMaxBytesRead;}
148 :
149 : static NS_METHOD ReadFromStream(nsIInputStream *, void *, const char *,
150 : PRUint32, PRUint32, PRUint32 *);
151 :
152 : // When a persistent connection is in the connection manager idle
153 : // connection pool, the nsHttpConnection still reads errors and hangups
154 : // on the socket so that it can be proactively released if the server
155 : // initiates a termination. Only call on socket thread.
156 : void BeginIdleMonitoring();
157 : void EndIdleMonitoring();
158 :
159 2988 : bool UsingSpdy() { return mUsingSpdy; }
160 :
161 : // When the connection is active this is called every 15 seconds
162 : void ReadTimeoutTick(PRIntervalTime now);
163 :
164 : private:
165 : // called to cause the underlying socket to start speaking SSL
166 : nsresult ProxyStartSSL();
167 :
168 : nsresult OnTransactionDone(nsresult reason);
169 : nsresult OnSocketWritable();
170 : nsresult OnSocketReadable();
171 :
172 : nsresult SetupProxyConnect();
173 :
174 : PRIntervalTime IdleTime();
175 : bool IsAlive();
176 : bool SupportsPipelining(nsHttpResponseHead *);
177 :
178 : // Makes certain the SSL handshake is complete and NPN negotiation
179 : // has had a chance to happen
180 : bool EnsureNPNComplete();
181 : void SetupNPN(PRUint8 caps);
182 :
183 : // Inform the connection manager of any SPDY Alternate-Protocol
184 : // redirections
185 : void HandleAlternateProtocol(nsHttpResponseHead *);
186 :
187 : // Start the Spdy transaction handler when NPN indicates spdy/2
188 : void StartSpdy();
189 :
190 : // Directly Add a transaction to an active connection for SPDY
191 : nsresult AddTransaction(nsAHttpTransaction *, PRInt32);
192 :
193 : private:
194 : nsCOMPtr<nsISocketTransport> mSocketTransport;
195 : nsCOMPtr<nsIAsyncInputStream> mSocketIn;
196 : nsCOMPtr<nsIAsyncOutputStream> mSocketOut;
197 :
198 : nsresult mSocketInCondition;
199 : nsresult mSocketOutCondition;
200 :
201 : nsCOMPtr<nsIInputStream> mProxyConnectStream;
202 : nsCOMPtr<nsIInputStream> mRequestStream;
203 :
204 : // mTransaction only points to the HTTP Transaction callbacks if the
205 : // transaction is open, otherwise it is null.
206 : nsRefPtr<nsAHttpTransaction> mTransaction;
207 :
208 : nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
209 : nsCOMPtr<nsIEventTarget> mCallbackTarget;
210 :
211 : nsRefPtr<nsHttpConnectionInfo> mConnInfo;
212 :
213 : PRUint32 mLastReadTime;
214 : PRIntervalTime mMaxHangTime; // max download time before dropping keep-alive status
215 : PRIntervalTime mIdleTimeout; // value of keep-alive: timeout=
216 : PRIntervalTime mConsiderReusedAfterInterval;
217 : PRIntervalTime mConsiderReusedAfterEpoch;
218 : PRInt64 mCurrentBytesRead; // data read per activation
219 : PRInt64 mMaxBytesRead; // max read in 1 activation
220 : PRInt64 mTotalBytesRead; // total data read
221 :
222 : nsRefPtr<nsIAsyncInputStream> mInputOverflow;
223 :
224 : bool mKeepAlive;
225 : bool mKeepAliveMask;
226 : bool mSupportsPipelining;
227 : bool mIsReused;
228 : bool mCompletedProxyConnect;
229 : bool mLastTransactionExpectedNoContent;
230 : bool mIdleMonitoring;
231 :
232 : // The number of <= HTTP/1.1 transactions performed on this connection. This
233 : // excludes spdy transactions.
234 : PRUint32 mHttp1xTransactionCount;
235 :
236 : // SPDY related
237 : bool mNPNComplete;
238 : bool mSetupNPNCalled;
239 : bool mUsingSpdy;
240 : nsRefPtr<mozilla::net::SpdySession> mSpdySession;
241 : PRInt32 mPriority;
242 : bool mReportedSpdy;
243 :
244 : // mUsingSpdy is cleared when mSpdySession is freed, this is permanent
245 : bool mEverUsedSpdy;
246 : };
247 :
248 : #endif // nsHttpConnection_h__
|