LCOV - code coverage report
Current view: directory - frmts/wcs - httpdriver.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 58 46 79.3 %
Date: 2011-12-18 Functions: 3 3 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: wcsdataset.cpp 10645 2007-01-18 02:22:39Z warmerdam $
       3                 :  *
       4                 :  * Project:  WCS Client Driver
       5                 :  * Purpose:  Implementation of an HTTP fetching driver.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2007, Frank Warmerdam
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "gdal_pam.h"
      31                 : #include "cpl_string.h"
      32                 : #include "cpl_http.h"
      33                 : #include "cpl_atomic_ops.h"
      34                 : 
      35                 : CPL_CVSID("$Id: wcsdataset.cpp 10645 2007-01-18 02:22:39Z warmerdam $");
      36                 : 
      37                 : 
      38                 : /************************************************************************/
      39                 : /*               HTTPFetchContentDispositionFilename()                 */
      40                 : /************************************************************************/
      41                 : 
      42               2 : static const char* HTTPFetchContentDispositionFilename(char** papszHeaders)
      43                 : {
      44               2 :     char** papszIter = papszHeaders;
      45              19 :     while(papszIter && *papszIter)
      46                 :     {
      47                 :         /* For multipart, we have in raw format, but without end-of-line characters */
      48              15 :         if (strncmp(*papszIter, "Content-Disposition: attachment; filename=", 42) == 0)
      49                 :         {
      50               0 :             return *papszIter + 42;
      51                 :         }
      52                 :         /* For single part, the headers are in KEY=VAL format, but with e-o-l ... */
      53              15 :         else if (strncmp(*papszIter, "Content-Disposition=attachment; filename=", 41) == 0)
      54                 :         {
      55               0 :             char* pszVal = (char*)(*papszIter + 41);
      56               0 :             char* pszEOL = strchr(pszVal, '\r');
      57               0 :             if (pszEOL) *pszEOL = 0;
      58               0 :             pszEOL = strchr(pszVal, '\n');
      59               0 :             if (pszEOL) *pszEOL = 0;
      60               0 :             return pszVal;
      61                 :         }
      62              15 :         papszIter ++;
      63                 :     }
      64               2 :     return NULL;
      65                 : }
      66                 : 
      67                 : /************************************************************************/
      68                 : /*                              HTTPOpen()                              */
      69                 : /************************************************************************/
      70                 : 
      71           10722 : static GDALDataset *HTTPOpen( GDALOpenInfo * poOpenInfo )
      72                 : 
      73                 : {
      74                 :     static volatile int nCounter = 0;
      75                 : 
      76           10722 :     if( poOpenInfo->nHeaderBytes != 0 )
      77             358 :         return NULL;
      78                 : 
      79           10364 :     if( !EQUALN(poOpenInfo->pszFilename,"http:",5)
      80                 :         && !EQUALN(poOpenInfo->pszFilename,"https:",6)
      81                 :         && !EQUALN(poOpenInfo->pszFilename,"ftp:",4) )
      82           10362 :         return NULL;
      83                 : 
      84                 : /* -------------------------------------------------------------------- */
      85                 : /*      Fetch the result.                                               */
      86                 : /* -------------------------------------------------------------------- */
      87               2 :     CPLErrorReset();
      88                 :     
      89               2 :     CPLHTTPResult *psResult = CPLHTTPFetch( poOpenInfo->pszFilename, NULL );
      90                 : 
      91                 : /* -------------------------------------------------------------------- */
      92                 : /*      Try to handle errors.                                           */
      93                 : /* -------------------------------------------------------------------- */
      94               2 :     if( psResult == NULL || psResult->nDataLen == 0 
      95                 :         || CPLGetLastErrorNo() != 0 )
      96                 :     {
      97               0 :         CPLHTTPDestroyResult( psResult );
      98               0 :         return NULL;
      99                 :     }
     100                 : 
     101                 : /* -------------------------------------------------------------------- */
     102                 : /*      Create a memory file from the result.                           */
     103                 : /* -------------------------------------------------------------------- */
     104               2 :     CPLString osResultFilename;
     105                 : 
     106               2 :     int nNewCounter = CPLAtomicInc(&nCounter);
     107                 : 
     108               2 :     const char* pszFilename = HTTPFetchContentDispositionFilename(psResult->papszHeaders);
     109               2 :     if (pszFilename == NULL)
     110                 :     {
     111               2 :         pszFilename = CPLGetFilename(poOpenInfo->pszFilename);
     112                 :         /* If we have special characters, let's default to a fixed name */
     113               2 :         if (strchr(pszFilename, '?') || strchr(pszFilename, '&'))
     114               0 :             pszFilename = "file.dat";
     115                 :     }
     116                 : 
     117                 :     osResultFilename.Printf( "/vsimem/http_%d/%s",
     118               2 :                              nNewCounter, pszFilename );
     119                 : 
     120                 :     VSILFILE *fp = VSIFileFromMemBuffer( osResultFilename,
     121                 :                                      psResult->pabyData, 
     122                 :                                      psResult->nDataLen, 
     123               2 :                                      TRUE );
     124                 : 
     125               2 :     if( fp == NULL )
     126               0 :         return NULL;
     127                 : 
     128               2 :     VSIFCloseL( fp );
     129                 : 
     130                 : /* -------------------------------------------------------------------- */
     131                 : /*      Steal the memory buffer from HTTP result before destroying      */
     132                 : /*      it.                                                             */
     133                 : /* -------------------------------------------------------------------- */
     134               2 :     psResult->pabyData = NULL;
     135               2 :     psResult->nDataLen = psResult->nDataAlloc = 0;
     136                 : 
     137               2 :     CPLHTTPDestroyResult( psResult );
     138                 : 
     139                 : /* -------------------------------------------------------------------- */
     140                 : /*      Try opening this result as a gdaldataset.                       */
     141                 : /* -------------------------------------------------------------------- */
     142                 :     GDALDataset *poDS = (GDALDataset *) 
     143               2 :         GDALOpen( osResultFilename, GA_ReadOnly );
     144                 : 
     145                 : /* -------------------------------------------------------------------- */
     146                 : /*      If opening it in memory didn't work, perhaps we need to         */
     147                 : /*      write to a temp file on disk?                                   */
     148                 : /* -------------------------------------------------------------------- */
     149               2 :     if( poDS == NULL )
     150                 :     {
     151               1 :         CPLString osTempFilename;
     152                 :         
     153               1 :         osTempFilename.Printf( "/tmp/%s", CPLGetFilename(osResultFilename) );
     154               1 :         if( CPLCopyFile( osTempFilename, osResultFilename ) != 0 )
     155                 :         {
     156                 :             CPLError( CE_Failure, CPLE_OpenFailed, 
     157                 :                       "Failed to create temporary file:%s", 
     158               0 :                       osTempFilename.c_str() );
     159                 :         }
     160                 :         else
     161                 :         {
     162                 :             poDS =  (GDALDataset *) 
     163               1 :                 GDALOpen( osTempFilename, GA_ReadOnly );
     164               1 :             VSIUnlink( osTempFilename ); /* this may not work on windows */
     165               1 :         }
     166                 :     }
     167                 : 
     168                 : /* -------------------------------------------------------------------- */
     169                 : /*      Release our hold on the vsi memory file, though if it is        */
     170                 : /*      held open by a dataset it will continue to exist till that      */
     171                 : /*      lets it go.                                                     */
     172                 : /* -------------------------------------------------------------------- */
     173               2 :     VSIUnlink( osResultFilename );
     174                 : 
     175               2 :     return poDS;
     176                 : }
     177                 : 
     178                 : /************************************************************************/
     179                 : /*                         GDALRegister_HTTP()                          */
     180                 : /************************************************************************/
     181                 : 
     182             558 : void GDALRegister_HTTP()
     183                 : 
     184                 : {
     185                 :     GDALDriver  *poDriver;
     186                 : 
     187             558 :     if( GDALGetDriverByName( "HTTP" ) == NULL )
     188                 :     {
     189             537 :         poDriver = new GDALDriver();
     190                 :         
     191             537 :         poDriver->SetDescription( "HTTP" );
     192                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     193             537 :                                    "HTTP Fetching Wrapper" );
     194                 :         
     195             537 :         poDriver->pfnOpen = HTTPOpen;
     196                 : 
     197             537 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     198                 :     }
     199             558 : }

Generated by: LCOV version 1.7