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 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is Mozilla.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications.
20 * Portions created by the Initial Developer are Copyright (C) 2001
21 * the Initial Developer. All Rights Reserved.
24 * Darin Fisher <darin@netscape.com> (original author)
25 * Christian Biesinger <cbiesinger@web.de>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either the GNU General Public License Version 2 or later (the "GPL"), or
29 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
41 #ifndef nsHttpChannel_h__
42 #define nsHttpChannel_h__
44 #include "nsHttpTransaction.h"
45 #include "nsHttpRequestHead.h"
46 #include "nsHttpAuthCache.h"
47 #include "nsHashPropertyBag.h"
48 #include "nsInputStreamPump.h"
49 #include "nsThreadUtils.h"
51 #include "nsAutoPtr.h"
55 #include "nsIHttpChannel.h"
56 #include "nsIHttpChannelInternal.h"
57 #include "nsIHttpHeaderVisitor.h"
58 #include "nsIHttpEventSink.h"
59 #include "nsIChannelEventSink.h"
60 #include "nsIStreamListener.h"
61 #include "nsIIOService.h"
63 #include "nsILoadGroup.h"
64 #include "nsIInterfaceRequestor.h"
65 #include "nsIInterfaceRequestorUtils.h"
66 #include "nsIInputStream.h"
67 #include "nsIProgressEventSink.h"
68 #include "nsICachingChannel.h"
69 #include "nsICacheSession.h"
70 #include "nsICacheEntryDescriptor.h"
71 #include "nsICacheListener.h"
72 #include "nsIApplicationCache.h"
73 #include "nsIApplicationCacheContainer.h"
74 #include "nsIEncodedChannel.h"
75 #include "nsITransport.h"
76 #include "nsIUploadChannel.h"
77 #include "nsIStringEnumerator.h"
78 #include "nsIOutputStream.h"
79 #include "nsIAsyncInputStream.h"
80 #include "nsIPrompt.h"
81 #include "nsIResumableChannel.h"
82 #include "nsISupportsPriority.h"
83 #include "nsIProtocolProxyCallback.h"
84 #include "nsICancelable.h"
85 #include "nsIProxiedChannel.h"
86 #include "nsITraceableChannel.h"
88 class nsHttpResponseHead
;
89 class nsAHttpConnection
;
90 class nsIHttpAuthenticator
;
93 //-----------------------------------------------------------------------------
95 //-----------------------------------------------------------------------------
97 class nsHttpChannel
: public nsHashPropertyBag
98 , public nsIHttpChannel
99 , public nsIHttpChannelInternal
100 , public nsIStreamListener
101 , public nsICachingChannel
102 , public nsIUploadChannel
103 , public nsICacheListener
104 , public nsIEncodedChannel
105 , public nsITransportEventSink
106 , public nsIResumableChannel
107 , public nsISupportsPriority
108 , public nsIProtocolProxyCallback
109 , public nsIProxiedChannel
110 , public nsITraceableChannel
111 , public nsIApplicationCacheContainer
114 NS_DECL_ISUPPORTS_INHERITED
117 NS_DECL_NSIHTTPCHANNEL
118 NS_DECL_NSIREQUESTOBSERVER
119 NS_DECL_NSISTREAMLISTENER
120 NS_DECL_NSICACHINGCHANNEL
121 NS_DECL_NSIUPLOADCHANNEL
122 NS_DECL_NSICACHELISTENER
123 NS_DECL_NSIENCODEDCHANNEL
124 NS_DECL_NSIHTTPCHANNELINTERNAL
125 NS_DECL_NSITRANSPORTEVENTSINK
126 NS_DECL_NSIRESUMABLECHANNEL
127 NS_DECL_NSISUPPORTSPRIORITY
128 NS_DECL_NSIPROTOCOLPROXYCALLBACK
129 NS_DECL_NSIPROXIEDCHANNEL
130 NS_DECL_NSITRACEABLECHANNEL
131 NS_DECL_NSIAPPLICATIONCACHECONTAINER
134 virtual ~nsHttpChannel();
136 nsresult
Init(nsIURI
*uri
,
137 PRUint8 capabilities
,
138 nsProxyInfo
* proxyInfo
);
140 public: /* internal; workaround lame compilers */
141 typedef void (nsHttpChannel:: *nsAsyncCallback
)(void);
145 // Helper function to simplify getting notification callbacks.
147 void GetCallback(nsCOMPtr
<T
> &aResult
)
149 NS_QueryNotificationCallbacks(mCallbacks
, mLoadGroup
,
150 NS_GET_TEMPLATE_IID(T
),
151 getter_AddRefs(aResult
));
154 // AsyncCall may be used to call a member function asynchronously.
155 nsresult
AsyncCall(nsAsyncCallback funcPtr
);
157 PRBool
RequestIsConditional();
158 nsresult
Connect(PRBool firstTime
= PR_TRUE
);
159 nsresult
AsyncAbort(nsresult status
);
160 // Send OnStartRequest/OnStopRequest to our listener, if any.
161 void HandleAsyncNotifyListener();
162 void DoNotifyListener();
163 nsresult
SetupTransaction();
164 void AddCookiesToRequest();
165 nsresult
ApplyContentConversions();
166 nsresult
CallOnStartRequest();
167 nsresult
ProcessResponse();
168 nsresult
ProcessNormal();
169 nsresult
ProcessNotModified();
170 nsresult
ProcessRedirection(PRUint32 httpStatus
);
171 nsresult
ProcessAuthentication(PRUint32 httpStatus
);
172 nsresult
ProcessFallback(PRBool
*fallingBack
);
173 PRBool
ResponseWouldVary();
175 // redirection specific methods
176 void HandleAsyncRedirect();
177 void HandleAsyncNotModified();
178 void HandleAsyncFallback();
179 nsresult
PromptTempRedirect();
180 nsresult
SetupReplacementChannel(nsIURI
*, nsIChannel
*, PRBool preserveMethod
);
182 // proxy specific methods
183 nsresult
ProxyFailover();
184 nsresult
DoReplaceWithProxy(nsIProxyInfo
*);
185 void HandleAsyncReplaceWithProxy();
186 nsresult
ResolveProxy();
188 // cache specific methods
189 nsresult
OpenCacheEntry(PRBool offline
, PRBool
*delayed
);
190 nsresult
OpenOfflineCacheEntryForWriting();
191 nsresult
GenerateCacheKey(PRUint32 postID
, nsACString
&key
);
192 nsresult
UpdateExpirationTime();
193 nsresult
CheckCache();
194 nsresult
ShouldUpdateOfflineCacheEntry(PRBool
*shouldCacheForOfflineUse
);
195 nsresult
ReadFromCache();
196 void CloseCacheEntry(PRBool doomOnFailure
);
197 void CloseOfflineCacheEntry();
198 nsresult
InitCacheEntry();
199 nsresult
InitOfflineCacheEntry();
200 nsresult
AddCacheEntryHeaders(nsICacheEntryDescriptor
*entry
);
201 nsresult
StoreAuthorizationMetaData(nsICacheEntryDescriptor
*entry
);
202 nsresult
FinalizeCacheEntry();
203 nsresult
InstallCacheListener(PRUint32 offset
= 0);
204 nsresult
InstallOfflineCacheListener();
205 void MaybeInvalidateCacheEntryForSubsequentGet();
206 nsCacheStoragePolicy
DetermineStoragePolicy();
208 // Handle the bogus Content-Encoding Apache sometimes sends
209 void ClearBogusContentEncodingIfNeeded();
211 // byte range request specific methods
212 nsresult
SetupByteRangeRequest(PRUint32 partialLen
);
213 nsresult
ProcessPartialContent();
214 nsresult
OnDoneReadingPartialCacheEntry(PRBool
*streamDone
);
216 // auth specific methods
217 nsresult
PrepareForAuthentication(PRBool proxyAuth
);
218 nsresult
GenCredsAndSetEntry(nsIHttpAuthenticator
*, PRBool proxyAuth
, const char *scheme
, const char *host
, PRInt32 port
, const char *dir
, const char *realm
, const char *challenge
, const nsHttpAuthIdentity
&ident
, nsCOMPtr
<nsISupports
> &session
, char **result
);
219 nsresult
GetCredentials(const char *challenges
, PRBool proxyAuth
, nsAFlatCString
&creds
);
220 nsresult
GetCredentialsForChallenge(const char *challenge
, const char *scheme
, PRBool proxyAuth
, nsIHttpAuthenticator
*auth
, nsAFlatCString
&creds
);
221 nsresult
GetAuthenticator(const char *challenge
, nsCString
&scheme
, nsIHttpAuthenticator
**auth
);
222 void ParseRealm(const char *challenge
, nsACString
&realm
);
223 void GetIdentityFromURI(PRUint32 authFlags
, nsHttpAuthIdentity
&);
224 nsresult
PromptForIdentity(PRUint32 level
, PRBool proxyAuth
, const char *realm
, const char *authType
, PRUint32 authFlags
, nsHttpAuthIdentity
&);
225 PRBool
ConfirmAuth(const nsString
&bundleKey
, PRBool doYesNoPrompt
);
226 void CheckForSuperfluousAuth();
227 void SetAuthorizationHeader(nsHttpAuthCache
*, nsHttpAtom header
, const char *scheme
, const char *host
, PRInt32 port
, const char *path
, nsHttpAuthIdentity
&ident
);
228 void AddAuthorizationHeaders();
229 nsresult
GetCurrentPath(nsACString
&);
230 nsresult
DoAuthRetry(nsAHttpConnection
*);
233 nsCOMPtr
<nsIURI
> mOriginalURI
;
234 nsCOMPtr
<nsIURI
> mURI
;
235 nsCOMPtr
<nsIURI
> mDocumentURI
;
236 nsCOMPtr
<nsIStreamListener
> mListener
;
237 nsCOMPtr
<nsISupports
> mListenerContext
;
238 nsCOMPtr
<nsILoadGroup
> mLoadGroup
;
239 nsCOMPtr
<nsISupports
> mOwner
;
240 nsCOMPtr
<nsIInterfaceRequestor
> mCallbacks
;
241 nsCOMPtr
<nsIProgressEventSink
> mProgressSink
;
242 nsCOMPtr
<nsIInputStream
> mUploadStream
;
243 nsCOMPtr
<nsIURI
> mReferrer
;
244 nsCOMPtr
<nsISupports
> mSecurityInfo
;
245 nsCOMPtr
<nsICancelable
> mProxyRequest
;
247 nsHttpRequestHead mRequestHead
;
248 nsHttpResponseHead
*mResponseHead
;
250 nsRefPtr
<nsInputStreamPump
> mTransactionPump
;
251 nsHttpTransaction
*mTransaction
; // hard ref
252 nsHttpConnectionInfo
*mConnectionInfo
; // hard ref
254 nsCString mSpec
; // ASCII encoded URL spec
258 nsUint64 mLogicalOffset
;
262 nsCString mContentTypeHint
;
263 nsCString mContentCharsetHint
;
264 nsCString mUserSetCookieHeader
;
266 // cache specific data
267 nsCOMPtr
<nsICacheEntryDescriptor
> mCacheEntry
;
268 nsRefPtr
<nsInputStreamPump
> mCachePump
;
269 nsHttpResponseHead
*mCachedResponseHead
;
270 nsCacheAccessMode mCacheAccess
;
272 PRUint32 mRequestTime
;
274 nsCOMPtr
<nsICacheEntryDescriptor
> mOfflineCacheEntry
;
275 nsCacheAccessMode mOfflineCacheAccess
;
276 nsCString mOfflineCacheClientID
;
278 nsCOMPtr
<nsIApplicationCache
> mApplicationCache
;
280 // auth specific data
281 nsISupports
*mProxyAuthContinuationState
;
282 nsCString mProxyAuthType
;
283 nsISupports
*mAuthContinuationState
;
285 nsHttpAuthIdentity mIdent
;
286 nsHttpAuthIdentity mProxyIdent
;
288 // Resumable channel specific data
292 // Function pointer that can be set to indicate that we got suspended while
293 // waiting on an AsyncCall. When we get resumed we should AsyncCall this
295 nsAsyncCallback mPendingAsyncCallOnResume
;
297 // Proxy info to replace with
298 nsCOMPtr
<nsIProxyInfo
> mTargetProxyInfo
;
300 // Suspend counter. This is used if someone tries to suspend/resume us
301 // before we have either a cache pump or a transaction pump.
302 PRUint32 mSuspendCount
;
304 // redirection specific data.
305 PRUint8 mRedirectionLimit
;
307 // If the channel is associated with a cache, and the URI matched
308 // a fallback namespace, this will hold the key for the fallback
310 nsCString mFallbackKey
;
313 PRUint32 mIsPending
: 1;
314 PRUint32 mWasOpened
: 1;
315 PRUint32 mApplyConversion
: 1;
316 PRUint32 mAllowPipelining
: 1;
317 PRUint32 mCachedContentIsValid
: 1;
318 PRUint32 mCachedContentIsPartial
: 1;
319 PRUint32 mResponseHeadersModified
: 1;
320 PRUint32 mCanceled
: 1;
321 PRUint32 mTransactionReplaced
: 1;
322 PRUint32 mUploadStreamHasHeaders
: 1;
323 PRUint32 mAuthRetryPending
: 1;
324 PRUint32 mSuppressDefensiveAuth
: 1;
325 PRUint32 mResuming
: 1;
326 PRUint32 mInitedCacheEntry
: 1;
327 PRUint32 mCacheForOfflineUse
: 1;
328 // True if mCacheForOfflineUse was set because we were caching
329 // opportunistically.
330 PRUint32 mCachingOpportunistically
: 1;
331 // True if we are loading a fallback cache entry from the
332 // application cache.
333 PRUint32 mFallbackChannel
: 1;
334 PRUint32 mTracingEnabled
: 1;
336 class nsContentEncodings
: public nsIUTF8StringEnumerator
340 NS_DECL_NSIUTF8STRINGENUMERATOR
342 nsContentEncodings(nsIHttpChannel
* aChannel
, const char* aEncodingHeader
);
343 virtual ~nsContentEncodings();
346 nsresult
PrepareForNext(void);
348 // We do not own the buffer. The channel owns it.
349 const char* mEncodingHeader
;
350 const char* mCurStart
; // points to start of current header
351 const char* mCurEnd
; // points to end of current header
353 // Hold a ref to our channel so that it can't go away and take the
355 nsCOMPtr
<nsIHttpChannel
> mChannel
;
361 #endif // nsHttpChannel_h__