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 :
34 : CPL_CVSID("$Id: wcsdataset.cpp 10645 2007-01-18 02:22:39Z warmerdam $");
35 :
36 : /************************************************************************/
37 : /* HTTPOpen() */
38 : /************************************************************************/
39 :
40 8459 : static GDALDataset *HTTPOpen( GDALOpenInfo * poOpenInfo )
41 :
42 : {
43 8459 : if( poOpenInfo->nHeaderBytes != 0 )
44 188 : return NULL;
45 :
46 8271 : if( !EQUALN(poOpenInfo->pszFilename,"http:",5)
47 : && !EQUALN(poOpenInfo->pszFilename,"https:",6)
48 : && !EQUALN(poOpenInfo->pszFilename,"ftp:",4) )
49 8270 : return NULL;
50 :
51 : /* -------------------------------------------------------------------- */
52 : /* Fetch the result. */
53 : /* -------------------------------------------------------------------- */
54 1 : CPLErrorReset();
55 :
56 1 : CPLHTTPResult *psResult = CPLHTTPFetch( poOpenInfo->pszFilename, NULL );
57 :
58 : /* -------------------------------------------------------------------- */
59 : /* Try to handle errors. */
60 : /* -------------------------------------------------------------------- */
61 1 : if( psResult == NULL || psResult->nDataLen == 0
62 : || CPLGetLastErrorNo() != 0 )
63 : {
64 0 : CPLHTTPDestroyResult( psResult );
65 0 : return NULL;
66 : }
67 :
68 : /* -------------------------------------------------------------------- */
69 : /* Create a memory file from the result. */
70 : /* -------------------------------------------------------------------- */
71 : // Eventually we should be looking at mime info and stuff to figure
72 : // out an optimal filename, but for now we just use a fixed one.
73 :
74 1 : CPLString osResultFilename;
75 :
76 : osResultFilename.Printf( "/vsimem/http/%p.dat",
77 1 : psResult->pabyData );
78 :
79 : FILE *fp = VSIFileFromMemBuffer( osResultFilename,
80 : psResult->pabyData,
81 : psResult->nDataLen,
82 1 : TRUE );
83 :
84 1 : if( fp == NULL )
85 0 : return NULL;
86 :
87 1 : VSIFCloseL( fp );
88 :
89 : /* -------------------------------------------------------------------- */
90 : /* Steal the memory buffer from HTTP result before destroying */
91 : /* it. */
92 : /* -------------------------------------------------------------------- */
93 1 : psResult->pabyData = NULL;
94 1 : psResult->nDataLen = psResult->nDataAlloc = 0;
95 :
96 1 : CPLHTTPDestroyResult( psResult );
97 :
98 : /* -------------------------------------------------------------------- */
99 : /* Try opening this result as a gdaldataset. */
100 : /* -------------------------------------------------------------------- */
101 : GDALDataset *poDS = (GDALDataset *)
102 1 : GDALOpen( osResultFilename, GA_ReadOnly );
103 :
104 : /* -------------------------------------------------------------------- */
105 : /* If opening it in memory didn't work, perhaps we need to */
106 : /* write to a temp file on disk? */
107 : /* -------------------------------------------------------------------- */
108 1 : if( poDS == NULL )
109 : {
110 0 : CPLString osTempFilename;
111 :
112 0 : osTempFilename.Printf( "/tmp/%s", CPLGetFilename(osResultFilename) );
113 0 : if( CPLCopyFile( osTempFilename, osResultFilename ) != 0 )
114 : {
115 : CPLError( CE_Failure, CPLE_OpenFailed,
116 : "Failed to create temporary file:%s",
117 0 : osTempFilename.c_str() );
118 : }
119 : else
120 : {
121 : poDS = (GDALDataset *)
122 0 : GDALOpen( osTempFilename, GA_ReadOnly );
123 0 : VSIUnlink( osTempFilename ); /* this may not work on windows */
124 0 : }
125 : }
126 :
127 : /* -------------------------------------------------------------------- */
128 : /* Release our hold on the vsi memory file, though if it is */
129 : /* held open by a dataset it will continue to exist till that */
130 : /* lets it go. */
131 : /* -------------------------------------------------------------------- */
132 1 : VSIUnlink( osResultFilename );
133 :
134 1 : return poDS;
135 : }
136 :
137 : /************************************************************************/
138 : /* GDALRegister_HTTP() */
139 : /************************************************************************/
140 :
141 338 : void GDALRegister_HTTP()
142 :
143 : {
144 : GDALDriver *poDriver;
145 :
146 338 : if( GDALGetDriverByName( "HTTP" ) == NULL )
147 : {
148 336 : poDriver = new GDALDriver();
149 :
150 336 : poDriver->SetDescription( "HTTP" );
151 : poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
152 336 : "HTTP Fetching Wrapper" );
153 :
154 336 : poDriver->pfnOpen = HTTPOpen;
155 :
156 336 : GetGDALDriverManager()->RegisterDriver( poDriver );
157 : }
158 338 : }
|