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 2975 : bool SupportsPipelining() { return mSupportsPipelining; }
107 8813 : bool IsKeepAlive() { return mUsingSpdy ||
108 8813 : (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 2830 : bool LastTransactionExpectedNoContent()
119 : {
120 2830 : return mLastTransactionExpectedNoContent;
121 : }
122 :
123 2819 : void SetLastTransactionExpectedNoContent(bool val)
124 : {
125 2819 : mLastTransactionExpectedNoContent = val;
126 2819 : }
127 :
128 0 : nsISocketTransport *Transport() { return mSocketTransport; }
129 0 : nsAHttpTransaction *Transaction() { return mTransaction; }
130 5951 : 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 5541 : 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 2975 : bool UsingSpdy() { return mUsingSpdy; }
160 :
161 : // true when connection SSL NPN phase is complete and we know
162 : // authoritatively whether UsingSpdy() or not.
163 0 : bool ReportedNPN() { return mReportedSpdy; }
164 :
165 : // When the connection is active this is called every 15 seconds
166 : void ReadTimeoutTick(PRIntervalTime now);
167 :
168 : private:
169 : // called to cause the underlying socket to start speaking SSL
170 : nsresult ProxyStartSSL();
171 :
172 : nsresult OnTransactionDone(nsresult reason);
173 : nsresult OnSocketWritable();
174 : nsresult OnSocketReadable();
175 :
176 : nsresult SetupProxyConnect();
177 :
178 : PRIntervalTime IdleTime();
179 : bool IsAlive();
180 : bool SupportsPipelining(nsHttpResponseHead *);
181 :
182 : // Makes certain the SSL handshake is complete and NPN negotiation
183 : // has had a chance to happen
184 : bool EnsureNPNComplete();
185 : void SetupNPN(PRUint8 caps);
186 :
187 : // Inform the connection manager of any SPDY Alternate-Protocol
188 : // redirections
189 : void HandleAlternateProtocol(nsHttpResponseHead *);
190 :
191 : // Start the Spdy transaction handler when NPN indicates spdy/2
192 : void StartSpdy();
193 :
194 : // Directly Add a transaction to an active connection for SPDY
195 : nsresult AddTransaction(nsAHttpTransaction *, PRInt32);
196 :
197 : private:
198 : nsCOMPtr<nsISocketTransport> mSocketTransport;
199 : nsCOMPtr<nsIAsyncInputStream> mSocketIn;
200 : nsCOMPtr<nsIAsyncOutputStream> mSocketOut;
201 :
202 : nsresult mSocketInCondition;
203 : nsresult mSocketOutCondition;
204 :
205 : nsCOMPtr<nsIInputStream> mProxyConnectStream;
206 : nsCOMPtr<nsIInputStream> mRequestStream;
207 :
208 : // mTransaction only points to the HTTP Transaction callbacks if the
209 : // transaction is open, otherwise it is null.
210 : nsRefPtr<nsAHttpTransaction> mTransaction;
211 :
212 : nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
213 : nsCOMPtr<nsIEventTarget> mCallbackTarget;
214 :
215 : nsRefPtr<nsHttpConnectionInfo> mConnInfo;
216 :
217 : PRUint32 mLastReadTime;
218 : PRIntervalTime mMaxHangTime; // max download time before dropping keep-alive status
219 : PRIntervalTime mIdleTimeout; // value of keep-alive: timeout=
220 : PRIntervalTime mConsiderReusedAfterInterval;
221 : PRIntervalTime mConsiderReusedAfterEpoch;
222 : PRInt64 mCurrentBytesRead; // data read per activation
223 : PRInt64 mMaxBytesRead; // max read in 1 activation
224 : PRInt64 mTotalBytesRead; // total data read
225 :
226 : nsRefPtr<nsIAsyncInputStream> mInputOverflow;
227 :
228 : bool mKeepAlive;
229 : bool mKeepAliveMask;
230 : bool mSupportsPipelining;
231 : bool mIsReused;
232 : bool mCompletedProxyConnect;
233 : bool mLastTransactionExpectedNoContent;
234 : bool mIdleMonitoring;
235 :
236 : // The number of <= HTTP/1.1 transactions performed on this connection. This
237 : // excludes spdy transactions.
238 : PRUint32 mHttp1xTransactionCount;
239 :
240 : // SPDY related
241 : bool mNPNComplete;
242 : bool mSetupNPNCalled;
243 : bool mUsingSpdy;
244 : nsRefPtr<mozilla::net::SpdySession> mSpdySession;
245 : PRInt32 mPriority;
246 : bool mReportedSpdy;
247 :
248 : // mUsingSpdy is cleared when mSpdySession is freed, this is permanent
249 : bool mEverUsedSpdy;
250 : };
251 :
252 : #endif // nsHttpConnection_h__
|