LCOV - app.info - netwerk/base/src/nsURIChecker.cpp

LCOV - code coverage report
| Current view: | directory - netwerk/base/src - nsURIChecker.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 131 | 0 | 0.0 %
| Date: | 2012-06-02 | Functions: | 25 | 0 | 0.0 %

           1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
           2                 : /* ***** BEGIN LICENSE BLOCK *****
           3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           4                 :  *
           5                 :  * The contents of this file are subject to the Mozilla Public License Version
           6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           7                 :  * the License. You may obtain a copy of the License at
           8                 :  * http://www.mozilla.org/MPL/
           9                 :  *
          10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          12                 :  * for the specific language governing rights and limitations under the
          13                 :  * License.
          14                 :  *
          15                 :  * The Original Code is mozilla.org code.
          16                 :  *
          17                 :  * The Initial Developer of the Original Code is
          18                 :  * Netscape Communications Corporation.
          19                 :  * Portions created by the Initial Developer are Copyright (C) 2001
          20                 :  * the Initial Developer. All Rights Reserved.
          21                 :  *
          22                 :  * Contributor(s):
          23                 :  *   Akkana Peck <akkana@netscape.com> (original author)
          24                 :  *   Darin Fisher <darin@meer.net>
          25                 :  *
          26                 :  * Alternatively, the contents of this file may be used under the terms of
          27                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          28                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          30                 :  * of those above. If you wish to allow use of your version of this file only
          31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          32                 :  * use your version of this file under the terms of the MPL, indicate your
          33                 :  * decision by deleting the provisions above and replace them with the notice
          34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          35                 :  * the provisions above, a recipient may use your version of this file under
          36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          37                 :  *
          38                 :  * ***** END LICENSE BLOCK ***** */
          39                 :
          40                 : #include "nsURIChecker.h"
          41                 : #include "nsIServiceManager.h"
          42                 : #include "nsIAuthPrompt.h"
          43                 : #include "nsIHttpChannel.h"
          44                 : #include "nsNetUtil.h"
          45                 : #include "nsString.h"
          46                 : #include "nsIAsyncVerifyRedirectCallback.h"
          47                 :
          48                 : //-----------------------------------------------------------------------------
          49                 :
          50                 : static bool
          51               0 : ServerIsNES3x(nsIHttpChannel *httpChannel)
          52                 : {
          53               0 :     nsCAutoString server;
          54               0 :     httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Server"), server);
          55                 :     // case sensitive string comparison is OK here.  the server string
          56                 :     // is a well-known value, so we should not have to worry about it
          57                 :     // being case-smashed or otherwise case-mutated.
          58                 :     return StringBeginsWith(server,
          59               0 :                             NS_LITERAL_CSTRING("Netscape-Enterprise/3."));
          60                 : }
          61                 :
          62                 : //-----------------------------------------------------------------------------
          63                 :
          64               0 : NS_IMPL_ISUPPORTS6(nsURIChecker,
          65                 :                    nsIURIChecker,
          66                 :                    nsIRequest,
          67                 :                    nsIRequestObserver,
          68                 :                    nsIStreamListener,
          69                 :                    nsIChannelEventSink,
          70                 :                    nsIInterfaceRequestor)
          71                 :
          72               0 : nsURIChecker::nsURIChecker()
          73                 :     : mStatus(NS_OK)
          74                 :     , mIsPending(false)
          75               0 :     , mAllowHead(true)
          76                 : {
          77               0 : }
          78                 :
          79                 : void
          80               0 : nsURIChecker::SetStatusAndCallBack(nsresult aStatus)
          81                 : {
          82               0 :     mStatus = aStatus;
          83               0 :     mIsPending = false;
          84                 :
          85               0 :     if (mObserver) {
          86               0 :         mObserver->OnStartRequest(this, mObserverContext);
          87               0 :         mObserver->OnStopRequest(this, mObserverContext, mStatus);
          88               0 :         mObserver = nsnull;
          89               0 :         mObserverContext = nsnull;
          90                 :     }
          91               0 : }
          92                 :
          93                 : nsresult
          94               0 : nsURIChecker::CheckStatus()
          95                 : {
          96               0 :     NS_ASSERTION(mChannel, "no channel");
          97                 :
          98                 :     nsresult status;
          99               0 :     nsresult rv = mChannel->GetStatus(&status);
         100                 :     // DNS errors and other obvious problems will return failure status
         101               0 :     if (NS_FAILED(rv) || NS_FAILED(status))
         102               0 :         return NS_BINDING_FAILED;
         103                 :
         104                 :     // If status is zero, it might still be an error if it's http:
         105                 :     // http has data even when there's an error like a 404.
         106               0 :     nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
         107               0 :     if (!httpChannel)
         108               0 :         return NS_BINDING_SUCCEEDED;
         109                 :
         110                 :     PRUint32 responseStatus;
         111               0 :     rv = httpChannel->GetResponseStatus(&responseStatus);
         112               0 :     if (NS_FAILED(rv))
         113               0 :         return NS_BINDING_FAILED;
         114                 :
         115                 :     // If it's between 200-299, it's valid:
         116               0 :     if (responseStatus / 100 == 2)
         117               0 :         return NS_BINDING_SUCCEEDED;
         118                 :
         119                 :     // If we got a 404 (not found), we need some extra checking:
         120                 :     // toplevel urls from Netscape Enterprise Server 3.6, like the old AOL-
         121                 :     // hosted http://www.mozilla.org, generate a 404 and will have to be
         122                 :     // retried without the head.
         123               0 :     if (responseStatus == 404) {
         124               0 :         if (mAllowHead && ServerIsNES3x(httpChannel)) {
         125               0 :             mAllowHead = false;
         126                 :
         127                 :             // save the current value of mChannel in case we can't issue
         128                 :             // the new request for some reason.
         129               0 :             nsCOMPtr<nsIChannel> lastChannel = mChannel;
         130                 :
         131               0 :             nsCOMPtr<nsIURI> uri;
         132                 :             PRUint32 loadFlags;
         133                 :
         134               0 :             rv  = lastChannel->GetOriginalURI(getter_AddRefs(uri));
         135               0 :             rv |= lastChannel->GetLoadFlags(&loadFlags);
         136                 :
         137                 :             // XXX we are carrying over the load flags, but what about other
         138                 :             // parameters that may have been set on lastChannel??
         139                 :
         140               0 :             if (NS_SUCCEEDED(rv)) {
         141               0 :                 rv = Init(uri);
         142               0 :                 if (NS_SUCCEEDED(rv)) {
         143               0 :                     rv = mChannel->SetLoadFlags(loadFlags);
         144               0 :                     if (NS_SUCCEEDED(rv)) {
         145               0 :                         rv = AsyncCheck(mObserver, mObserverContext);
         146                 :                         // if we succeeded in loading the new channel, then we
         147                 :                         // want to return without notifying our observer.
         148               0 :                         if (NS_SUCCEEDED(rv))
         149               0 :                             return NS_BASE_STREAM_WOULD_BLOCK;
         150                 :                     }
         151                 :                 }
         152                 :             }
         153                 :             // it is important to update this so our observer will be able
         154                 :             // to access our baseChannel attribute if they want.
         155               0 :             mChannel = lastChannel;
         156                 :         }
         157                 :     }
         158                 :
         159                 :     // If we get here, assume the resource does not exist.
         160               0 :     return NS_BINDING_FAILED;
         161                 : }
         162                 :
         163                 : //-----------------------------------------------------------------------------
         164                 : // nsIURIChecker methods:
         165                 : //-----------------------------------------------------------------------------
         166                 :
         167                 : NS_IMETHODIMP
         168               0 : nsURIChecker::Init(nsIURI *aURI)
         169                 : {
         170                 :     nsresult rv;
         171               0 :     nsCOMPtr<nsIIOService> ios = do_GetIOService(&rv);
         172               0 :     if (NS_FAILED(rv)) return rv;
         173                 :
         174               0 :     rv = ios->NewChannelFromURI(aURI, getter_AddRefs(mChannel));
         175               0 :     if (NS_FAILED(rv)) return rv;
         176                 :
         177               0 :     if (mAllowHead) {
         178               0 :         mAllowHead = false;
         179                 :         // See if it's an http channel, which needs special treatment:
         180               0 :         nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
         181               0 :         if (httpChannel) {
         182                 :             // We can have an HTTP channel that has a non-HTTP URL if
         183                 :             // we're doing FTP via an HTTP proxy, for example.  See for
         184                 :             // example bug 148813
         185               0 :             bool isReallyHTTP = false;
         186               0 :             aURI->SchemeIs("http", &isReallyHTTP);
         187               0 :             if (!isReallyHTTP)
         188               0 :                 aURI->SchemeIs("https", &isReallyHTTP);
         189               0 :             if (isReallyHTTP) {
         190               0 :                 httpChannel->SetRequestMethod(NS_LITERAL_CSTRING("HEAD"));
         191                 :                 // set back to true so we'll know that this request is issuing
         192                 :                 // a HEAD request.  this is used down in OnStartRequest to
         193                 :                 // handle cases where we need to repeat the request as a normal
         194                 :                 // GET to deal with server borkage.
         195               0 :                 mAllowHead = true;
         196                 :             }
         197                 :         }
         198                 :     }
         199               0 :     return NS_OK;
         200                 : }
         201                 :
         202                 : NS_IMETHODIMP
         203               0 : nsURIChecker::AsyncCheck(nsIRequestObserver *aObserver,
         204                 :                          nsISupports *aObserverContext)
         205                 : {
         206               0 :     NS_ENSURE_TRUE(mChannel, NS_ERROR_NOT_INITIALIZED);
         207                 :
         208                 :     // Hook us up to listen to redirects and the like (this creates a reference
         209                 :     // cycle!)
         210               0 :     mChannel->SetNotificationCallbacks(this);
         211                 :
         212                 :     // and start the request:
         213               0 :     nsresult rv = mChannel->AsyncOpen(this, nsnull);
         214               0 :     if (NS_FAILED(rv))
         215               0 :         mChannel = nsnull;
         216                 :     else {
         217                 :         // ok, wait for OnStartRequest to fire.
         218               0 :         mIsPending = true;
         219               0 :         mObserver = aObserver;
         220               0 :         mObserverContext = aObserverContext;
         221                 :     }
         222               0 :     return rv;
         223                 : }
         224                 :
         225                 : NS_IMETHODIMP
         226               0 : nsURIChecker::GetBaseChannel(nsIChannel **aChannel)
         227                 : {
         228               0 :     NS_ENSURE_TRUE(mChannel, NS_ERROR_NOT_INITIALIZED);
         229               0 :     NS_ADDREF(*aChannel = mChannel);
         230               0 :     return NS_OK;
         231                 : }
         232                 :
         233                 : //-----------------------------------------------------------------------------
         234                 : // nsIRequest methods:
         235                 : //-----------------------------------------------------------------------------
         236                 :
         237                 : NS_IMETHODIMP
         238               0 : nsURIChecker::GetName(nsACString &aName)
         239                 : {
         240               0 :     NS_ENSURE_TRUE(mChannel, NS_ERROR_NOT_INITIALIZED);
         241               0 :     return mChannel->GetName(aName);
         242                 : }
         243                 :
         244                 : NS_IMETHODIMP
         245               0 : nsURIChecker::IsPending(bool *aPendingRet)
         246                 : {
         247               0 :     *aPendingRet = mIsPending;
         248               0 :     return NS_OK;
         249                 : }
         250                 :
         251                 : NS_IMETHODIMP
         252               0 : nsURIChecker::GetStatus(nsresult* aStatusRet)
         253                 : {
         254               0 :     *aStatusRet = mStatus;
         255               0 :     return NS_OK;
         256                 : }
         257                 :
         258                 : NS_IMETHODIMP
         259               0 : nsURIChecker::Cancel(nsresult status)
         260                 : {
         261               0 :     NS_ENSURE_TRUE(mChannel, NS_ERROR_NOT_INITIALIZED);
         262               0 :     return mChannel->Cancel(status);
         263                 : }
         264                 :
         265                 : NS_IMETHODIMP
         266               0 : nsURIChecker::Suspend()
         267                 : {
         268               0 :     NS_ENSURE_TRUE(mChannel, NS_ERROR_NOT_INITIALIZED);
         269               0 :     return mChannel->Suspend();
         270                 : }
         271                 :
         272                 : NS_IMETHODIMP
         273               0 : nsURIChecker::Resume()
         274                 : {
         275               0 :     NS_ENSURE_TRUE(mChannel, NS_ERROR_NOT_INITIALIZED);
         276               0 :     return mChannel->Resume();
         277                 : }
         278                 :
         279                 : NS_IMETHODIMP
         280               0 : nsURIChecker::GetLoadGroup(nsILoadGroup **aLoadGroup)
         281                 : {
         282               0 :     NS_ENSURE_TRUE(mChannel, NS_ERROR_NOT_INITIALIZED);
         283               0 :     return mChannel->GetLoadGroup(aLoadGroup);
         284                 : }
         285                 :
         286                 : NS_IMETHODIMP
         287               0 : nsURIChecker::SetLoadGroup(nsILoadGroup *aLoadGroup)
         288                 : {
         289               0 :     NS_ENSURE_TRUE(mChannel, NS_ERROR_NOT_INITIALIZED);
         290               0 :     return mChannel->SetLoadGroup(aLoadGroup);
         291                 : }
         292                 :
         293                 : NS_IMETHODIMP
         294               0 : nsURIChecker::GetLoadFlags(nsLoadFlags *aLoadFlags)
         295                 : {
         296               0 :     NS_ENSURE_TRUE(mChannel, NS_ERROR_NOT_INITIALIZED);
         297               0 :     return mChannel->GetLoadFlags(aLoadFlags);
         298                 : }
         299                 :
         300                 : NS_IMETHODIMP
         301               0 : nsURIChecker::SetLoadFlags(nsLoadFlags aLoadFlags)
         302                 : {
         303               0 :     NS_ENSURE_TRUE(mChannel, NS_ERROR_NOT_INITIALIZED);
         304               0 :     return mChannel->SetLoadFlags(aLoadFlags);
         305                 : }
         306                 :
         307                 : //-----------------------------------------------------------------------------
         308                 : // nsIRequestObserver methods:
         309                 : //-----------------------------------------------------------------------------
         310                 :
         311                 : NS_IMETHODIMP
         312               0 : nsURIChecker::OnStartRequest(nsIRequest *aRequest, nsISupports *aCtxt)
         313                 : {
         314               0 :     NS_ASSERTION(aRequest == mChannel, "unexpected request");
         315                 :
         316               0 :     nsresult rv = CheckStatus();
         317               0 :     if (rv != NS_BASE_STREAM_WOULD_BLOCK)
         318               0 :         SetStatusAndCallBack(rv);
         319                 :
         320                 :     // cancel the request (we don't care to look at the data).
         321               0 :     return NS_BINDING_ABORTED;
         322                 : }
         323                 :
         324                 : NS_IMETHODIMP
         325               0 : nsURIChecker::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
         326                 :                              nsresult statusCode)
         327                 : {
         328                 :     // NOTE: we may have kicked off a subsequent request, so we should not do
         329                 :     // any cleanup unless this request matches the one we are currently using.
         330               0 :     if (mChannel == request) {
         331                 :         // break reference cycle between us and the channel (see comment in
         332                 :         // AsyncCheckURI)
         333               0 :         mChannel = nsnull;
         334                 :     }
         335               0 :     return NS_OK;
         336                 : }
         337                 :
         338                 : //-----------------------------------------------------------------------------
         339                 : // nsIStreamListener methods:
         340                 : //-----------------------------------------------------------------------------
         341                 :
         342                 : NS_IMETHODIMP
         343               0 : nsURIChecker::OnDataAvailable(nsIRequest *aRequest, nsISupports *aCtxt,
         344                 :                                nsIInputStream *aInput, PRUint32 aOffset,
         345                 :                                PRUint32 aCount)
         346                 : {
         347               0 :     NS_NOTREACHED("nsURIChecker::OnDataAvailable");
         348               0 :     return NS_BINDING_ABORTED;
         349                 : }
         350                 :
         351                 : //-----------------------------------------------------------------------------
         352                 : // nsIInterfaceRequestor methods:
         353                 : //-----------------------------------------------------------------------------
         354                 :
         355                 : NS_IMETHODIMP
         356               0 : nsURIChecker::GetInterface(const nsIID & aIID, void **aResult)
         357                 : {
         358               0 :     if (mObserver && aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
         359               0 :         nsCOMPtr<nsIInterfaceRequestor> req = do_QueryInterface(mObserver);
         360               0 :         if (req)
         361               0 :             return req->GetInterface(aIID, aResult);
         362                 :     }
         363               0 :     return QueryInterface(aIID, aResult);
         364                 : }
         365                 :
         366                 : //-----------------------------------------------------------------------------
         367                 : // nsIChannelEventSink methods:
         368                 : //-----------------------------------------------------------------------------
         369                 :
         370                 : NS_IMETHODIMP
         371               0 : nsURIChecker::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
         372                 :                                      nsIChannel *aNewChannel,
         373                 :                                      PRUint32 aFlags,
         374                 :                                      nsIAsyncVerifyRedirectCallback *callback)
         375                 : {
         376                 :     // We have a new channel
         377               0 :     mChannel = aNewChannel;
         378               0 :     callback->OnRedirectVerifyCallback(NS_OK);
         379               0 :     return NS_OK;
         380                 : }

Generated by: LCOV version 1.7