LCOV - code coverage report
Current view: directory - netwerk/protocol/http - nsHttpHandler.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 660 562 85.2 %
Date: 2012-06-02 Functions: 56 45 80.4 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 : /* vim:set ts=4 sw=4 sts=4 et cin: */
       3                 : /* ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       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/
      10                 :  *
      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
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is Mozilla.
      17                 :  *
      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.
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *   Darin Fisher <darin@netscape.com> (original author)
      25                 :  *   Gagan Saksena <gagan@netscape.com>
      26                 :  *   Pierre Phaneuf <pp@ludusdesign.com>
      27                 :  *   Christopher Blizzard <blizzard@mozilla.org>
      28                 :  *   Adrian Havill <havill@redhat.com>
      29                 :  *   Gervase Markham <gerv@gerv.net>
      30                 :  *   Bradley Baetz <bbaetz@netscape.com>
      31                 :  *   Benjamin Smedberg <bsmedberg@covad.net>
      32                 :  *   Josh Aas <josh@mozilla.com>
      33                 :  *   Dão Gottwald <dao@mozilla.com>
      34                 :  *
      35                 :  * Alternatively, the contents of this file may be used under the terms of
      36                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      37                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      38                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      39                 :  * of those above. If you wish to allow use of your version of this file only
      40                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      41                 :  * use your version of this file under the terms of the MPL, indicate your
      42                 :  * decision by deleting the provisions above and replace them with the notice
      43                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      44                 :  * the provisions above, a recipient may use your version of this file under
      45                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      46                 :  *
      47                 :  * ***** END LICENSE BLOCK ***** */
      48                 : 
      49                 : #include "nsHttp.h"
      50                 : #include "nsHttpHandler.h"
      51                 : #include "nsHttpChannel.h"
      52                 : #include "nsHttpConnection.h"
      53                 : #include "nsHttpResponseHead.h"
      54                 : #include "nsHttpTransaction.h"
      55                 : #include "nsHttpAuthCache.h"
      56                 : #include "nsStandardURL.h"
      57                 : #include "nsIHttpChannel.h"
      58                 : #include "nsIURL.h"
      59                 : #include "nsIStandardURL.h"
      60                 : #include "nsICacheService.h"
      61                 : #include "nsICategoryManager.h"
      62                 : #include "nsCategoryManagerUtils.h"
      63                 : #include "nsICacheService.h"
      64                 : #include "nsIPrefService.h"
      65                 : #include "nsIPrefBranch.h"
      66                 : #include "nsIPrefLocalizedString.h"
      67                 : #include "nsISocketProviderService.h"
      68                 : #include "nsISocketProvider.h"
      69                 : #include "nsPrintfCString.h"
      70                 : #include "nsCOMPtr.h"
      71                 : #include "nsNetCID.h"
      72                 : #include "prprf.h"
      73                 : #include "nsReadableUtils.h"
      74                 : #include "nsQuickSort.h"
      75                 : #include "nsNetUtil.h"
      76                 : #include "nsIOService.h"
      77                 : #include "nsAsyncRedirectVerifyHelper.h"
      78                 : #include "nsSocketTransportService2.h"
      79                 : #include "nsAlgorithm.h"
      80                 : #include "SpdySession.h"
      81                 : 
      82                 : #include "nsIXULAppInfo.h"
      83                 : 
      84                 : #include "mozilla/net/NeckoChild.h"
      85                 : 
      86                 : #if defined(XP_UNIX)
      87                 : #include <sys/utsname.h>
      88                 : #endif
      89                 : 
      90                 : #if defined(XP_WIN)
      91                 : #include <windows.h>
      92                 : #endif
      93                 : 
      94                 : #if defined(XP_MACOSX)
      95                 : #include <CoreServices/CoreServices.h>
      96                 : #endif
      97                 : 
      98                 : #if defined(XP_OS2)
      99                 : #define INCL_DOSMISC
     100                 : #include <os2.h>
     101                 : #endif
     102                 : 
     103                 : //-----------------------------------------------------------------------------
     104                 : using namespace mozilla;
     105                 : using namespace mozilla::net;
     106                 : #include "mozilla/net/HttpChannelChild.h"
     107                 : 
     108                 : #include "mozilla/FunctionTimer.h"
     109                 : 
     110                 : #ifdef DEBUG
     111                 : // defined by the socket transport service while active
     112                 : extern PRThread *gSocketThread;
     113                 : #endif
     114                 : 
     115                 : static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
     116                 : static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID);
     117                 : static NS_DEFINE_CID(kCookieServiceCID, NS_COOKIESERVICE_CID);
     118                 : static NS_DEFINE_CID(kCacheServiceCID, NS_CACHESERVICE_CID);
     119                 : static NS_DEFINE_CID(kSocketProviderServiceCID, NS_SOCKETPROVIDERSERVICE_CID);
     120                 : 
     121                 : #define UA_PREF_PREFIX          "general.useragent."
     122                 : #ifdef XP_WIN
     123                 : #define UA_SPARE_PLATFORM
     124                 : #endif
     125                 : 
     126                 : #define HTTP_PREF_PREFIX        "network.http."
     127                 : #define INTL_ACCEPT_LANGUAGES   "intl.accept_languages"
     128                 : #define NETWORK_ENABLEIDN       "network.enableIDN"
     129                 : #define BROWSER_PREF_PREFIX     "browser.cache."
     130                 : #define DONOTTRACK_HEADER_ENABLED "privacy.donottrackheader.enabled"
     131                 : #define TELEMETRY_ENABLED        "toolkit.telemetry.enabled"
     132                 : #define ALLOW_EXPERIMENTS        "network.allow-experiments"
     133                 : 
     134                 : #define UA_PREF(_pref) UA_PREF_PREFIX _pref
     135                 : #define HTTP_PREF(_pref) HTTP_PREF_PREFIX _pref
     136                 : #define BROWSER_PREF(_pref) BROWSER_PREF_PREFIX _pref
     137                 : 
     138                 : #define NS_HTTP_PROTOCOL_FLAGS (URI_STD | ALLOWS_PROXY | ALLOWS_PROXY_HTTP | URI_LOADABLE_BY_ANYONE)
     139                 : 
     140                 : //-----------------------------------------------------------------------------
     141                 : 
     142                 : static nsresult
     143           35064 : NewURI(const nsACString &aSpec,
     144                 :        const char *aCharset,
     145                 :        nsIURI *aBaseURI,
     146                 :        PRInt32 aDefaultPort,
     147                 :        nsIURI **aURI)
     148                 : {
     149           35064 :     nsStandardURL *url = new nsStandardURL();
     150           35064 :     if (!url)
     151               0 :         return NS_ERROR_OUT_OF_MEMORY;
     152           35064 :     NS_ADDREF(url);
     153                 : 
     154                 :     nsresult rv = url->Init(nsIStandardURL::URLTYPE_AUTHORITY,
     155           35064 :                             aDefaultPort, aSpec, aCharset, aBaseURI);
     156           35064 :     if (NS_FAILED(rv)) {
     157              36 :         NS_RELEASE(url);
     158              36 :         return rv;
     159                 :     }
     160                 : 
     161           35028 :     *aURI = url; // no QI needed
     162           35028 :     return NS_OK;
     163                 : }
     164                 : 
     165                 : //-----------------------------------------------------------------------------
     166                 : // nsHttpHandler <public>
     167                 : //-----------------------------------------------------------------------------
     168                 : 
     169                 : nsHttpHandler *gHttpHandler = nsnull;
     170                 : 
     171             679 : nsHttpHandler::nsHttpHandler()
     172                 :     : mConnMgr(nsnull)
     173                 :     , mHttpVersion(NS_HTTP_VERSION_1_1)
     174                 :     , mProxyHttpVersion(NS_HTTP_VERSION_1_1)
     175                 :     , mCapabilities(NS_HTTP_ALLOW_KEEPALIVE)
     176                 :     , mProxyCapabilities(NS_HTTP_ALLOW_KEEPALIVE)
     177                 :     , mReferrerLevel(0xff) // by default we always send a referrer
     178                 :     , mFastFallbackToIPv4(false)
     179             679 :     , mIdleTimeout(PR_SecondsToInterval(10))
     180             679 :     , mSpdyTimeout(PR_SecondsToInterval(180))
     181                 :     , mMaxRequestAttempts(10)
     182                 :     , mMaxRequestDelay(10)
     183                 :     , mIdleSynTimeout(250)
     184                 :     , mMaxConnections(24)
     185                 :     , mMaxConnectionsPerServer(8)
     186                 :     , mMaxPersistentConnectionsPerServer(2)
     187                 :     , mMaxPersistentConnectionsPerProxy(4)
     188                 :     , mMaxPipelinedRequests(2)
     189                 :     , mRedirectionLimit(10)
     190                 :     , mPhishyUserPassLength(1)
     191                 :     , mQoSBits(0x00)
     192                 :     , mPipeliningOverSSL(false)
     193                 :     , mInPrivateBrowsingMode(PRIVATE_BROWSING_UNKNOWN)
     194             679 :     , mLastUniqueID(NowInSeconds())
     195                 :     , mSessionStartTime(0)
     196                 :     , mLegacyAppName("Mozilla")
     197                 :     , mLegacyAppVersion("5.0")
     198                 :     , mProduct("Gecko")
     199                 :     , mUserAgentIsDirty(true)
     200                 :     , mUseCache(true)
     201                 :     , mPromptTempRedirect(true)
     202                 :     , mSendSecureXSiteReferrer(true)
     203                 :     , mEnablePersistentHttpsCaching(false)
     204                 :     , mDoNotTrackEnabled(false)
     205                 :     , mTelemetryEnabled(false)
     206                 :     , mAllowExperiments(true)
     207                 :     , mEnableSpdy(false)
     208                 :     , mCoalesceSpdy(true)
     209                 :     , mUseAlternateProtocol(false)
     210                 :     , mSpdySendingChunkSize(SpdySession::kSendingChunkSize)
     211             679 :     , mSpdyPingThreshold(PR_SecondsToInterval(44))
     212            3395 :     , mSpdyPingTimeout(PR_SecondsToInterval(8))
     213                 : {
     214                 : #if defined(PR_LOGGING)
     215             679 :     gHttpLog = PR_NewLogModule("nsHttp");
     216                 : #endif
     217                 : 
     218             679 :     LOG(("Creating nsHttpHandler [this=%x].\n", this));
     219                 : 
     220             679 :     NS_ASSERTION(!gHttpHandler, "HTTP handler already created!");
     221             679 :     gHttpHandler = this;
     222             679 : }
     223                 : 
     224            2031 : nsHttpHandler::~nsHttpHandler()
     225                 : {
     226             677 :     LOG(("Deleting nsHttpHandler [this=%x]\n", this));
     227                 : 
     228                 :     // make sure the connection manager is shutdown
     229             677 :     if (mConnMgr) {
     230             677 :         mConnMgr->Shutdown();
     231             677 :         NS_RELEASE(mConnMgr);
     232                 :     }
     233                 : 
     234                 :     // Note: don't call NeckoChild::DestroyNeckoChild() here, as it's too late
     235                 :     // and it'll segfault.  NeckoChild will get cleaned up by process exit.
     236                 : 
     237             677 :     nsHttp::DestroyAtomTable();
     238                 : 
     239             677 :     gHttpHandler = nsnull;
     240            2708 : }
     241                 : 
     242                 : nsresult
     243             679 : nsHttpHandler::Init()
     244                 : {
     245                 :     NS_TIME_FUNCTION;
     246                 : 
     247                 :     nsresult rv;
     248                 : 
     249             679 :     LOG(("nsHttpHandler::Init\n"));
     250                 : 
     251             679 :     rv = nsHttp::CreateAtomTable();
     252             679 :     if (NS_FAILED(rv))
     253               0 :         return rv;
     254                 : 
     255             679 :     mIOService = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
     256             679 :     if (NS_FAILED(rv)) {
     257               0 :         NS_WARNING("unable to continue without io service");
     258               0 :         return rv;
     259                 :     }
     260                 : 
     261             679 :     if (IsNeckoChild())
     262               0 :         NeckoChild::InitNeckoChild();
     263                 : 
     264             679 :     InitUserAgentComponents();
     265                 : 
     266                 :     // monitor some preference changes
     267            1358 :     nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID);
     268             679 :     if (prefBranch) {
     269             679 :         prefBranch->AddObserver(HTTP_PREF_PREFIX, this, true);
     270             679 :         prefBranch->AddObserver(UA_PREF_PREFIX, this, true);
     271             679 :         prefBranch->AddObserver(INTL_ACCEPT_LANGUAGES, this, true); 
     272             679 :         prefBranch->AddObserver(NETWORK_ENABLEIDN, this, true);
     273             679 :         prefBranch->AddObserver(BROWSER_PREF("disk_cache_ssl"), this, true);
     274             679 :         prefBranch->AddObserver(DONOTTRACK_HEADER_ENABLED, this, true);
     275             679 :         prefBranch->AddObserver(TELEMETRY_ENABLED, this, true);
     276                 : 
     277             679 :         PrefsChanged(prefBranch, nsnull);
     278                 :     }
     279                 : 
     280             679 :     mMisc.AssignLiteral("rv:" MOZILLA_UAVERSION);
     281                 : 
     282                 :     nsCOMPtr<nsIXULAppInfo> appInfo =
     283            1358 :         do_GetService("@mozilla.org/xre/app-info;1");
     284                 : 
     285             679 :     mAppName.AssignLiteral(MOZ_APP_UA_NAME);
     286             679 :     if (mAppName.Length() == 0 && appInfo) {
     287             299 :         appInfo->GetName(mAppName);
     288             299 :         appInfo->GetVersion(mAppVersion);
     289             299 :         mAppName.StripChars(" ()<>@,;:\\\"/[]?={}");
     290                 :     } else {
     291             380 :         mAppVersion.AssignLiteral(MOZ_APP_UA_VERSION);
     292                 :     }
     293                 : 
     294                 : #if DEBUG
     295                 :     // dump user agent prefs
     296             679 :     LOG(("> legacy-app-name = %s\n", mLegacyAppName.get()));
     297             679 :     LOG(("> legacy-app-version = %s\n", mLegacyAppVersion.get()));
     298             679 :     LOG(("> platform = %s\n", mPlatform.get()));
     299             679 :     LOG(("> oscpu = %s\n", mOscpu.get()));
     300             679 :     LOG(("> misc = %s\n", mMisc.get()));
     301             679 :     LOG(("> product = %s\n", mProduct.get()));
     302             679 :     LOG(("> product-sub = %s\n", mProductSub.get()));
     303             679 :     LOG(("> app-name = %s\n", mAppName.get()));
     304             679 :     LOG(("> app-version = %s\n", mAppVersion.get()));
     305             679 :     LOG(("> compat-firefox = %s\n", mCompatFirefox.get()));
     306             679 :     LOG(("> user-agent = %s\n", UserAgent().get()));
     307                 : #endif
     308                 : 
     309             679 :     mSessionStartTime = NowInSeconds();
     310                 : 
     311             679 :     rv = mAuthCache.Init();
     312             679 :     if (NS_FAILED(rv)) return rv;
     313                 : 
     314             679 :     rv = InitConnectionMgr();
     315             679 :     if (NS_FAILED(rv)) return rv;
     316                 : 
     317                 : #ifdef ANDROID
     318                 :     mProductSub.AssignLiteral(MOZILLA_UAVERSION);
     319                 : #else
     320             679 :     mProductSub.AssignLiteral(MOZ_UA_BUILDID);
     321                 : #endif
     322             679 :     if (mProductSub.IsEmpty() && appInfo)
     323             299 :         appInfo->GetPlatformBuildID(mProductSub);
     324             679 :     if (mProductSub.Length() > 8)
     325             233 :         mProductSub.SetLength(8);
     326                 : 
     327                 :     // Startup the http category
     328                 :     // Bring alive the objects in the http-protocol-startup category
     329                 :     NS_CreateServicesFromCategory(NS_HTTP_STARTUP_CATEGORY,
     330                 :                                   static_cast<nsISupports*>(static_cast<void*>(this)),
     331             679 :                                   NS_HTTP_STARTUP_TOPIC);    
     332                 :     
     333             679 :     mObserverService = mozilla::services::GetObserverService();
     334             679 :     if (mObserverService) {
     335             679 :         mObserverService->AddObserver(this, "profile-change-net-teardown", true);
     336             679 :         mObserverService->AddObserver(this, "profile-change-net-restore", true);
     337             679 :         mObserverService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, true);
     338             679 :         mObserverService->AddObserver(this, "net:clear-active-logins", true);
     339             679 :         mObserverService->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, true);
     340             679 :         mObserverService->AddObserver(this, "net:prune-dead-connections", true);
     341                 :     }
     342                 :  
     343             679 :     return NS_OK;
     344                 : }
     345                 : 
     346                 : nsresult
     347             679 : nsHttpHandler::InitConnectionMgr()
     348                 : {
     349                 :     NS_TIME_FUNCTION;
     350                 : 
     351                 :     nsresult rv;
     352                 : 
     353             679 :     if (!mConnMgr) {
     354             679 :         mConnMgr = new nsHttpConnectionMgr();
     355             679 :         if (!mConnMgr)
     356               0 :             return NS_ERROR_OUT_OF_MEMORY;
     357             679 :         NS_ADDREF(mConnMgr);
     358                 :     }
     359                 : 
     360                 :     rv = mConnMgr->Init(mMaxConnections,
     361                 :                         mMaxConnectionsPerServer,
     362                 :                         mMaxConnectionsPerServer,
     363                 :                         mMaxPersistentConnectionsPerServer,
     364                 :                         mMaxPersistentConnectionsPerProxy,
     365                 :                         mMaxRequestDelay,
     366             679 :                         mMaxPipelinedRequests);
     367             679 :     return rv;
     368                 : }
     369                 : 
     370                 : nsresult
     371            3514 : nsHttpHandler::AddStandardRequestHeaders(nsHttpHeaderArray *request,
     372                 :                                          PRUint8 caps,
     373                 :                                          bool useProxy)
     374                 : {
     375                 :     nsresult rv;
     376                 : 
     377                 :     // Add the "User-Agent" header
     378            3514 :     rv = request->SetHeader(nsHttp::User_Agent, UserAgent());
     379            3514 :     if (NS_FAILED(rv)) return rv;
     380                 : 
     381                 :     // MIME based content negotiation lives!
     382                 :     // Add the "Accept" header
     383            3514 :     rv = request->SetHeader(nsHttp::Accept, mAccept);
     384            3514 :     if (NS_FAILED(rv)) return rv;
     385                 : 
     386                 :     // Add the "Accept-Language" header
     387            3514 :     if (!mAcceptLanguages.IsEmpty()) {
     388                 :         // Add the "Accept-Language" header
     389            3514 :         rv = request->SetHeader(nsHttp::Accept_Language, mAcceptLanguages);
     390            3514 :         if (NS_FAILED(rv)) return rv;
     391                 :     }
     392                 : 
     393                 :     // Add the "Accept-Encoding" header
     394            3514 :     rv = request->SetHeader(nsHttp::Accept_Encoding, mAcceptEncodings);
     395            3514 :     if (NS_FAILED(rv)) return rv;
     396                 : 
     397                 :     // RFC2616 section 19.6.2 states that the "Connection: keep-alive"
     398                 :     // and "Keep-alive" request headers should not be sent by HTTP/1.1
     399                 :     // user-agents.  Otherwise, problems with proxy servers (especially
     400                 :     // transparent proxies) can result.
     401                 :     //
     402                 :     // However, we need to send something so that we can use keepalive
     403                 :     // with HTTP/1.0 servers/proxies. We use "Proxy-Connection:" when 
     404                 :     // we're talking to an http proxy, and "Connection:" otherwise.
     405                 :     // We no longer send the Keep-Alive request header.
     406                 :     
     407            7028 :     NS_NAMED_LITERAL_CSTRING(close, "close");
     408            7028 :     NS_NAMED_LITERAL_CSTRING(keepAlive, "keep-alive");
     409                 : 
     410            3514 :     const nsACString *connectionType = &close;
     411            3514 :     if (caps & NS_HTTP_ALLOW_KEEPALIVE) {
     412            3514 :         connectionType = &keepAlive;
     413               0 :     } else if (useProxy) {
     414                 :         // Bug 92006
     415               0 :         request->SetHeader(nsHttp::Connection, close);
     416                 :     }
     417                 : 
     418                 :     // Add the "Do-Not-Track" header
     419            3514 :     if (mDoNotTrackEnabled) {
     420                 :       rv = request->SetHeader(nsHttp::DoNotTrack,
     421               0 :                               NS_LITERAL_CSTRING("1"));
     422               0 :       if (NS_FAILED(rv)) return rv;
     423                 :     }
     424                 : 
     425                 :     const nsHttpAtom &header = useProxy ? nsHttp::Proxy_Connection
     426            3514 :                                         : nsHttp::Connection;
     427            3514 :     return request->SetHeader(header, *connectionType);
     428                 : }
     429                 : 
     430                 : bool
     431               4 : nsHttpHandler::IsAcceptableEncoding(const char *enc)
     432                 : {
     433               4 :     if (!enc)
     434               0 :         return false;
     435                 : 
     436                 :     // HTTP 1.1 allows servers to send x-gzip and x-compress instead
     437                 :     // of gzip and compress, for example.  So, we'll always strip off
     438                 :     // an "x-" prefix before matching the encoding to one we claim
     439                 :     // to accept.
     440               4 :     if (!PL_strncasecmp(enc, "x-", 2))
     441               0 :         enc += 2;
     442                 :     
     443               4 :     return nsHttp::FindToken(mAcceptEncodings.get(), enc, HTTP_LWS ",") != nsnull;
     444                 : }
     445                 : 
     446                 : nsresult
     447            2614 : nsHttpHandler::GetCacheSession(nsCacheStoragePolicy storagePolicy,
     448                 :                                nsICacheSession **result)
     449                 : {
     450                 :     nsresult rv;
     451                 : 
     452                 :     // Skip cache if disabled in preferences
     453            2614 :     if (!mUseCache)
     454               0 :         return NS_ERROR_NOT_AVAILABLE;
     455                 : 
     456                 :     // We want to get the pointer to the cache service each time we're called,
     457                 :     // because it's possible for some add-ons (such as Google Gears) to swap
     458                 :     // in new cache services on the fly, and we want to pick them up as
     459                 :     // appropriate.
     460                 :     nsCOMPtr<nsICacheService> serv = do_GetService(NS_CACHESERVICE_CONTRACTID,
     461            5228 :                                                    &rv);
     462            2614 :     if (NS_FAILED(rv)) return rv;
     463                 : 
     464            2614 :     const char *sessionName = "HTTP";
     465            2614 :     switch (storagePolicy) {
     466                 :     case nsICache::STORE_IN_MEMORY:
     467               0 :         sessionName = "HTTP-memory-only";
     468               0 :         break;
     469                 :     case nsICache::STORE_OFFLINE:
     470               0 :         sessionName = "HTTP-offline";
     471               0 :         break;
     472                 :     default:
     473            2614 :         break;
     474                 :     }
     475                 : 
     476            5228 :     nsCOMPtr<nsICacheSession> cacheSession;
     477            2614 :     rv = serv->CreateSession(sessionName,
     478                 :                              storagePolicy,
     479                 :                              nsICache::STREAM_BASED,
     480            2614 :                              getter_AddRefs(cacheSession));
     481            2614 :     if (NS_FAILED(rv)) return rv;
     482                 : 
     483            2614 :     rv = cacheSession->SetDoomEntriesIfExpired(false);
     484            2614 :     if (NS_FAILED(rv)) return rv;
     485                 : 
     486            2614 :     NS_ADDREF(*result = cacheSession);
     487                 : 
     488            2614 :     return NS_OK;
     489                 : }
     490                 : 
     491                 : bool
     492               0 : nsHttpHandler::InPrivateBrowsingMode()
     493                 : {
     494               0 :     if (PRIVATE_BROWSING_UNKNOWN == mInPrivateBrowsingMode) {
     495                 :         // figure out if we're starting in private browsing mode
     496                 :         nsCOMPtr<nsIPrivateBrowsingService> pbs =
     497               0 :             do_GetService(NS_PRIVATE_BROWSING_SERVICE_CONTRACTID);
     498               0 :         if (!pbs)
     499               0 :             return PRIVATE_BROWSING_OFF;
     500                 : 
     501               0 :         bool p = false;
     502               0 :         pbs->GetPrivateBrowsingEnabled(&p);
     503               0 :         mInPrivateBrowsingMode = p ? PRIVATE_BROWSING_ON : PRIVATE_BROWSING_OFF;
     504                 :     }
     505               0 :     return PRIVATE_BROWSING_ON == mInPrivateBrowsingMode;
     506                 : }
     507                 : 
     508                 : nsresult
     509             894 : nsHttpHandler::GetStreamConverterService(nsIStreamConverterService **result)
     510                 : {
     511             894 :     if (!mStreamConvSvc) {
     512                 :         nsresult rv;
     513              71 :         mStreamConvSvc = do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID, &rv);
     514              71 :         if (NS_FAILED(rv)) return rv;
     515                 :     }
     516             894 :     *result = mStreamConvSvc;
     517             894 :     NS_ADDREF(*result);
     518             894 :     return NS_OK;
     519                 : }
     520                 : 
     521                 : nsIStrictTransportSecurityService*
     522            5051 : nsHttpHandler::GetSTSService()
     523                 : {
     524            5051 :     if (!mSTSService)
     525             265 :       mSTSService = do_GetService(NS_STSSERVICE_CONTRACTID);
     526            5051 :     return mSTSService;
     527                 : }
     528                 : 
     529                 : nsICookieService *
     530            3507 : nsHttpHandler::GetCookieService()
     531                 : {
     532            3507 :     if (!mCookieService)
     533             265 :         mCookieService = do_GetService(NS_COOKIESERVICE_CONTRACTID);
     534            3507 :     return mCookieService;
     535                 : }
     536                 : 
     537                 : nsresult 
     538             327 : nsHttpHandler::GetIOService(nsIIOService** result)
     539                 : {
     540             327 :     NS_ADDREF(*result = mIOService);
     541             327 :     return NS_OK;
     542                 : }
     543                 : 
     544                 : PRUint32
     545               0 : nsHttpHandler::Get32BitsOfPseudoRandom()
     546                 : {
     547                 :     // only confirm rand seeding on socket thread
     548               0 :     NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
     549                 : 
     550                 :     // rand() provides different amounts of PRNG on different platforms.
     551                 :     // 15 or 31 bits are common amounts.
     552                 : 
     553                 :     PR_STATIC_ASSERT(RAND_MAX >= 0xfff);
     554                 :     
     555                 : #if RAND_MAX < 0xffffU
     556                 :     return ((PRUint16) rand() << 20) |
     557                 :             (((PRUint16) rand() & 0xfff) << 8) |
     558                 :             ((PRUint16) rand() & 0xff);
     559                 : #elif RAND_MAX < 0xffffffffU
     560               0 :     return ((PRUint16) rand() << 16) | ((PRUint16) rand() & 0xffff);
     561                 : #else
     562                 :     return (PRUint32) rand();
     563                 : #endif
     564                 : }
     565                 : 
     566                 : void
     567            6553 : nsHttpHandler::NotifyObservers(nsIHttpChannel *chan, const char *event)
     568                 : {
     569            6553 :     LOG(("nsHttpHandler::NotifyObservers [chan=%x event=\"%s\"]\n", chan, event));
     570            6553 :     if (mObserverService)
     571            6553 :         mObserverService->NotifyObservers(chan, event, nsnull);
     572            6553 : }
     573                 : 
     574                 : nsresult
     575             155 : nsHttpHandler::AsyncOnChannelRedirect(nsIChannel* oldChan, nsIChannel* newChan,
     576                 :                                  PRUint32 flags)
     577                 : {
     578                 :     // TODO E10S This helper has to be initialized on the other process
     579                 :     nsRefPtr<nsAsyncRedirectVerifyHelper> redirectCallbackHelper =
     580             310 :         new nsAsyncRedirectVerifyHelper();
     581                 : 
     582             155 :     return redirectCallbackHelper->Init(oldChan, newChan, flags);
     583                 : }
     584                 : 
     585                 : /* static */ nsresult
     586            3514 : nsHttpHandler::GenerateHostPort(const nsCString& host, PRInt32 port,
     587                 :                                 nsCString& hostLine)
     588                 : {
     589            3514 :     return NS_GenerateHostPort(host, port, hostLine);
     590                 : }
     591                 : 
     592                 : //-----------------------------------------------------------------------------
     593                 : // nsHttpHandler <private>
     594                 : //-----------------------------------------------------------------------------
     595                 : 
     596                 : const nsAFlatCString &
     597            3561 : nsHttpHandler::UserAgent()
     598                 : {
     599            3561 :     if (mUserAgentOverride) {
     600               8 :         LOG(("using general.useragent.override : %s\n", mUserAgentOverride.get()));
     601               8 :         return mUserAgentOverride;
     602                 :     }
     603                 : 
     604            3553 :     if (mUserAgentIsDirty) {
     605             285 :         BuildUserAgent();
     606             285 :         mUserAgentIsDirty = false;
     607                 :     }
     608                 : 
     609            3553 :     return mUserAgent;
     610                 : }
     611                 : 
     612                 : void
     613             285 : nsHttpHandler::BuildUserAgent()
     614                 : {
     615             285 :     LOG(("nsHttpHandler::BuildUserAgent\n"));
     616                 : 
     617             285 :     NS_ASSERTION(!mLegacyAppName.IsEmpty() &&
     618                 :                  !mLegacyAppVersion.IsEmpty() &&
     619                 :                  !mPlatform.IsEmpty() &&
     620                 :                  !mOscpu.IsEmpty(),
     621                 :                  "HTTP cannot send practical requests without this much");
     622                 : 
     623                 :     // preallocate to worst-case size, which should always be better
     624                 :     // than if we didn't preallocate at all.
     625             285 :     mUserAgent.SetCapacity(mLegacyAppName.Length() + 
     626             285 :                            mLegacyAppVersion.Length() + 
     627                 : #ifndef UA_SPARE_PLATFORM
     628             285 :                            mPlatform.Length() + 
     629                 : #endif
     630             285 :                            mOscpu.Length() +
     631             285 :                            mMisc.Length() +
     632             285 :                            mProduct.Length() +
     633             285 :                            mProductSub.Length() +
     634             285 :                            mAppName.Length() +
     635             285 :                            mAppVersion.Length() +
     636             285 :                            mCompatFirefox.Length() +
     637             285 :                            mCompatDevice.Length() +
     638            2850 :                            13);
     639                 : 
     640                 :     // Application portion
     641             285 :     mUserAgent.Assign(mLegacyAppName);
     642             285 :     mUserAgent += '/';
     643             285 :     mUserAgent += mLegacyAppVersion;
     644             285 :     mUserAgent += ' ';
     645                 : 
     646                 :     // Application comment
     647             285 :     mUserAgent += '(';
     648                 : #ifndef UA_SPARE_PLATFORM
     649             285 :     mUserAgent += mPlatform;
     650             285 :     mUserAgent.AppendLiteral("; ");
     651                 : #endif
     652                 : #ifdef ANDROID
     653                 :     if (!mCompatDevice.IsEmpty()) {
     654                 :         mUserAgent += mCompatDevice;
     655                 :         mUserAgent.AppendLiteral("; ");
     656                 :     }
     657                 : #else
     658             285 :     mUserAgent += mOscpu;
     659             285 :     mUserAgent.AppendLiteral("; ");
     660                 : #endif
     661             285 :     mUserAgent += mMisc;
     662             285 :     mUserAgent += ')';
     663                 : 
     664                 :     // Product portion
     665             285 :     mUserAgent += ' ';
     666             285 :     mUserAgent += mProduct;
     667             285 :     mUserAgent += '/';
     668             285 :     mUserAgent += mProductSub;
     669                 : 
     670                 :     // "Firefox/x.y.z" compatibility token
     671             285 :     if (!mCompatFirefox.IsEmpty()) {
     672               0 :         mUserAgent += ' ';
     673               0 :         mUserAgent += mCompatFirefox;
     674                 :     }
     675                 : 
     676                 :     // App portion
     677             285 :     mUserAgent += ' ';
     678             285 :     mUserAgent += mAppName;
     679             285 :     mUserAgent += '/';
     680             285 :     mUserAgent += mAppVersion;
     681             285 : }
     682                 : 
     683                 : #ifdef XP_WIN
     684                 : #define WNT_BASE "Windows NT %ld.%ld"
     685                 : #define W64_PREFIX "; Win64"
     686                 : #endif
     687                 : 
     688                 : void
     689             679 : nsHttpHandler::InitUserAgentComponents()
     690                 : {
     691                 :     // Gather platform.
     692                 :     mPlatform.AssignLiteral(
     693                 : #if defined(ANDROID)
     694                 :     "Android"
     695                 : #elif defined(XP_OS2)
     696                 :     "OS/2"
     697                 : #elif defined(XP_WIN)
     698                 :     "Windows"
     699                 : #elif defined(XP_MACOSX)
     700                 :     "Macintosh"
     701                 : #elif defined(MOZ_PLATFORM_MAEMO)
     702                 :     "Maemo"
     703                 : #elif defined(MOZ_X11)
     704                 :     "X11"
     705                 : #else
     706                 :     "?"
     707                 : #endif
     708             679 :     );
     709                 : 
     710                 : #if defined(ANDROID)
     711                 :     nsCOMPtr<nsIPropertyBag2> infoService = do_GetService("@mozilla.org/system-info;1");
     712                 :     NS_ASSERTION(infoService, "Could not find a system info service");
     713                 : 
     714                 :     bool isTablet = false;
     715                 :     infoService->GetPropertyAsBool(NS_LITERAL_STRING("tablet"), &isTablet);
     716                 :     if (isTablet)
     717                 :         mCompatDevice.AssignLiteral("Tablet");
     718                 :     else
     719                 :         mCompatDevice.AssignLiteral("Mobile");
     720                 : #endif
     721                 : 
     722                 :     // Gather OS/CPU.
     723                 : #if defined(XP_OS2)
     724                 :     ULONG os2ver = 0;
     725                 :     DosQuerySysInfo(QSV_VERSION_MINOR, QSV_VERSION_MINOR,
     726                 :                     &os2ver, sizeof(os2ver));
     727                 :     if (os2ver == 11)
     728                 :         mOscpu.AssignLiteral("2.11");
     729                 :     else if (os2ver == 30)
     730                 :         mOscpu.AssignLiteral("Warp 3");
     731                 :     else if (os2ver == 40)
     732                 :         mOscpu.AssignLiteral("Warp 4");
     733                 :     else if (os2ver == 45)
     734                 :         mOscpu.AssignLiteral("Warp 4.5");
     735                 : 
     736                 : #elif defined(XP_WIN)
     737                 :     OSVERSIONINFO info = { sizeof(OSVERSIONINFO) };
     738                 :     if (GetVersionEx(&info)) {
     739                 :         const char *format;
     740                 : #if defined _M_IA64
     741                 :         format = WNT_BASE W64_PREFIX "; IA64";
     742                 : #elif defined _M_X64 || defined _M_AMD64
     743                 :         format = WNT_BASE W64_PREFIX "; x64";
     744                 : #else
     745                 :         BOOL isWow64 = FALSE;
     746                 :         if (!IsWow64Process(GetCurrentProcess(), &isWow64)) {
     747                 :             isWow64 = FALSE;
     748                 :         }
     749                 :         format = isWow64
     750                 :           ? WNT_BASE "; WOW64"
     751                 :           : WNT_BASE;
     752                 : #endif
     753                 :         char *buf = PR_smprintf(format,
     754                 :                                 info.dwMajorVersion,
     755                 :                                 info.dwMinorVersion);
     756                 :         if (buf) {
     757                 :             mOscpu = buf;
     758                 :             PR_smprintf_free(buf);
     759                 :         }
     760                 :     }
     761                 : #elif defined (XP_MACOSX)
     762                 : #if defined(__ppc__)
     763                 :     mOscpu.AssignLiteral("PPC Mac OS X");
     764                 : #elif defined(__i386__) || defined(__x86_64__)
     765                 :     mOscpu.AssignLiteral("Intel Mac OS X");
     766                 : #endif
     767                 :     SInt32 majorVersion, minorVersion;
     768                 :     if ((::Gestalt(gestaltSystemVersionMajor, &majorVersion) == noErr) &&
     769                 :         (::Gestalt(gestaltSystemVersionMinor, &minorVersion) == noErr)) {
     770                 :         mOscpu += nsPrintfCString(" %d.%d", majorVersion, minorVersion);
     771                 :     }
     772                 : #elif defined (XP_UNIX)
     773                 :     struct utsname name;
     774                 :     
     775             679 :     int ret = uname(&name);
     776             679 :     if (ret >= 0) {
     777            1358 :         nsCAutoString buf;
     778             679 :         buf =  (char*)name.sysname;
     779                 : 
     780             679 :         if (strcmp(name.machine, "x86_64") == 0 &&
     781                 :             sizeof(void *) == sizeof(PRInt32)) {
     782                 :             // We're running 32-bit code on x86_64. Make this browser
     783                 :             // look like it's running on i686 hardware, but append "
     784                 :             // (x86_64)" to the end of the oscpu identifier to be able
     785                 :             // to differentiate this from someone running 64-bit code
     786                 :             // on x86_64..
     787                 : 
     788               0 :             buf += " i686 on x86_64";
     789                 :         } else {
     790             679 :             buf += ' ';
     791                 : 
     792                 : #ifdef AIX
     793                 :             // AIX uname returns machine specific info in the uname.machine
     794                 :             // field and does not return the cpu type like other platforms.
     795                 :             // We use the AIX version and release numbers instead.
     796                 :             buf += (char*)name.version;
     797                 :             buf += '.';
     798                 :             buf += (char*)name.release;
     799                 : #else
     800             679 :             buf += (char*)name.machine;
     801                 : #endif
     802                 :         }
     803                 : 
     804             679 :         mOscpu.Assign(buf);
     805                 :     }
     806                 : #endif
     807                 : 
     808             679 :     mUserAgentIsDirty = true;
     809             679 : }
     810                 : 
     811                 : PRUint32
     812            3656 : nsHttpHandler::MaxSocketCount()
     813                 : {
     814                 :     PR_CallOnce(&nsSocketTransportService::gMaxCountInitOnce,
     815            3656 :                 nsSocketTransportService::DiscoverMaxCount);
     816                 :     // Don't use the full max count because sockets can be held in
     817                 :     // the persistent connection pool for a long time and that could
     818                 :     // starve other users.
     819                 : 
     820            3656 :     PRUint32 maxCount = nsSocketTransportService::gMaxCount;
     821            3656 :     if (maxCount <= 8)
     822               0 :         maxCount = 1;
     823                 :     else
     824            3656 :         maxCount -= 8;
     825                 : 
     826            3656 :     return maxCount;
     827                 : }
     828                 : 
     829                 : void
     830             698 : nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref)
     831                 : {
     832             698 :     nsresult rv = NS_OK;
     833                 :     PRInt32 val;
     834                 : 
     835             698 :     LOG(("nsHttpHandler::PrefsChanged [pref=%s]\n", pref));
     836                 : 
     837                 : #define PREF_CHANGED(p) ((pref == nsnull) || !PL_strcmp(pref, p))
     838                 : #define MULTI_PREF_CHANGED(p) \
     839                 :   ((pref == nsnull) || !PL_strncmp(pref, p, sizeof(p) - 1))
     840                 : 
     841                 :     //
     842                 :     // UA components
     843                 :     //
     844                 : 
     845             698 :     bool cVar = false;
     846                 : 
     847             698 :     if (PREF_CHANGED(UA_PREF("compatMode.firefox"))) {
     848             679 :         rv = prefs->GetBoolPref(UA_PREF("compatMode.firefox"), &cVar);
     849             679 :         if (NS_SUCCEEDED(rv) && cVar) {
     850               0 :             mCompatFirefox.AssignLiteral("Firefox/" MOZ_UA_FIREFOX_VERSION);
     851                 :         } else {
     852             679 :             mCompatFirefox.Truncate();
     853                 :         }
     854             679 :         mUserAgentIsDirty = true;
     855                 :     }
     856                 : 
     857                 :     // general.useragent.override
     858             698 :     if (PREF_CHANGED(UA_PREF("override"))) {
     859                 :         prefs->GetCharPref(UA_PREF("override"),
     860             682 :                             getter_Copies(mUserAgentOverride));
     861             682 :         mUserAgentIsDirty = true;
     862                 :     }
     863                 : 
     864                 :     //
     865                 :     // HTTP options
     866                 :     //
     867                 : 
     868             698 :     if (PREF_CHANGED(HTTP_PREF("keep-alive.timeout"))) {
     869             679 :         rv = prefs->GetIntPref(HTTP_PREF("keep-alive.timeout"), &val);
     870             679 :         if (NS_SUCCEEDED(rv))
     871             679 :             mIdleTimeout = PR_SecondsToInterval(clamped(val, 1, 0xffff));
     872                 :     }
     873                 : 
     874             698 :     if (PREF_CHANGED(HTTP_PREF("request.max-attempts"))) {
     875             679 :         rv = prefs->GetIntPref(HTTP_PREF("request.max-attempts"), &val);
     876             679 :         if (NS_SUCCEEDED(rv))
     877               0 :             mMaxRequestAttempts = (PRUint16) clamped(val, 1, 0xffff);
     878                 :     }
     879                 : 
     880             698 :     if (PREF_CHANGED(HTTP_PREF("request.max-start-delay"))) {
     881             679 :         rv = prefs->GetIntPref(HTTP_PREF("request.max-start-delay"), &val);
     882             679 :         if (NS_SUCCEEDED(rv)) {
     883             679 :             mMaxRequestDelay = (PRUint16) clamped(val, 0, 0xffff);
     884             679 :             if (mConnMgr)
     885                 :                 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_REQUEST_DELAY,
     886               0 :                                       mMaxRequestDelay);
     887                 :         }
     888                 :     }
     889                 : 
     890             698 :     if (PREF_CHANGED(HTTP_PREF("max-connections"))) {
     891             679 :         rv = prefs->GetIntPref(HTTP_PREF("max-connections"), &val);
     892             679 :         if (NS_SUCCEEDED(rv)) {
     893                 : 
     894                 :             mMaxConnections = (PRUint16) clamped((PRUint32)val,
     895             679 :                                                  (PRUint32)1, MaxSocketCount());
     896                 : 
     897             679 :             if (mConnMgr)
     898                 :                 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_CONNECTIONS,
     899               0 :                                       mMaxConnections);
     900                 :         }
     901                 :     }
     902                 : 
     903             698 :     if (PREF_CHANGED(HTTP_PREF("max-connections-per-server"))) {
     904             679 :         rv = prefs->GetIntPref(HTTP_PREF("max-connections-per-server"), &val);
     905             679 :         if (NS_SUCCEEDED(rv)) {
     906             679 :             mMaxConnectionsPerServer = (PRUint8) clamped(val, 1, 0xff);
     907             679 :             if (mConnMgr) {
     908                 :                 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_CONNECTIONS_PER_HOST,
     909               0 :                                       mMaxConnectionsPerServer);
     910                 :                 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_CONNECTIONS_PER_PROXY,
     911               0 :                                       mMaxConnectionsPerServer);
     912                 :             }
     913                 :         }
     914                 :     }
     915                 : 
     916             698 :     if (PREF_CHANGED(HTTP_PREF("max-persistent-connections-per-server"))) {
     917             679 :         rv = prefs->GetIntPref(HTTP_PREF("max-persistent-connections-per-server"), &val);
     918             679 :         if (NS_SUCCEEDED(rv)) {
     919             679 :             mMaxPersistentConnectionsPerServer = (PRUint8) clamped(val, 1, 0xff);
     920             679 :             if (mConnMgr)
     921                 :                 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_PERSISTENT_CONNECTIONS_PER_HOST,
     922               0 :                                       mMaxPersistentConnectionsPerServer);
     923                 :         }
     924                 :     }
     925                 : 
     926             698 :     if (PREF_CHANGED(HTTP_PREF("max-persistent-connections-per-proxy"))) {
     927             679 :         rv = prefs->GetIntPref(HTTP_PREF("max-persistent-connections-per-proxy"), &val);
     928             679 :         if (NS_SUCCEEDED(rv)) {
     929             679 :             mMaxPersistentConnectionsPerProxy = (PRUint8) clamped(val, 1, 0xff);
     930             679 :             if (mConnMgr)
     931                 :                 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_PERSISTENT_CONNECTIONS_PER_PROXY,
     932               0 :                                       mMaxPersistentConnectionsPerProxy);
     933                 :         }
     934                 :     }
     935                 : 
     936             698 :     if (PREF_CHANGED(HTTP_PREF("sendRefererHeader"))) {
     937             679 :         rv = prefs->GetIntPref(HTTP_PREF("sendRefererHeader"), &val);
     938             679 :         if (NS_SUCCEEDED(rv))
     939             679 :             mReferrerLevel = (PRUint8) clamped(val, 0, 0xff);
     940                 :     }
     941                 : 
     942             698 :     if (PREF_CHANGED(HTTP_PREF("redirection-limit"))) {
     943             679 :         rv = prefs->GetIntPref(HTTP_PREF("redirection-limit"), &val);
     944             679 :         if (NS_SUCCEEDED(rv))
     945             679 :             mRedirectionLimit = (PRUint8) clamped(val, 0, 0xff);
     946                 :     }
     947                 : 
     948             698 :     if (PREF_CHANGED(HTTP_PREF("connection-retry-timeout"))) {
     949             679 :         rv = prefs->GetIntPref(HTTP_PREF("connection-retry-timeout"), &val);
     950             679 :         if (NS_SUCCEEDED(rv))
     951             679 :             mIdleSynTimeout = (PRUint16) clamped(val, 0, 3000);
     952                 :     }
     953                 : 
     954             698 :     if (PREF_CHANGED(HTTP_PREF("fast-fallback-to-IPv4"))) {
     955             679 :         rv = prefs->GetBoolPref(HTTP_PREF("fast-fallback-to-IPv4"), &cVar);
     956             679 :         if (NS_SUCCEEDED(rv))
     957             679 :             mFastFallbackToIPv4 = cVar;
     958                 :     }
     959                 : 
     960             698 :     if (PREF_CHANGED(HTTP_PREF("version"))) {
     961            1358 :         nsXPIDLCString httpVersion;
     962             679 :         prefs->GetCharPref(HTTP_PREF("version"), getter_Copies(httpVersion));
     963             679 :         if (httpVersion) {
     964             679 :             if (!PL_strcmp(httpVersion, "1.1"))
     965             679 :                 mHttpVersion = NS_HTTP_VERSION_1_1;
     966               0 :             else if (!PL_strcmp(httpVersion, "0.9"))
     967               0 :                 mHttpVersion = NS_HTTP_VERSION_0_9;
     968                 :             else
     969               0 :                 mHttpVersion = NS_HTTP_VERSION_1_0;
     970                 :         }
     971                 :     }
     972                 : 
     973             698 :     if (PREF_CHANGED(HTTP_PREF("proxy.version"))) {
     974            1358 :         nsXPIDLCString httpVersion;
     975             679 :         prefs->GetCharPref(HTTP_PREF("proxy.version"), getter_Copies(httpVersion));
     976             679 :         if (httpVersion) {
     977             679 :             if (!PL_strcmp(httpVersion, "1.1"))
     978             679 :                 mProxyHttpVersion = NS_HTTP_VERSION_1_1;
     979                 :             else
     980               0 :                 mProxyHttpVersion = NS_HTTP_VERSION_1_0;
     981                 :             // it does not make sense to issue a HTTP/0.9 request to a proxy server
     982                 :         }
     983                 :     }
     984                 : 
     985             698 :     if (PREF_CHANGED(HTTP_PREF("keep-alive"))) {
     986             679 :         rv = prefs->GetBoolPref(HTTP_PREF("keep-alive"), &cVar);
     987             679 :         if (NS_SUCCEEDED(rv)) {
     988             679 :             if (cVar)
     989             679 :                 mCapabilities |= NS_HTTP_ALLOW_KEEPALIVE;
     990                 :             else
     991               0 :                 mCapabilities &= ~NS_HTTP_ALLOW_KEEPALIVE;
     992                 :         }
     993                 :     }
     994                 : 
     995             698 :     if (PREF_CHANGED(HTTP_PREF("proxy.keep-alive"))) {
     996             679 :         rv = prefs->GetBoolPref(HTTP_PREF("proxy.keep-alive"), &cVar);
     997             679 :         if (NS_SUCCEEDED(rv)) {
     998             679 :             if (cVar)
     999             679 :                 mProxyCapabilities |= NS_HTTP_ALLOW_KEEPALIVE;
    1000                 :             else
    1001               0 :                 mProxyCapabilities &= ~NS_HTTP_ALLOW_KEEPALIVE;
    1002                 :         }
    1003                 :     }
    1004                 : 
    1005             698 :     if (PREF_CHANGED(HTTP_PREF("pipelining"))) {
    1006             679 :         rv = prefs->GetBoolPref(HTTP_PREF("pipelining"), &cVar);
    1007             679 :         if (NS_SUCCEEDED(rv)) {
    1008             679 :             if (cVar)
    1009               0 :                 mCapabilities |=  NS_HTTP_ALLOW_PIPELINING;
    1010                 :             else
    1011             679 :                 mCapabilities &= ~NS_HTTP_ALLOW_PIPELINING;
    1012                 :         }
    1013                 :     }
    1014                 : 
    1015             698 :     if (PREF_CHANGED(HTTP_PREF("pipelining.maxrequests"))) {
    1016             679 :         rv = prefs->GetIntPref(HTTP_PREF("pipelining.maxrequests"), &val);
    1017             679 :         if (NS_SUCCEEDED(rv)) {
    1018             679 :             mMaxPipelinedRequests = clamped(val, 1, NS_HTTP_MAX_PIPELINED_REQUESTS);
    1019             679 :             if (mConnMgr)
    1020                 :                 mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_PIPELINED_REQUESTS,
    1021               0 :                                       mMaxPipelinedRequests);
    1022                 :         }
    1023                 :     }
    1024                 : 
    1025             698 :     if (PREF_CHANGED(HTTP_PREF("pipelining.ssl"))) {
    1026             679 :         rv = prefs->GetBoolPref(HTTP_PREF("pipelining.ssl"), &cVar);
    1027             679 :         if (NS_SUCCEEDED(rv))
    1028             679 :             mPipeliningOverSSL = cVar;
    1029                 :     }
    1030                 : 
    1031             698 :     if (PREF_CHANGED(HTTP_PREF("proxy.pipelining"))) {
    1032             679 :         rv = prefs->GetBoolPref(HTTP_PREF("proxy.pipelining"), &cVar);
    1033             679 :         if (NS_SUCCEEDED(rv)) {
    1034             679 :             if (cVar)
    1035               0 :                 mProxyCapabilities |=  NS_HTTP_ALLOW_PIPELINING;
    1036                 :             else
    1037             679 :                 mProxyCapabilities &= ~NS_HTTP_ALLOW_PIPELINING;
    1038                 :         }
    1039                 :     }
    1040                 : 
    1041             698 :     if (PREF_CHANGED(HTTP_PREF("qos"))) {
    1042             679 :         rv = prefs->GetIntPref(HTTP_PREF("qos"), &val);
    1043             679 :         if (NS_SUCCEEDED(rv))
    1044             679 :             mQoSBits = (PRUint8) clamped(val, 0, 0xff);
    1045                 :     }
    1046                 : 
    1047             698 :     if (PREF_CHANGED(HTTP_PREF("sendSecureXSiteReferrer"))) {
    1048             679 :         rv = prefs->GetBoolPref(HTTP_PREF("sendSecureXSiteReferrer"), &cVar);
    1049             679 :         if (NS_SUCCEEDED(rv))
    1050             679 :             mSendSecureXSiteReferrer = cVar;
    1051                 :     }
    1052                 : 
    1053             698 :     if (PREF_CHANGED(HTTP_PREF("accept.default"))) {
    1054            1358 :         nsXPIDLCString accept;
    1055                 :         rv = prefs->GetCharPref(HTTP_PREF("accept.default"),
    1056             679 :                                   getter_Copies(accept));
    1057             679 :         if (NS_SUCCEEDED(rv))
    1058             679 :             SetAccept(accept);
    1059                 :     }
    1060                 :     
    1061             698 :     if (PREF_CHANGED(HTTP_PREF("accept-encoding"))) {
    1062            1358 :         nsXPIDLCString acceptEncodings;
    1063                 :         rv = prefs->GetCharPref(HTTP_PREF("accept-encoding"),
    1064             679 :                                   getter_Copies(acceptEncodings));
    1065             679 :         if (NS_SUCCEEDED(rv))
    1066             679 :             SetAcceptEncodings(acceptEncodings);
    1067                 :     }
    1068                 : 
    1069             698 :     if (PREF_CHANGED(HTTP_PREF("use-cache"))) {
    1070             679 :         rv = prefs->GetBoolPref(HTTP_PREF("use-cache"), &cVar);
    1071             679 :         if (NS_SUCCEEDED(rv)) {
    1072             679 :             mUseCache = cVar;
    1073                 :         }
    1074                 :     }
    1075                 : 
    1076             698 :     if (PREF_CHANGED(HTTP_PREF("default-socket-type"))) {
    1077            1358 :         nsXPIDLCString sval;
    1078                 :         rv = prefs->GetCharPref(HTTP_PREF("default-socket-type"),
    1079             679 :                                 getter_Copies(sval));
    1080             679 :         if (NS_SUCCEEDED(rv)) {
    1081             679 :             if (sval.IsEmpty())
    1082             679 :                 mDefaultSocketType.Adopt(0);
    1083                 :             else {
    1084                 :                 // verify that this socket type is actually valid
    1085                 :                 nsCOMPtr<nsISocketProviderService> sps(
    1086               0 :                         do_GetService(NS_SOCKETPROVIDERSERVICE_CONTRACTID));
    1087               0 :                 if (sps) {
    1088               0 :                     nsCOMPtr<nsISocketProvider> sp;
    1089               0 :                     rv = sps->GetSocketProvider(sval, getter_AddRefs(sp));
    1090               0 :                     if (NS_SUCCEEDED(rv)) {
    1091                 :                         // OK, this looks like a valid socket provider.
    1092               0 :                         mDefaultSocketType.Assign(sval);
    1093                 :                     }
    1094                 :                 }
    1095                 :             }
    1096                 :         }
    1097                 :     }
    1098                 : 
    1099             698 :     if (PREF_CHANGED(HTTP_PREF("prompt-temp-redirect"))) {
    1100             679 :         rv = prefs->GetBoolPref(HTTP_PREF("prompt-temp-redirect"), &cVar);
    1101             679 :         if (NS_SUCCEEDED(rv)) {
    1102             679 :             mPromptTempRedirect = cVar;
    1103                 :         }
    1104                 :     }
    1105                 : 
    1106                 :     // enable Persistent caching for HTTPS - bug#205921    
    1107             698 :     if (PREF_CHANGED(BROWSER_PREF("disk_cache_ssl"))) {
    1108             679 :         cVar = false;
    1109             679 :         rv = prefs->GetBoolPref(BROWSER_PREF("disk_cache_ssl"), &cVar);
    1110             679 :         if (NS_SUCCEEDED(rv))
    1111             679 :             mEnablePersistentHttpsCaching = cVar;
    1112                 :     }
    1113                 : 
    1114             698 :     if (PREF_CHANGED(HTTP_PREF("phishy-userpass-length"))) {
    1115             679 :         rv = prefs->GetIntPref(HTTP_PREF("phishy-userpass-length"), &val);
    1116             679 :         if (NS_SUCCEEDED(rv))
    1117               0 :             mPhishyUserPassLength = (PRUint8) clamped(val, 0, 0xff);
    1118                 :     }
    1119                 : 
    1120             698 :     if (PREF_CHANGED(HTTP_PREF("spdy.enabled"))) {
    1121             679 :         rv = prefs->GetBoolPref(HTTP_PREF("spdy.enabled"), &cVar);
    1122             679 :         if (NS_SUCCEEDED(rv))
    1123             679 :             mEnableSpdy = cVar;
    1124                 :     }
    1125                 : 
    1126             698 :     if (PREF_CHANGED(HTTP_PREF("spdy.coalesce-hostnames"))) {
    1127             679 :         rv = prefs->GetBoolPref(HTTP_PREF("spdy.coalesce-hostnames"), &cVar);
    1128             679 :         if (NS_SUCCEEDED(rv))
    1129             679 :             mCoalesceSpdy = cVar;
    1130                 :     }
    1131                 : 
    1132             698 :     if (PREF_CHANGED(HTTP_PREF("spdy.use-alternate-protocol"))) {
    1133                 :         rv = prefs->GetBoolPref(HTTP_PREF("spdy.use-alternate-protocol"),
    1134             679 :                                 &cVar);
    1135             679 :         if (NS_SUCCEEDED(rv))
    1136             679 :             mUseAlternateProtocol = cVar;
    1137                 :     }
    1138                 : 
    1139             698 :     if (PREF_CHANGED(HTTP_PREF("spdy.timeout"))) {
    1140             679 :         rv = prefs->GetIntPref(HTTP_PREF("spdy.timeout"), &val);
    1141             679 :         if (NS_SUCCEEDED(rv))
    1142             679 :             mSpdyTimeout = PR_SecondsToInterval(clamped(val, 1, 0xffff));
    1143                 :     }
    1144                 : 
    1145             698 :     if (PREF_CHANGED(HTTP_PREF("spdy.chunk-size"))) {
    1146             679 :         rv = prefs->GetIntPref(HTTP_PREF("spdy.chunk-size"), &val);
    1147             679 :         if (NS_SUCCEEDED(rv))
    1148             679 :             mSpdySendingChunkSize = (PRUint32) clamped(val, 1, 0x7fffffff);
    1149                 :     }
    1150                 : 
    1151                 :     // The amount of idle seconds on a spdy connection before initiating a
    1152                 :     // server ping. 0 will disable.
    1153             698 :     if (PREF_CHANGED(HTTP_PREF("spdy.ping-threshold"))) {
    1154             679 :         rv = prefs->GetIntPref(HTTP_PREF("spdy.ping-threshold"), &val);
    1155             679 :         if (NS_SUCCEEDED(rv))
    1156                 :             mSpdyPingThreshold =
    1157             679 :                 PR_SecondsToInterval((PRUint16) clamped(val, 0, 0x7fffffff));
    1158                 :     }
    1159                 : 
    1160                 :     // The amount of seconds to wait for a spdy ping response before
    1161                 :     // closing the session.
    1162             698 :     if (PREF_CHANGED(HTTP_PREF("spdy.ping-timeout"))) {
    1163             679 :         rv = prefs->GetIntPref(HTTP_PREF("spdy.ping-timeout"), &val);
    1164             679 :         if (NS_SUCCEEDED(rv))
    1165                 :             mSpdyPingTimeout =
    1166             679 :                 PR_SecondsToInterval((PRUint16) clamped(val, 0, 0x7fffffff));
    1167                 :     }
    1168                 : 
    1169                 :     //
    1170                 :     // INTL options
    1171                 :     //
    1172                 : 
    1173             698 :     if (PREF_CHANGED(INTL_ACCEPT_LANGUAGES)) {
    1174            1358 :         nsCOMPtr<nsIPrefLocalizedString> pls;
    1175                 :         prefs->GetComplexValue(INTL_ACCEPT_LANGUAGES,
    1176                 :                                 NS_GET_IID(nsIPrefLocalizedString),
    1177             679 :                                 getter_AddRefs(pls));
    1178             679 :         if (pls) {
    1179            1358 :             nsXPIDLString uval;
    1180             679 :             pls->ToString(getter_Copies(uval));
    1181             679 :             if (uval)
    1182             679 :                 SetAcceptLanguages(NS_ConvertUTF16toUTF8(uval).get());
    1183                 :         } 
    1184                 :     }
    1185                 : 
    1186                 :     //
    1187                 :     // IDN options
    1188                 :     //
    1189                 : 
    1190             698 :     if (PREF_CHANGED(NETWORK_ENABLEIDN)) {
    1191             679 :         bool enableIDN = false;
    1192             679 :         prefs->GetBoolPref(NETWORK_ENABLEIDN, &enableIDN);
    1193                 :         // No locking is required here since this method runs in the main
    1194                 :         // UI thread, and so do all the methods in nsHttpChannel.cpp
    1195                 :         // (mIDNConverter is used by nsHttpChannel)
    1196             679 :         if (enableIDN && !mIDNConverter) {
    1197             679 :             mIDNConverter = do_GetService(NS_IDNSERVICE_CONTRACTID);
    1198             679 :             NS_ASSERTION(mIDNConverter, "idnSDK not installed");
    1199                 :         }
    1200               0 :         else if (!enableIDN && mIDNConverter)
    1201               0 :             mIDNConverter = nsnull;
    1202                 :     }
    1203                 : 
    1204                 :     //
    1205                 :     // Tracking options
    1206                 :     //
    1207                 : 
    1208             698 :     if (PREF_CHANGED(DONOTTRACK_HEADER_ENABLED)) {
    1209             679 :         cVar = false;
    1210             679 :         rv = prefs->GetBoolPref(DONOTTRACK_HEADER_ENABLED, &cVar);
    1211             679 :         if (NS_SUCCEEDED(rv)) {
    1212             679 :             mDoNotTrackEnabled = cVar;
    1213                 :         }
    1214                 :     }
    1215                 : 
    1216                 :     //
    1217                 :     // Telemetry
    1218                 :     //
    1219                 : 
    1220             698 :     if (PREF_CHANGED(TELEMETRY_ENABLED)) {
    1221             679 :         cVar = false;
    1222             679 :         rv = prefs->GetBoolPref(TELEMETRY_ENABLED, &cVar);
    1223             679 :         if (NS_SUCCEEDED(rv)) {
    1224             679 :             mTelemetryEnabled = cVar;
    1225                 :         }
    1226                 :     }
    1227                 : 
    1228                 :     //
    1229                 :     // network.allow-experiments
    1230                 :     //
    1231                 : 
    1232             698 :     if (PREF_CHANGED(ALLOW_EXPERIMENTS)) {
    1233             679 :         cVar = true;
    1234             679 :         rv = prefs->GetBoolPref(ALLOW_EXPERIMENTS, &cVar);
    1235             679 :         if (NS_SUCCEEDED(rv)) {
    1236             679 :             mAllowExperiments = cVar;
    1237                 :         }
    1238                 :     }
    1239                 : 
    1240                 : #undef PREF_CHANGED
    1241                 : #undef MULTI_PREF_CHANGED
    1242             698 : }
    1243                 : 
    1244                 : /**
    1245                 :  *  Allocates a C string into that contains a ISO 639 language list
    1246                 :  *  notated with HTTP "q" values for output with a HTTP Accept-Language
    1247                 :  *  header. Previous q values will be stripped because the order of
    1248                 :  *  the langs imply the q value. The q values are calculated by dividing
    1249                 :  *  1.0 amongst the number of languages present.
    1250                 :  *
    1251                 :  *  Ex: passing: "en, ja"
    1252                 :  *      returns: "en,ja;q=0.5"
    1253                 :  *
    1254                 :  *      passing: "en, ja, fr_CA"
    1255                 :  *      returns: "en,ja;q=0.7,fr_CA;q=0.3"
    1256                 :  */
    1257                 : static nsresult
    1258             679 : PrepareAcceptLanguages(const char *i_AcceptLanguages, nsACString &o_AcceptLanguages)
    1259                 : {
    1260             679 :     if (!i_AcceptLanguages)
    1261               0 :         return NS_OK;
    1262                 : 
    1263                 :     PRUint32 n, size, wrote;
    1264                 :     double q, dec;
    1265                 :     char *p, *p2, *token, *q_Accept, *o_Accept;
    1266                 :     const char *comma;
    1267                 :     PRInt32 available;
    1268                 : 
    1269             679 :     o_Accept = nsCRT::strdup(i_AcceptLanguages);
    1270             679 :     if (!o_Accept)
    1271               0 :         return NS_ERROR_OUT_OF_MEMORY;
    1272            6790 :     for (p = o_Accept, n = size = 0; '\0' != *p; p++) {
    1273            6111 :         if (*p == ',') n++;
    1274            6111 :             size++;
    1275                 :     }
    1276                 : 
    1277             679 :     available = size + ++n * 11 + 1;
    1278            1358 :     q_Accept = new char[available];
    1279             679 :     if (!q_Accept) {
    1280               0 :         nsCRT::free(o_Accept);
    1281               0 :         return NS_ERROR_OUT_OF_MEMORY;
    1282                 :     }
    1283             679 :     *q_Accept = '\0';
    1284             679 :     q = 1.0;
    1285             679 :     dec = q / (double) n;
    1286             679 :     n = 0;
    1287             679 :     p2 = q_Accept;
    1288            2037 :     for (token = nsCRT::strtok(o_Accept, ",", &p);
    1289                 :          token != (char *) 0;
    1290            1358 :          token = nsCRT::strtok(p, ",", &p))
    1291                 :     {
    1292            1358 :         token = net_FindCharNotInSet(token, HTTP_LWS);
    1293                 :         char* trim;
    1294            1358 :         trim = net_FindCharInSet(token, ";" HTTP_LWS);
    1295            1358 :         if (trim != (char*)0)  // remove "; q=..." if present
    1296            1358 :             *trim = '\0';
    1297                 : 
    1298            1358 :         if (*token != '\0') {
    1299            1358 :             comma = n++ != 0 ? "," : ""; // delimiter if not first item
    1300            1358 :             PRUint32 u = QVAL_TO_UINT(q);
    1301            1358 :             if (u < 10)
    1302             679 :                 wrote = PR_snprintf(p2, available, "%s%s;q=0.%u", comma, token, u);
    1303                 :             else
    1304             679 :                 wrote = PR_snprintf(p2, available, "%s%s", comma, token);
    1305            1358 :             q -= dec;
    1306            1358 :             p2 += wrote;
    1307            1358 :             available -= wrote;
    1308            1358 :             NS_ASSERTION(available > 0, "allocated string not long enough");
    1309                 :         }
    1310                 :     }
    1311             679 :     nsCRT::free(o_Accept);
    1312                 : 
    1313             679 :     o_AcceptLanguages.Assign((const char *) q_Accept);
    1314             679 :     delete [] q_Accept;
    1315                 : 
    1316             679 :     return NS_OK;
    1317                 : }
    1318                 : 
    1319                 : nsresult
    1320             679 : nsHttpHandler::SetAcceptLanguages(const char *aAcceptLanguages) 
    1321                 : {
    1322            1358 :     nsCAutoString buf;
    1323             679 :     nsresult rv = PrepareAcceptLanguages(aAcceptLanguages, buf);
    1324             679 :     if (NS_SUCCEEDED(rv))
    1325             679 :         mAcceptLanguages.Assign(buf);
    1326             679 :     return rv;
    1327                 : }
    1328                 : 
    1329                 : nsresult
    1330             679 : nsHttpHandler::SetAccept(const char *aAccept) 
    1331                 : {
    1332             679 :     mAccept = aAccept;
    1333             679 :     return NS_OK;
    1334                 : }
    1335                 : 
    1336                 : nsresult
    1337             679 : nsHttpHandler::SetAcceptEncodings(const char *aAcceptEncodings) 
    1338                 : {
    1339             679 :     mAcceptEncodings = aAcceptEncodings;
    1340             679 :     return NS_OK;
    1341                 : }
    1342                 : 
    1343                 : //-----------------------------------------------------------------------------
    1344                 : // nsHttpHandler::nsISupports
    1345                 : //-----------------------------------------------------------------------------
    1346                 : 
    1347          464964 : NS_IMPL_THREADSAFE_ISUPPORTS5(nsHttpHandler,
    1348                 :                               nsIHttpProtocolHandler,
    1349                 :                               nsIProxiedProtocolHandler,
    1350                 :                               nsIProtocolHandler,
    1351                 :                               nsIObserver,
    1352                 :                               nsISupportsWeakReference)
    1353                 : 
    1354                 : //-----------------------------------------------------------------------------
    1355                 : // nsHttpHandler::nsIProtocolHandler
    1356                 : //-----------------------------------------------------------------------------
    1357                 : 
    1358                 : NS_IMETHODIMP
    1359               0 : nsHttpHandler::GetScheme(nsACString &aScheme)
    1360                 : {
    1361               0 :     aScheme.AssignLiteral("http");
    1362               0 :     return NS_OK;
    1363                 : }
    1364                 : 
    1365                 : NS_IMETHODIMP
    1366            3690 : nsHttpHandler::GetDefaultPort(PRInt32 *result)
    1367                 : {
    1368            3690 :     *result = NS_HTTP_DEFAULT_PORT;
    1369            3690 :     return NS_OK;
    1370                 : }
    1371                 : 
    1372                 : NS_IMETHODIMP
    1373           26451 : nsHttpHandler::GetProtocolFlags(PRUint32 *result)
    1374                 : {
    1375           26451 :     *result = NS_HTTP_PROTOCOL_FLAGS;
    1376           26451 :     return NS_OK;
    1377                 : }
    1378                 : 
    1379                 : NS_IMETHODIMP
    1380           34745 : nsHttpHandler::NewURI(const nsACString &aSpec,
    1381                 :                       const char *aCharset,
    1382                 :                       nsIURI *aBaseURI,
    1383                 :                       nsIURI **aURI)
    1384                 : {
    1385           34745 :     LOG(("nsHttpHandler::NewURI\n"));
    1386           34745 :     return ::NewURI(aSpec, aCharset, aBaseURI, NS_HTTP_DEFAULT_PORT, aURI);
    1387                 : }
    1388                 : 
    1389                 : NS_IMETHODIMP
    1390            3485 : nsHttpHandler::NewChannel(nsIURI *uri, nsIChannel **result)
    1391                 : {
    1392            3485 :     LOG(("nsHttpHandler::NewChannel\n"));
    1393                 : 
    1394            3485 :     NS_ENSURE_ARG_POINTER(uri);
    1395            3485 :     NS_ENSURE_ARG_POINTER(result);
    1396                 : 
    1397            3485 :     bool isHttp = false, isHttps = false;
    1398                 : 
    1399                 :     // Verify that we have been given a valid scheme
    1400            3485 :     nsresult rv = uri->SchemeIs("http", &isHttp);
    1401            3485 :     if (NS_FAILED(rv)) return rv;
    1402            3485 :     if (!isHttp) {
    1403               5 :         rv = uri->SchemeIs("https", &isHttps);
    1404               5 :         if (NS_FAILED(rv)) return rv;
    1405               5 :         if (!isHttps) {
    1406               0 :             NS_WARNING("Invalid URI scheme");
    1407               0 :             return NS_ERROR_UNEXPECTED;
    1408                 :         }
    1409                 :     }
    1410                 :     
    1411            3485 :     return NewProxiedChannel(uri, nsnull, result);
    1412                 : }
    1413                 : 
    1414                 : NS_IMETHODIMP 
    1415               0 : nsHttpHandler::AllowPort(PRInt32 port, const char *scheme, bool *_retval)
    1416                 : {
    1417                 :     // don't override anything.  
    1418               0 :     *_retval = false;
    1419               0 :     return NS_OK;
    1420                 : }
    1421                 : 
    1422                 : //-----------------------------------------------------------------------------
    1423                 : // nsHttpHandler::nsIProxiedProtocolHandler
    1424                 : //-----------------------------------------------------------------------------
    1425                 : 
    1426                 : NS_IMETHODIMP
    1427            3514 : nsHttpHandler::NewProxiedChannel(nsIURI *uri,
    1428                 :                                  nsIProxyInfo* givenProxyInfo,
    1429                 :                                  nsIChannel **result)
    1430                 : {
    1431            7028 :     nsRefPtr<HttpBaseChannel> httpChannel;
    1432                 : 
    1433            3514 :     LOG(("nsHttpHandler::NewProxiedChannel [proxyInfo=%p]\n",
    1434                 :         givenProxyInfo));
    1435                 :     
    1436            7028 :     nsCOMPtr<nsProxyInfo> proxyInfo;
    1437            3514 :     if (givenProxyInfo) {
    1438              24 :         proxyInfo = do_QueryInterface(givenProxyInfo);
    1439              24 :         NS_ENSURE_ARG(proxyInfo);
    1440                 :     }
    1441                 : 
    1442                 :     bool https;
    1443            3514 :     nsresult rv = uri->SchemeIs("https", &https);
    1444            3514 :     if (NS_FAILED(rv))
    1445               0 :         return rv;
    1446                 : 
    1447            3514 :     if (IsNeckoChild()) {
    1448               0 :         httpChannel = new HttpChannelChild();
    1449                 :     } else {
    1450            3514 :         httpChannel = new nsHttpChannel();
    1451                 :     }
    1452                 : 
    1453                 :     // select proxy caps if using a non-transparent proxy.  SSL tunneling
    1454                 :     // should not use proxy settings.
    1455                 :     PRInt8 caps;
    1456            3514 :     if (proxyInfo && !nsCRT::strcmp(proxyInfo->Type(), "http") && !https)
    1457              14 :         caps = mProxyCapabilities;
    1458                 :     else
    1459            3500 :         caps = mCapabilities;
    1460                 : 
    1461            3514 :     if (https) {
    1462                 :         // enable pipelining over SSL if requested
    1463               5 :         if (mPipeliningOverSSL)
    1464               0 :             caps |= NS_HTTP_ALLOW_PIPELINING;
    1465                 : 
    1466               5 :         if (!IsNeckoChild()) {
    1467                 :             // HACK: make sure PSM gets initialized on the main thread.
    1468               5 :             net_EnsurePSMInit();
    1469                 :         }
    1470                 :     }
    1471                 : 
    1472            3514 :     rv = httpChannel->Init(uri, caps, proxyInfo);
    1473            3514 :     if (NS_FAILED(rv))
    1474               0 :         return rv;
    1475                 : 
    1476            3514 :     httpChannel.forget(result);
    1477            3514 :     return NS_OK;
    1478                 : }
    1479                 : 
    1480                 : //-----------------------------------------------------------------------------
    1481                 : // nsHttpHandler::nsIHttpProtocolHandler
    1482                 : //-----------------------------------------------------------------------------
    1483                 : 
    1484                 : NS_IMETHODIMP
    1485              47 : nsHttpHandler::GetUserAgent(nsACString &value)
    1486                 : {
    1487              47 :     value = UserAgent();
    1488              47 :     return NS_OK;
    1489                 : }
    1490                 : 
    1491                 : NS_IMETHODIMP
    1492               0 : nsHttpHandler::GetAppName(nsACString &value)
    1493                 : {
    1494               0 :     value = mLegacyAppName;
    1495               0 :     return NS_OK;
    1496                 : }
    1497                 : 
    1498                 : NS_IMETHODIMP
    1499               0 : nsHttpHandler::GetAppVersion(nsACString &value)
    1500                 : {
    1501               0 :     value = mLegacyAppVersion;
    1502               0 :     return NS_OK;
    1503                 : }
    1504                 : 
    1505                 : NS_IMETHODIMP
    1506               0 : nsHttpHandler::GetProduct(nsACString &value)
    1507                 : {
    1508               0 :     value = mProduct;
    1509               0 :     return NS_OK;
    1510                 : }
    1511                 : 
    1512                 : NS_IMETHODIMP
    1513               0 : nsHttpHandler::GetProductSub(nsACString &value)
    1514                 : {
    1515               0 :     value = mProductSub;
    1516               0 :     return NS_OK;
    1517                 : }
    1518                 : 
    1519                 : NS_IMETHODIMP
    1520               1 : nsHttpHandler::GetPlatform(nsACString &value)
    1521                 : {
    1522               1 :     value = mPlatform;
    1523               1 :     return NS_OK;
    1524                 : }
    1525                 : 
    1526                 : NS_IMETHODIMP
    1527              75 : nsHttpHandler::GetOscpu(nsACString &value)
    1528                 : {
    1529              75 :     value = mOscpu;
    1530              75 :     return NS_OK;
    1531                 : }
    1532                 : 
    1533                 : NS_IMETHODIMP
    1534               0 : nsHttpHandler::GetMisc(nsACString &value)
    1535                 : {
    1536               0 :     value = mMisc;
    1537               0 :     return NS_OK;
    1538                 : }
    1539                 : 
    1540                 : //-----------------------------------------------------------------------------
    1541                 : // nsHttpHandler::nsIObserver
    1542                 : //-----------------------------------------------------------------------------
    1543                 : 
    1544                 : NS_IMETHODIMP
    1545            1478 : nsHttpHandler::Observe(nsISupports *subject,
    1546                 :                        const char *topic,
    1547                 :                        const PRUnichar *data)
    1548                 : {
    1549            1478 :     LOG(("nsHttpHandler::Observe [topic=\"%s\"]\n", topic));
    1550                 : 
    1551            1478 :     if (strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) {
    1552              38 :         nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(subject);
    1553              19 :         if (prefBranch)
    1554              19 :             PrefsChanged(prefBranch, NS_ConvertUTF16toUTF8(data).get());
    1555                 :     }
    1556            2386 :     else if (strcmp(topic, "profile-change-net-teardown")    == 0 ||
    1557             927 :              strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)    == 0) {
    1558                 : 
    1559                 :         // clear cache of all authentication credentials.
    1560            1211 :         mAuthCache.ClearAll();
    1561                 : 
    1562                 :         // ensure connection manager is shutdown
    1563            1211 :         if (mConnMgr)
    1564            1211 :             mConnMgr->Shutdown();
    1565                 : 
    1566                 :         // need to reset the session start time since cache validation may
    1567                 :         // depend on this value.
    1568            1211 :         mSessionStartTime = NowInSeconds();
    1569                 :     }
    1570             248 :     else if (strcmp(topic, "profile-change-net-restore") == 0) {
    1571                 :         // initialize connection manager
    1572               0 :         InitConnectionMgr();
    1573                 :     }
    1574             248 :     else if (strcmp(topic, "net:clear-active-logins") == 0) {
    1575               1 :         mAuthCache.ClearAll();
    1576                 :     }
    1577             247 :     else if (strcmp(topic, NS_PRIVATE_BROWSING_SWITCH_TOPIC) == 0) {
    1578             123 :         if (NS_LITERAL_STRING(NS_PRIVATE_BROWSING_ENTER).Equals(data))
    1579              56 :             mInPrivateBrowsingMode = PRIVATE_BROWSING_ON;
    1580              67 :         else if (NS_LITERAL_STRING(NS_PRIVATE_BROWSING_LEAVE).Equals(data))
    1581              67 :             mInPrivateBrowsingMode = PRIVATE_BROWSING_OFF;
    1582             123 :         if (mConnMgr)
    1583             123 :             mConnMgr->ClosePersistentConnections();
    1584                 :     }
    1585             124 :     else if (strcmp(topic, "net:prune-dead-connections") == 0) {
    1586             124 :         if (mConnMgr) {
    1587             124 :             mConnMgr->PruneDeadConnections();
    1588                 :         }
    1589                 :     }
    1590                 :   
    1591            1478 :     return NS_OK;
    1592                 : }
    1593                 : 
    1594                 : //-----------------------------------------------------------------------------
    1595                 : // nsHttpsHandler implementation
    1596                 : //-----------------------------------------------------------------------------
    1597                 : 
    1598            3013 : NS_IMPL_THREADSAFE_ISUPPORTS4(nsHttpsHandler,
    1599                 :                               nsIHttpProtocolHandler,
    1600                 :                               nsIProxiedProtocolHandler,
    1601                 :                               nsIProtocolHandler,
    1602                 :                               nsISupportsWeakReference)
    1603                 : 
    1604                 : nsresult
    1605              39 : nsHttpsHandler::Init()
    1606                 : {
    1607                 :     nsCOMPtr<nsIProtocolHandler> httpHandler(
    1608              78 :             do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http"));
    1609              39 :     NS_ASSERTION(httpHandler.get() != nsnull, "no http handler?");
    1610              39 :     return NS_OK;
    1611                 : }
    1612                 : 
    1613                 : NS_IMETHODIMP
    1614               0 : nsHttpsHandler::GetScheme(nsACString &aScheme)
    1615                 : {
    1616               0 :     aScheme.AssignLiteral("https");
    1617               0 :     return NS_OK;
    1618                 : }
    1619                 : 
    1620                 : NS_IMETHODIMP
    1621              26 : nsHttpsHandler::GetDefaultPort(PRInt32 *aPort)
    1622                 : {
    1623              26 :     *aPort = NS_HTTPS_DEFAULT_PORT;
    1624              26 :     return NS_OK;
    1625                 : }
    1626                 : 
    1627                 : NS_IMETHODIMP
    1628              14 : nsHttpsHandler::GetProtocolFlags(PRUint32 *aProtocolFlags)
    1629                 : {
    1630              14 :     *aProtocolFlags = NS_HTTP_PROTOCOL_FLAGS;
    1631              14 :     return NS_OK;
    1632                 : }
    1633                 : 
    1634                 : NS_IMETHODIMP
    1635             319 : nsHttpsHandler::NewURI(const nsACString &aSpec,
    1636                 :                        const char *aOriginCharset,
    1637                 :                        nsIURI *aBaseURI,
    1638                 :                        nsIURI **_retval)
    1639                 : {
    1640             319 :     return ::NewURI(aSpec, aOriginCharset, aBaseURI, NS_HTTPS_DEFAULT_PORT, _retval);
    1641                 : }
    1642                 : 
    1643                 : NS_IMETHODIMP
    1644               5 : nsHttpsHandler::NewChannel(nsIURI *aURI, nsIChannel **_retval)
    1645                 : {
    1646               5 :     NS_ABORT_IF_FALSE(gHttpHandler, "Should have a HTTP handler by now.");
    1647               5 :     if (!gHttpHandler)
    1648               0 :       return NS_ERROR_UNEXPECTED;
    1649               5 :     return gHttpHandler->NewChannel(aURI, _retval);
    1650                 : }
    1651                 : 
    1652                 : NS_IMETHODIMP
    1653               0 : nsHttpsHandler::AllowPort(PRInt32 aPort, const char *aScheme, bool *_retval)
    1654                 : {
    1655                 :     // don't override anything.  
    1656               0 :     *_retval = false;
    1657               0 :     return NS_OK;
    1658                 : }

Generated by: LCOV version 1.7