Thu, 15 Jan 2015 21:03:48 +0100
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 nsHttpHandler_h__
7 #define nsHttpHandler_h__
9 #include "nsHttp.h"
10 #include "nsHttpAuthCache.h"
11 #include "nsHttpConnectionMgr.h"
12 #include "ASpdySession.h"
14 #include "nsString.h"
15 #include "nsCOMPtr.h"
16 #include "nsWeakReference.h"
18 #include "nsIHttpProtocolHandler.h"
19 #include "nsIObserver.h"
20 #include "nsISpeculativeConnect.h"
21 #include "nsICache.h"
23 class nsIHttpChannel;
24 class nsIPrefBranch;
25 class nsICancelable;
26 class nsICookieService;
27 class nsIIOService;
28 class nsIObserverService;
29 class nsISiteSecurityService;
30 class nsIStreamConverterService;
31 class nsITimer;
33 namespace mozilla {
34 namespace net {
35 class ATokenBucketEvent;
36 class EventTokenBucket;
37 class Tickler;
38 class nsHttpConnection;
39 class nsHttpConnectionInfo;
40 class nsHttpTransaction;
42 //-----------------------------------------------------------------------------
43 // nsHttpHandler - protocol handler for HTTP and HTTPS
44 //-----------------------------------------------------------------------------
46 class nsHttpHandler : public nsIHttpProtocolHandler
47 , public nsIObserver
48 , public nsSupportsWeakReference
49 , public nsISpeculativeConnect
50 {
51 public:
52 NS_DECL_THREADSAFE_ISUPPORTS
53 NS_DECL_NSIPROTOCOLHANDLER
54 NS_DECL_NSIPROXIEDPROTOCOLHANDLER
55 NS_DECL_NSIHTTPPROTOCOLHANDLER
56 NS_DECL_NSIOBSERVER
57 NS_DECL_NSISPECULATIVECONNECT
59 nsHttpHandler();
60 virtual ~nsHttpHandler();
62 nsresult Init();
63 nsresult AddStandardRequestHeaders(nsHttpHeaderArray *);
64 nsresult AddConnectionHeader(nsHttpHeaderArray *,
65 uint32_t capabilities);
66 bool IsAcceptableEncoding(const char *encoding);
68 const nsAFlatCString &UserAgent();
70 nsHttpVersion HttpVersion() { return mHttpVersion; }
71 nsHttpVersion ProxyHttpVersion() { return mProxyHttpVersion; }
72 uint8_t ReferrerLevel() { return mReferrerLevel; }
73 bool SpoofReferrerSource() { return mSpoofReferrerSource; }
74 uint8_t ReferrerTrimmingPolicy() { return mReferrerTrimmingPolicy; }
75 uint8_t ReferrerXOriginPolicy() { return mReferrerXOriginPolicy; }
76 bool SendSecureXSiteReferrer() { return mSendSecureXSiteReferrer; }
77 uint8_t RedirectionLimit() { return mRedirectionLimit; }
78 PRIntervalTime IdleTimeout() { return mIdleTimeout; }
79 PRIntervalTime SpdyTimeout() { return mSpdyTimeout; }
80 PRIntervalTime ResponseTimeout() {
81 return mResponseTimeoutEnabled ? mResponseTimeout : 0;
82 }
83 PRIntervalTime ResponseTimeoutEnabled() { return mResponseTimeoutEnabled; }
84 uint16_t MaxRequestAttempts() { return mMaxRequestAttempts; }
85 const char *DefaultSocketType() { return mDefaultSocketType.get(); /* ok to return null */ }
86 uint32_t PhishyUserPassLength() { return mPhishyUserPassLength; }
87 uint8_t GetQoSBits() { return mQoSBits; }
88 uint16_t GetIdleSynTimeout() { return mIdleSynTimeout; }
89 bool FastFallbackToIPv4() { return mFastFallbackToIPv4; }
90 bool ProxyPipelining() { return mProxyPipelining; }
91 uint32_t MaxSocketCount();
92 bool EnforceAssocReq() { return mEnforceAssocReq; }
94 bool IsPersistentHttpsCachingEnabled() { return mEnablePersistentHttpsCaching; }
95 bool IsTelemetryEnabled() { return mTelemetryEnabled; }
96 bool AllowExperiments() { return mTelemetryEnabled && mAllowExperiments; }
98 bool IsSpdyEnabled() { return mEnableSpdy; }
99 bool IsSpdyV3Enabled() { return mSpdyV3; }
100 bool IsSpdyV31Enabled() { return mSpdyV31; }
101 bool IsHttp2DraftEnabled() { return mHttp2DraftEnabled; }
102 bool EnforceHttp2TlsProfile() { return mEnforceHttp2TlsProfile; }
103 bool CoalesceSpdy() { return mCoalesceSpdy; }
104 bool UseSpdyPersistentSettings() { return mSpdyPersistentSettings; }
105 uint32_t SpdySendingChunkSize() { return mSpdySendingChunkSize; }
106 uint32_t SpdySendBufferSize() { return mSpdySendBufferSize; }
107 uint32_t SpdyPushAllowance() { return mSpdyPushAllowance; }
108 PRIntervalTime SpdyPingThreshold() { return mSpdyPingThreshold; }
109 PRIntervalTime SpdyPingTimeout() { return mSpdyPingTimeout; }
110 bool AllowPush() { return mAllowPush; }
111 uint32_t ConnectTimeout() { return mConnectTimeout; }
112 uint32_t ParallelSpeculativeConnectLimit() { return mParallelSpeculativeConnectLimit; }
113 bool CriticalRequestPrioritization() { return mCriticalRequestPrioritization; }
114 double BypassCacheLockThreshold() { return mBypassCacheLockThreshold; }
116 bool UseRequestTokenBucket() { return mRequestTokenBucketEnabled; }
117 uint16_t RequestTokenBucketMinParallelism() { return mRequestTokenBucketMinParallelism; }
118 uint32_t RequestTokenBucketHz() { return mRequestTokenBucketHz; }
119 uint32_t RequestTokenBucketBurst() {return mRequestTokenBucketBurst; }
121 bool PromptTempRedirect() { return mPromptTempRedirect; }
123 // TCP Keepalive configuration values.
125 // Returns true if TCP keepalive should be enabled for short-lived conns.
126 bool TCPKeepaliveEnabledForShortLivedConns() {
127 return mTCPKeepaliveShortLivedEnabled;
128 }
129 // Return time (secs) that a connection is consider short lived (for TCP
130 // keepalive purposes). After this time, the connection is long-lived.
131 int32_t GetTCPKeepaliveShortLivedTime() {
132 return mTCPKeepaliveShortLivedTimeS;
133 }
134 // Returns time (secs) before first TCP keepalive probes should be sent;
135 // same time used between successful keepalive probes.
136 int32_t GetTCPKeepaliveShortLivedIdleTime() {
137 return mTCPKeepaliveShortLivedIdleTimeS;
138 }
140 // Returns true if TCP keepalive should be enabled for long-lived conns.
141 bool TCPKeepaliveEnabledForLongLivedConns() {
142 return mTCPKeepaliveLongLivedEnabled;
143 }
144 // Returns time (secs) before first TCP keepalive probes should be sent;
145 // same time used between successful keepalive probes.
146 int32_t GetTCPKeepaliveLongLivedIdleTime() {
147 return mTCPKeepaliveLongLivedIdleTimeS;
148 }
150 nsHttpAuthCache *AuthCache(bool aPrivate) {
151 return aPrivate ? &mPrivateAuthCache : &mAuthCache;
152 }
153 nsHttpConnectionMgr *ConnMgr() { return mConnMgr; }
155 // cache support
156 bool UseCache() const { return mUseCache; }
157 uint32_t GenerateUniqueID() { return ++mLastUniqueID; }
158 uint32_t SessionStartTime() { return mSessionStartTime; }
160 //
161 // Connection management methods:
162 //
163 // - the handler only owns idle connections; it does not own active
164 // connections.
165 //
166 // - the handler keeps a count of active connections to enforce the
167 // steady-state max-connections pref.
168 //
170 // Called to kick-off a new transaction, by default the transaction
171 // will be put on the pending transaction queue if it cannot be
172 // initiated at this time. Callable from any thread.
173 nsresult InitiateTransaction(nsHttpTransaction *trans, int32_t priority)
174 {
175 return mConnMgr->AddTransaction(trans, priority);
176 }
178 // Called to change the priority of an existing transaction that has
179 // already been initiated.
180 nsresult RescheduleTransaction(nsHttpTransaction *trans, int32_t priority)
181 {
182 return mConnMgr->RescheduleTransaction(trans, priority);
183 }
185 // Called to cancel a transaction, which may or may not be assigned to
186 // a connection. Callable from any thread.
187 nsresult CancelTransaction(nsHttpTransaction *trans, nsresult reason)
188 {
189 return mConnMgr->CancelTransaction(trans, reason);
190 }
192 // Called when a connection is done processing a transaction. Callable
193 // from any thread.
194 nsresult ReclaimConnection(nsHttpConnection *conn)
195 {
196 return mConnMgr->ReclaimConnection(conn);
197 }
199 nsresult ProcessPendingQ(nsHttpConnectionInfo *cinfo)
200 {
201 return mConnMgr->ProcessPendingQ(cinfo);
202 }
204 nsresult ProcessPendingQ()
205 {
206 return mConnMgr->ProcessPendingQ();
207 }
209 nsresult GetSocketThreadTarget(nsIEventTarget **target)
210 {
211 return mConnMgr->GetSocketThreadTarget(target);
212 }
214 nsresult SpeculativeConnect(nsHttpConnectionInfo *ci,
215 nsIInterfaceRequestor *callbacks,
216 uint32_t caps = 0)
217 {
218 TickleWifi(callbacks);
219 return mConnMgr->SpeculativeConnect(ci, callbacks, caps);
220 }
222 //
223 // The HTTP handler caches pointers to specific XPCOM services, and
224 // provides the following helper routines for accessing those services:
225 //
226 nsresult GetStreamConverterService(nsIStreamConverterService **);
227 nsresult GetIOService(nsIIOService** service);
228 nsICookieService * GetCookieService(); // not addrefed
229 nsISiteSecurityService * GetSSService();
231 // callable from socket thread only
232 uint32_t Get32BitsOfPseudoRandom();
234 // Called by the channel synchronously during asyncOpen
235 void OnOpeningRequest(nsIHttpChannel *chan)
236 {
237 NotifyObservers(chan, NS_HTTP_ON_OPENING_REQUEST_TOPIC);
238 }
240 // Called by the channel before writing a request
241 void OnModifyRequest(nsIHttpChannel *chan)
242 {
243 NotifyObservers(chan, NS_HTTP_ON_MODIFY_REQUEST_TOPIC);
244 }
246 // Called by the channel once headers are available
247 void OnExamineResponse(nsIHttpChannel *chan)
248 {
249 NotifyObservers(chan, NS_HTTP_ON_EXAMINE_RESPONSE_TOPIC);
250 }
252 // Called by the channel once headers have been merged with cached headers
253 void OnExamineMergedResponse(nsIHttpChannel *chan)
254 {
255 NotifyObservers(chan, NS_HTTP_ON_EXAMINE_MERGED_RESPONSE_TOPIC);
256 }
258 // Called by channels before a redirect happens. This notifies both the
259 // channel's and the global redirect observers.
260 nsresult AsyncOnChannelRedirect(nsIChannel* oldChan, nsIChannel* newChan,
261 uint32_t flags);
263 // Called by the channel when the response is read from the cache without
264 // communicating with the server.
265 void OnExamineCachedResponse(nsIHttpChannel *chan)
266 {
267 NotifyObservers(chan, NS_HTTP_ON_EXAMINE_CACHED_RESPONSE_TOPIC);
268 }
270 // Generates the host:port string for use in the Host: header as well as the
271 // CONNECT line for proxies. This handles IPv6 literals correctly.
272 static nsresult GenerateHostPort(const nsCString& host, int32_t port,
273 nsCString& hostLine);
275 bool GetPipelineAggressive() { return mPipelineAggressive; }
276 uint32_t GetMaxPipelinedRequests() { return mMaxPipelinedRequests; }
277 uint32_t GetMaxOptimisticPipelinedRequests() { return mMaxOptimisticPipelinedRequests; }
278 void GetMaxPipelineObjectSize(int64_t *outVal)
279 {
280 *outVal = mMaxPipelineObjectSize;
281 }
283 bool GetPipelineEnabled()
284 {
285 return mCapabilities & NS_HTTP_ALLOW_PIPELINING;
286 }
288 bool GetPipelineRescheduleOnTimeout()
289 {
290 return mPipelineRescheduleOnTimeout;
291 }
293 PRIntervalTime GetPipelineRescheduleTimeout()
294 {
295 return mPipelineRescheduleTimeout;
296 }
298 PRIntervalTime GetPipelineTimeout() { return mPipelineReadTimeout; }
300 SpdyInformation *SpdyInfo() { return &mSpdyInfo; }
302 // returns true in between Init and Shutdown states
303 bool Active() { return mHandlerActive; }
305 static void GetCacheSessionNameForStoragePolicy(
306 nsCacheStoragePolicy storagePolicy,
307 bool isPrivate,
308 uint32_t appId,
309 bool inBrowser,
310 nsACString& sessionName);
312 // When the disk cache is responding slowly its use is suppressed
313 // for 1 minute for most requests. Callable from main thread only.
314 TimeStamp GetCacheSkippedUntil() { return mCacheSkippedUntil; }
315 void SetCacheSkippedUntil(TimeStamp arg) { mCacheSkippedUntil = arg; }
316 void ClearCacheSkippedUntil() { mCacheSkippedUntil = TimeStamp(); }
318 private:
320 //
321 // Useragent/prefs helper methods
322 //
323 void BuildUserAgent();
324 void InitUserAgentComponents();
325 void PrefsChanged(nsIPrefBranch *prefs, const char *pref);
327 nsresult SetAccept(const char *);
328 nsresult SetAcceptLanguages(const char *);
329 nsresult SetAcceptEncodings(const char *);
331 nsresult InitConnectionMgr();
333 void NotifyObservers(nsIHttpChannel *chan, const char *event);
335 static void TimerCallback(nsITimer * aTimer, void * aClosure);
336 private:
338 // cached services
339 nsMainThreadPtrHandle<nsIIOService> mIOService;
340 nsMainThreadPtrHandle<nsIStreamConverterService> mStreamConvSvc;
341 nsMainThreadPtrHandle<nsIObserverService> mObserverService;
342 nsMainThreadPtrHandle<nsICookieService> mCookieService;
343 nsMainThreadPtrHandle<nsISiteSecurityService> mSSService;
345 // the authentication credentials cache
346 nsHttpAuthCache mAuthCache;
347 nsHttpAuthCache mPrivateAuthCache;
349 // the connection manager
350 nsHttpConnectionMgr *mConnMgr;
352 //
353 // prefs
354 //
356 uint8_t mHttpVersion;
357 uint8_t mProxyHttpVersion;
358 uint32_t mCapabilities;
359 uint8_t mReferrerLevel;
360 uint8_t mSpoofReferrerSource;
361 uint8_t mReferrerTrimmingPolicy;
362 uint8_t mReferrerXOriginPolicy;
364 bool mFastFallbackToIPv4;
365 bool mProxyPipelining;
366 PRIntervalTime mIdleTimeout;
367 PRIntervalTime mSpdyTimeout;
368 PRIntervalTime mResponseTimeout;
369 bool mResponseTimeoutEnabled;
371 uint16_t mMaxRequestAttempts;
372 uint16_t mMaxRequestDelay;
373 uint16_t mIdleSynTimeout;
375 bool mPipeliningEnabled;
376 uint16_t mMaxConnections;
377 uint8_t mMaxPersistentConnectionsPerServer;
378 uint8_t mMaxPersistentConnectionsPerProxy;
379 uint16_t mMaxPipelinedRequests;
380 uint16_t mMaxOptimisticPipelinedRequests;
381 bool mPipelineAggressive;
382 int64_t mMaxPipelineObjectSize;
383 bool mPipelineRescheduleOnTimeout;
384 PRIntervalTime mPipelineRescheduleTimeout;
385 PRIntervalTime mPipelineReadTimeout;
386 nsCOMPtr<nsITimer> mPipelineTestTimer;
388 uint8_t mRedirectionLimit;
390 // we'll warn the user if we load an URL containing a userpass field
391 // unless its length is less than this threshold. this warning is
392 // intended to protect the user against spoofing attempts that use
393 // the userpass field of the URL to obscure the actual origin server.
394 uint8_t mPhishyUserPassLength;
396 uint8_t mQoSBits;
398 bool mPipeliningOverSSL;
399 bool mEnforceAssocReq;
401 nsCString mAccept;
402 nsCString mAcceptLanguages;
403 nsCString mAcceptEncodings;
405 nsXPIDLCString mDefaultSocketType;
407 // cache support
408 uint32_t mLastUniqueID;
409 uint32_t mSessionStartTime;
411 // useragent components
412 nsCString mLegacyAppName;
413 nsCString mLegacyAppVersion;
414 nsCString mPlatform;
415 nsCString mOscpu;
416 nsCString mMisc;
417 nsCString mProduct;
418 nsXPIDLCString mProductSub;
419 nsXPIDLCString mAppName;
420 nsXPIDLCString mAppVersion;
421 nsCString mCompatFirefox;
422 bool mCompatFirefoxEnabled;
423 nsXPIDLCString mCompatDevice;
425 nsCString mUserAgent;
426 nsXPIDLCString mUserAgentOverride;
427 bool mUserAgentIsDirty; // true if mUserAgent should be rebuilt
429 bool mUseCache;
431 bool mPromptTempRedirect;
432 // mSendSecureXSiteReferrer: default is false,
433 // if true allow referrer headers between secure non-matching hosts
434 bool mSendSecureXSiteReferrer;
436 // Persistent HTTPS caching flag
437 bool mEnablePersistentHttpsCaching;
439 // For broadcasting tracking preference
440 bool mDoNotTrackEnabled;
441 uint8_t mDoNotTrackValue;
443 // for broadcasting safe hint;
444 bool mSafeHintEnabled;
445 bool mParentalControlEnabled;
447 // Whether telemetry is reported or not
448 uint32_t mTelemetryEnabled : 1;
450 // The value of network.allow-experiments
451 uint32_t mAllowExperiments : 1;
453 // true in between init and shutdown states
454 uint32_t mHandlerActive : 1;
456 uint32_t mEnableSpdy : 1;
457 uint32_t mSpdyV3 : 1;
458 uint32_t mSpdyV31 : 1;
459 uint32_t mHttp2DraftEnabled : 1;
460 uint32_t mEnforceHttp2TlsProfile : 1;
461 uint32_t mCoalesceSpdy : 1;
462 uint32_t mSpdyPersistentSettings : 1;
463 uint32_t mAllowPush : 1;
465 // Try to use SPDY features instead of HTTP/1.1 over SSL
466 SpdyInformation mSpdyInfo;
468 uint32_t mSpdySendingChunkSize;
469 uint32_t mSpdySendBufferSize;
470 uint32_t mSpdyPushAllowance;
471 PRIntervalTime mSpdyPingThreshold;
472 PRIntervalTime mSpdyPingTimeout;
474 // The maximum amount of time to wait for socket transport to be
475 // established. In milliseconds.
476 uint32_t mConnectTimeout;
478 // The maximum amount of time the nsICacheSession lock can be held
479 // before a new transaction bypasses the cache. In milliseconds.
480 double mBypassCacheLockThreshold;
482 // The maximum number of current global half open sockets allowable
483 // when starting a new speculative connection.
484 uint32_t mParallelSpeculativeConnectLimit;
486 // For Rate Pacing of HTTP/1 requests through a netwerk/base/src/EventTokenBucket
487 // Active requests <= *MinParallelism are not subject to the rate pacing
488 bool mRequestTokenBucketEnabled;
489 uint16_t mRequestTokenBucketMinParallelism;
490 uint32_t mRequestTokenBucketHz; // EventTokenBucket HZ
491 uint32_t mRequestTokenBucketBurst; // EventTokenBucket Burst
493 // Whether or not to block requests for non head js/css items (e.g. media)
494 // while those elements load.
495 bool mCriticalRequestPrioritization;
497 // When the disk cache is responding slowly its use is suppressed
498 // for 1 minute for most requests.
499 TimeStamp mCacheSkippedUntil;
501 // TCP Keepalive configuration values.
503 // True if TCP keepalive is enabled for short-lived conns.
504 bool mTCPKeepaliveShortLivedEnabled;
505 // Time (secs) indicating how long a conn is considered short-lived.
506 int32_t mTCPKeepaliveShortLivedTimeS;
507 // Time (secs) before first keepalive probe; between successful probes.
508 int32_t mTCPKeepaliveShortLivedIdleTimeS;
510 // True if TCP keepalive is enabled for long-lived conns.
511 bool mTCPKeepaliveLongLivedEnabled;
512 // Time (secs) before first keepalive probe; between successful probes.
513 int32_t mTCPKeepaliveLongLivedIdleTimeS;
515 private:
516 // For Rate Pacing Certain Network Events. Only assign this pointer on
517 // socket thread.
518 void MakeNewRequestTokenBucket();
519 nsRefPtr<EventTokenBucket> mRequestTokenBucket;
521 public:
522 // Socket thread only
523 nsresult SubmitPacedRequest(ATokenBucketEvent *event,
524 nsICancelable **cancel)
525 {
526 if (!mRequestTokenBucket)
527 return NS_ERROR_UNEXPECTED;
528 return mRequestTokenBucket->SubmitEvent(event, cancel);
529 }
531 // Socket thread only
532 void SetRequestTokenBucket(EventTokenBucket *aTokenBucket)
533 {
534 mRequestTokenBucket = aTokenBucket;
535 }
537 private:
538 nsRefPtr<Tickler> mWifiTickler;
539 void TickleWifi(nsIInterfaceRequestor *cb);
540 };
542 extern nsHttpHandler *gHttpHandler;
544 //-----------------------------------------------------------------------------
545 // nsHttpsHandler - thin wrapper to distinguish the HTTP handler from the
546 // HTTPS handler (even though they share the same impl).
547 //-----------------------------------------------------------------------------
549 class nsHttpsHandler : public nsIHttpProtocolHandler
550 , public nsSupportsWeakReference
551 , public nsISpeculativeConnect
552 {
553 public:
554 // we basically just want to override GetScheme and GetDefaultPort...
555 // all other methods should be forwarded to the nsHttpHandler instance.
557 NS_DECL_THREADSAFE_ISUPPORTS
558 NS_DECL_NSIPROTOCOLHANDLER
559 NS_FORWARD_NSIPROXIEDPROTOCOLHANDLER (gHttpHandler->)
560 NS_FORWARD_NSIHTTPPROTOCOLHANDLER (gHttpHandler->)
561 NS_FORWARD_NSISPECULATIVECONNECT (gHttpHandler->)
563 nsHttpsHandler() { }
564 virtual ~nsHttpsHandler() { }
566 nsresult Init();
567 };
569 }} // namespace mozilla::net
571 #endif // nsHttpHandler_h__