LCOV - code coverage report
Current view: directory - netwerk/protocol/data - nsDataHandler.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 102 82 80.4 %
Date: 2012-06-02 Functions: 14 11 78.6 %

       1                 : /* -*- Mode: C++; tab-width: 2; 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) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      26                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : #include "nspr.h"
      39                 : #include "nsDataChannel.h"
      40                 : #include "nsDataHandler.h"
      41                 : #include "nsIURL.h"
      42                 : #include "nsCRT.h"
      43                 : #include "nsIComponentManager.h"
      44                 : #include "nsIServiceManager.h"
      45                 : #include "nsIInterfaceRequestor.h"
      46                 : #include "nsIInterfaceRequestorUtils.h"
      47                 : #include "nsIProgressEventSink.h"
      48                 : #include "nsNetCID.h"
      49                 : #include "nsNetError.h"
      50                 : 
      51                 : static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
      52                 : 
      53                 : ////////////////////////////////////////////////////////////////////////////////
      54                 : 
      55              52 : nsDataHandler::nsDataHandler() {
      56              52 : }
      57                 : 
      58             104 : nsDataHandler::~nsDataHandler() {
      59             208 : }
      60                 : 
      61            7976 : NS_IMPL_ISUPPORTS1(nsDataHandler, nsIProtocolHandler)
      62                 : 
      63                 : nsresult
      64              52 : nsDataHandler::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult) {
      65                 : 
      66              52 :     nsDataHandler* ph = new nsDataHandler();
      67              52 :     if (ph == nsnull)
      68               0 :         return NS_ERROR_OUT_OF_MEMORY;
      69              52 :     NS_ADDREF(ph);
      70              52 :     nsresult rv = ph->QueryInterface(aIID, aResult);
      71              52 :     NS_RELEASE(ph);
      72              52 :     return rv;
      73                 : }
      74                 :     
      75                 : ////////////////////////////////////////////////////////////////////////////////
      76                 : // nsIProtocolHandler methods:
      77                 : 
      78                 : NS_IMETHODIMP
      79               0 : nsDataHandler::GetScheme(nsACString &result) {
      80               0 :     result.AssignLiteral("data");
      81               0 :     return NS_OK;
      82                 : }
      83                 : 
      84                 : NS_IMETHODIMP
      85               0 : nsDataHandler::GetDefaultPort(PRInt32 *result) {
      86                 :     // no ports for data protocol
      87               0 :     *result = -1;
      88               0 :     return NS_OK;
      89                 : }
      90                 : 
      91                 : NS_IMETHODIMP
      92             318 : nsDataHandler::GetProtocolFlags(PRUint32 *result) {
      93                 :     *result = URI_NORELATIVE | URI_NOAUTH | URI_INHERITS_SECURITY_CONTEXT |
      94             318 :         URI_LOADABLE_BY_ANYONE | URI_NON_PERSISTABLE | URI_IS_LOCAL_RESOURCE;
      95             318 :     return NS_OK;
      96                 : }
      97                 : 
      98                 : NS_IMETHODIMP
      99             556 : nsDataHandler::NewURI(const nsACString &aSpec,
     100                 :                       const char *aCharset, // ignore charset info
     101                 :                       nsIURI *aBaseURI,
     102                 :                       nsIURI **result) {
     103                 :     nsresult rv;
     104            1112 :     nsRefPtr<nsIURI> uri;
     105                 : 
     106            1112 :     nsCString spec(aSpec);
     107                 : 
     108             556 :     if (aBaseURI && !spec.IsEmpty() && spec[0] == '#') {
     109                 :         // Looks like a reference instead of a fully-specified URI.
     110                 :         // --> initialize |uri| as a clone of |aBaseURI|, with ref appended.
     111               5 :         rv = aBaseURI->Clone(getter_AddRefs(uri));
     112               5 :         if (NS_FAILED(rv))
     113               0 :             return rv;
     114               5 :         rv = uri->SetRef(spec);
     115                 :     } else {
     116                 :         // Otherwise, we'll assume |spec| is a fully-specified data URI
     117            1653 :         nsCAutoString contentType, contentCharset, dataBuffer, hashRef;
     118                 :         bool base64;
     119             551 :         rv = ParseURI(spec, contentType, contentCharset, base64, dataBuffer, hashRef);
     120             551 :         if (NS_FAILED(rv))
     121               0 :             return rv;
     122                 : 
     123                 :         // Strip whitespace unless this is text, where whitespace is important
     124                 :         // Don't strip escaped whitespace though (bug 391951)
     125             562 :         if (base64 || (strncmp(contentType.get(),"text/",5) != 0 &&
     126              11 :                        contentType.Find("xml") == kNotFound)) {
     127                 :             // it's ascii encoded binary, don't let any spaces in
     128             122 :             spec.StripWhitespace();
     129                 :         }
     130                 : 
     131             551 :         uri = do_CreateInstance(kSimpleURICID, &rv);
     132             551 :         if (NS_FAILED(rv))
     133               0 :             return rv;
     134            1102 :         rv = uri->SetSpec(spec);
     135                 :     }
     136                 : 
     137             556 :     if (NS_FAILED(rv))
     138               0 :         return rv;
     139                 : 
     140             556 :     uri.forget(result);
     141             556 :     return rv;
     142                 : }
     143                 : 
     144                 : NS_IMETHODIMP
     145             401 : nsDataHandler::NewChannel(nsIURI* uri, nsIChannel* *result) {
     146             401 :     NS_ENSURE_ARG_POINTER(uri);
     147             401 :     nsDataChannel* channel = new nsDataChannel(uri);
     148             401 :     if (!channel)
     149               0 :         return NS_ERROR_OUT_OF_MEMORY;
     150             401 :     NS_ADDREF(channel);
     151                 : 
     152             401 :     nsresult rv = channel->Init();
     153             401 :     if (NS_FAILED(rv)) {
     154               0 :         NS_RELEASE(channel);
     155               0 :         return rv;
     156                 :     }
     157                 : 
     158             401 :     *result = channel;
     159             401 :     return NS_OK;
     160                 : }
     161                 : 
     162                 : NS_IMETHODIMP 
     163               0 : nsDataHandler::AllowPort(PRInt32 port, const char *scheme, bool *_retval) {
     164                 :     // don't override anything.  
     165               0 :     *_retval = false;
     166               0 :     return NS_OK;
     167                 : }
     168                 : 
     169                 : nsresult
     170             951 : nsDataHandler::ParseURI(nsCString& spec,
     171                 :                         nsCString& contentType,
     172                 :                         nsCString& contentCharset,
     173                 :                         bool&    isBase64,
     174                 :                         nsCString& dataBuffer,
     175                 :                         nsCString& hashRef) {
     176             951 :     isBase64 = false;
     177                 : 
     178                 :     // move past "data:"
     179             951 :     char *buffer = (char *) PL_strcasestr(spec.BeginWriting(), "data:");
     180             951 :     if (!buffer) {
     181                 :         // malformed uri
     182               0 :         return NS_ERROR_MALFORMED_URI;
     183                 :     }
     184             951 :     buffer += 5;
     185                 : 
     186                 :     // First, find the start of the data
     187             951 :     char *comma = strchr(buffer, ',');
     188             951 :     if (!comma)
     189               0 :         return NS_ERROR_MALFORMED_URI;
     190                 : 
     191             951 :     *comma = '\0';
     192                 : 
     193                 :     // determine if the data is base64 encoded.
     194             951 :     char *base64 = PL_strcasestr(buffer, ";base64");
     195             951 :     if (base64) {
     196             222 :         isBase64 = true;
     197             222 :         *base64 = '\0';
     198                 :     }
     199                 : 
     200             951 :     if (comma == buffer) {
     201                 :         // nothing but data
     202             224 :         contentType.AssignLiteral("text/plain");
     203             224 :         contentCharset.AssignLiteral("US-ASCII");
     204                 :     } else {
     205                 :         // everything else is content type
     206             727 :         char *semiColon = (char *) strchr(buffer, ';');
     207             727 :         if (semiColon)
     208             406 :             *semiColon = '\0';
     209                 :         
     210             727 :         if (semiColon == buffer || base64 == buffer) {
     211                 :             // there is no content type, but there are other parameters
     212               0 :             contentType.AssignLiteral("text/plain");
     213                 :         } else {
     214             727 :             contentType = buffer;
     215             727 :             ToLowerCase(contentType);
     216                 :         }
     217                 : 
     218             727 :         if (semiColon) {
     219             406 :             char *charset = PL_strcasestr(semiColon + 1, "charset=");
     220             406 :             if (charset)
     221             406 :                 contentCharset = charset + sizeof("charset=") - 1;
     222                 : 
     223             406 :             *semiColon = ';';
     224                 :         }
     225                 :     }
     226                 : 
     227             951 :     *comma = ',';
     228             951 :     if (isBase64)
     229             222 :         *base64 = ';';
     230                 : 
     231             951 :     contentType.StripWhitespace();
     232             951 :     contentCharset.StripWhitespace();
     233                 : 
     234                 :     // Split encoded data from terminal "#ref" (if present)
     235             951 :     char *data = comma + 1;
     236             951 :     char *hash = strchr(data, '#');
     237             951 :     if (!hash) {
     238             921 :         dataBuffer.Assign(data);
     239             921 :         hashRef.Truncate();
     240                 :     } else {
     241              30 :         dataBuffer.Assign(data, hash - data);
     242              30 :         hashRef.Assign(hash);
     243                 :     }
     244                 : 
     245             951 :     return NS_OK;
     246                 : }

Generated by: LCOV version 1.7