29 #ifndef CPL_VSIL_CURL_CLASS_H_INCLUDED 30 #define CPL_VSIL_CURL_CLASS_H_INCLUDED 37 #include "cpl_vsil_curl_priv.h" 38 #include "cpl_mem_cache.h" 40 #include <curl/curl.h> 49 #if LIBCURL_VERSION_NUM >= 0x071201 50 #define HAVE_CURLINFO_REDIRECT_URL 53 void VSICurlStreamingClearCache(
void );
55 struct curl_slist* VSICurlSetOptions(CURL* hCurlHandle,
const char* pszURL,
56 const char *
const* papszOptions);
57 struct curl_slist* VSICurlMergeHeaders(
struct curl_slist* poDest,
58 struct curl_slist* poSrcToDestroy );
72 ExistStatus eExists = EXIST_UNKNOWN;
75 time_t nExpireTimestampLocal = 0;
77 bool bHasComputedFileSize =
false;
78 bool bIsDirectory =
false;
79 bool bS3LikeRedirect =
false;
85 bool bGotFileList =
false;
100 bool bFoundContentRange;
102 bool bDownloadHeaderOnly;
103 bool bDetectRangeDownloadingError;
107 VSICurlReadCbkFunc pfnReadCbk;
108 void *pReadCbkUserData;
118 class VSICurlFilesystemHandler :
public VSIFilesystemHandler
122 struct FilenameOffsetPair
124 std::string filename_;
127 FilenameOffsetPair(
const std::string& filename,
129 filename_(filename), offset_(offset) {}
131 bool operator==(
const FilenameOffsetPair& other)
const 133 return filename_ == other.filename_ &&
134 offset_ == other.offset_;
137 struct FilenameOffsetPairHasher
139 std::size_t operator()(
const FilenameOffsetPair& k)
const 141 return std::hash<std::string>()(k.filename_) ^
142 std::hash<vsi_l_offset>()(k.offset_);
146 using RegionCacheType =
147 lru11::Cache<FilenameOffsetPair, std::shared_ptr<std::string>,
151 typename std::list<lru11::KeyValuePair<FilenameOffsetPair,
152 std::shared_ptr<std::string>>>::iterator,
153 FilenameOffsetPairHasher>>;
155 RegionCacheType oRegionCache;
157 lru11::Cache<std::string, FileProp> oCacheFileProp;
159 int nCachedFilesInDirList = 0;
160 lru11::Cache<std::string, CachedDirList> oCacheDirList;
162 char** ParseHTMLFileList(
const char* pszFilename,
165 bool* pbGotFileList);
168 CPLMutex *hMutex =
nullptr;
170 virtual VSICurlHandle* CreateFileHandle(
const char* pszFilename);
171 virtual char** GetFileList(
const char *pszFilename,
173 bool* pbGotFileList);
175 void RegisterEmptyDir(
const CPLString& osDirname );
177 bool AnalyseS3FileList(
const CPLString& osBaseURL,
181 bool bIgnoreGlacierStorageClass,
182 bool& bIsTruncated );
184 void AnalyseSwiftFileList(
const CPLString& osBaseURL,
188 int nMaxFilesThisQuery,
193 static const char* GetOptionsStatic();
195 static bool IsAllowedFilename(
const char* pszFilename );
198 VSICurlFilesystemHandler();
199 ~VSICurlFilesystemHandler()
override;
202 const char *pszAccess,
203 bool bSetError )
override;
205 int Stat(
const char *pszFilename,
VSIStatBufL *pStatBuf,
206 int nFlags )
override;
207 int Unlink(
const char *pszFilename )
override;
208 int Rename(
const char *oldpath,
const char *newpath )
override;
209 int Mkdir(
const char *pszDirname,
long nMode )
override;
210 int Rmdir(
const char *pszDirname )
override;
211 char **ReadDir(
const char *pszDirname )
override 212 {
return ReadDirEx(pszDirname, 0); }
213 char **ReadDirEx(
const char *pszDirname,
int nMaxFiles )
override;
215 int HasOptimizedReadMultiRange(
const char* )
216 override {
return true; }
218 const char* GetActualURL(
const char* pszFilename)
override;
220 const char* GetOptions()
override;
222 char **ReadDirInternal(
const char *pszDirname,
int nMaxFiles,
223 bool* pbGotFileList );
224 void InvalidateDirContent(
const char *pszDirname );
226 virtual CPLString GetFSPrefix() {
return "/vsicurl/"; }
227 virtual bool AllowCachedDataFor(
const char* pszFilename);
229 std::shared_ptr<std::string> GetRegion(
const char* pszURL,
232 void AddRegion(
const char* pszURL,
237 bool GetCachedFileProp(
const char* pszURL,
238 FileProp& oFileProp );
239 void SetCachedFileProp(
const char* pszURL,
240 const FileProp& oFileProp );
241 void InvalidateCachedData(
const char* pszURL );
243 CURLM *GetCurlMultiHandleFor(
const CPLString& osURL );
245 virtual void ClearCache();
246 virtual void PartialClearCache(
const char* pszFilename);
249 bool GetCachedDirList(
const char* pszURL,
250 CachedDirList& oCachedDirList );
251 void SetCachedDirList(
const char* pszURL,
252 const CachedDirList& oCachedDirList );
253 bool ExistsInCacheDirList(
const CPLString& osDirname,
bool *pbIsDir );
267 VSICurlFilesystemHandler* poFS =
nullptr;
269 bool m_bCached =
true;
271 FileProp oFileProp{};
274 char* m_pszURL =
nullptr;
276 char **m_papszHTTPOptions =
nullptr;
279 int nBlocksToDownload = 1;
281 bool bStopOnInterruptUntilUninstall =
false;
282 bool bInterrupted =
false;
283 VSICurlReadCbkFunc pfnReadCbk =
nullptr;
284 void *pReadCbkUserData =
nullptr;
287 double m_dfRetryDelay = 0.0;
289 void DownloadRegionPostProcess(
const vsi_l_offset startOffset,
300 virtual bool DownloadRegion(
vsi_l_offset startOffset,
int nBlocks);
302 bool m_bUseHead =
false;
304 int ReadMultiRangeSingleGet(
int nRanges,
void ** ppData,
306 const size_t* panSizes );
307 CPLString GetRedirectURLIfValid(
bool& bHasExpired);
310 virtual struct curl_slist* GetCurlHeaders(
const CPLString& ,
311 const struct curl_slist* )
313 virtual bool AllowAutomaticRedirection() {
return true; }
314 virtual bool CanRestartOnError(
const char*,
const char*,
bool ) {
return false; }
315 virtual bool UseLimitRangeGetInsteadOfHead() {
return false; }
316 virtual bool IsDirectoryFromExists(
const char* ,
int ) {
return false; }
317 virtual void ProcessGetFileSizeResult(
const char* ) {}
318 void SetURL(
const char* pszURL);
322 VSICurlHandle( VSICurlFilesystemHandler* poFS,
323 const char* pszFilename,
324 const char* pszURLIn =
nullptr );
325 ~VSICurlHandle()
override;
329 size_t Read(
void *pBuffer,
size_t nSize,
size_t nMemb )
override;
330 int ReadMultiRange(
int nRanges,
void ** ppData,
332 const size_t* panSizes )
override;
333 size_t Write(
const void *pBuffer,
size_t nSize,
size_t nMemb )
override;
335 int Flush()
override;
336 int Close()
override;
338 bool IsKnownFileSize()
const {
return oFileProp.bHasComputedFileSize; }
339 vsi_l_offset GetFileSize() {
return GetFileSize(
false); }
341 bool Exists(
bool bSetError );
342 bool IsDirectory()
const {
return oFileProp.bIsDirectory; }
343 time_t GetMTime()
const {
return oFileProp.mTime; }
345 int InstallReadCbk( VSICurlReadCbkFunc pfnReadCbk,
347 int bStopOnInterruptUntilUninstall );
348 int UninstallReadCbk();
350 const char *GetURL()
const {
return m_pszURL; }
357 class IVSIS3LikeFSHandler:
public VSICurlFilesystemHandler
362 char** GetFileList(
const char *pszFilename,
364 bool* pbGotFileList )
override;
366 virtual IVSIS3LikeHandleHelper* CreateHandleHelper(
367 const char* pszURI,
bool bAllowNoObject) = 0;
369 IVSIS3LikeFSHandler() =
default;
372 int Unlink(
const char *pszFilename )
override;
373 int Mkdir(
const char *pszDirname,
long nMode )
override;
374 int Rmdir(
const char *pszDirname )
override;
375 int Stat(
const char *pszFilename,
VSIStatBufL *pStatBuf,
376 int nFlags )
override;
378 virtual int DeleteObject(
const char *pszFilename );
380 virtual const char* GetDebugKey()
const = 0;
382 virtual void UpdateMapFromHandle(IVSIS3LikeHandleHelper*) {}
383 virtual void UpdateHandleFromMap( IVSIS3LikeHandleHelper * ) {}
385 bool Sync(
const char* pszSource,
const char* pszTarget,
386 const char*
const * papszOptions,
387 GDALProgressFunc pProgressFunc,
389 char*** ppapszOutputs )
override;
391 VSIDIR* OpenDir(
const char *pszPath,
int nRecurseDepth,
392 const char*
const *papszOptions)
override;
399 class IVSIS3LikeHandle:
public VSICurlHandle
404 bool UseLimitRangeGetInsteadOfHead()
override {
return true; }
405 bool IsDirectoryFromExists(
const char* pszVerb,
406 int response_code )
override 409 return response_code == 416 &&
EQUAL(pszVerb,
"GET") &&
412 void ProcessGetFileSizeResult(
const char* pszContent )
override 414 oFileProp.bIsDirectory = strstr(pszContent,
"ListBucketResult") !=
nullptr;
418 IVSIS3LikeHandle( VSICurlFilesystemHandler* poFSIn,
419 const char* pszFilename,
420 const char* pszURLIn =
nullptr ) :
421 VSICurlHandle(poFSIn, pszFilename, pszURLIn) {}
422 ~IVSIS3LikeHandle()
override {}
433 IVSIS3LikeFSHandler *m_poFS =
nullptr;
435 IVSIS3LikeHandleHelper *m_poS3HandleHelper =
nullptr;
436 bool m_bUseChunked =
false;
439 int m_nBufferOff = 0;
440 int m_nBufferSize = 0;
441 int m_nBufferOffReadCallback = 0;
442 bool m_bClosed =
false;
443 GByte *m_pabyBuffer =
nullptr;
445 int m_nPartNumber = 0;
446 std::vector<CPLString> m_aosEtags{};
448 int m_nOffsetInXML = 0;
449 bool m_bError =
false;
451 CURLM *m_hCurlMulti =
nullptr;
452 CURL *m_hCurl =
nullptr;
453 const void *m_pBuffer =
nullptr;
455 size_t m_nChunkedBufferOff = 0;
456 size_t m_nChunkedBufferSize = 0;
458 static size_t ReadCallBackBuffer(
char *buffer,
size_t size,
459 size_t nitems,
void *instream );
460 bool InitiateMultipartUpload();
462 static size_t ReadCallBackXML(
char *buffer,
size_t size,
463 size_t nitems,
void *instream );
464 bool CompleteMultipart();
465 bool AbortMultipart();
466 bool DoSinglePartPUT();
468 static size_t ReadCallBackBufferChunked(
char *buffer,
size_t size,
469 size_t nitems,
void *instream );
470 size_t WriteChunked(
const void *pBuffer,
471 size_t nSize,
size_t nMemb );
472 int FinishChunkedTransfer();
474 void InvalidateParentDirectory();
477 VSIS3WriteHandle( IVSIS3LikeFSHandler* poFS,
478 const char* pszFilename,
479 IVSIS3LikeHandleHelper* poS3HandleHelper,
481 ~VSIS3WriteHandle()
override;
485 size_t Read(
void *pBuffer,
size_t nSize,
size_t nMemb )
override;
486 size_t Write(
const void *pBuffer,
size_t nSize,
size_t nMemb )
override;
488 int Close()
override;
490 bool IsOK() {
return m_bUseChunked || m_pabyBuffer !=
nullptr; }
503 VSICurlFilesystemHandler* m_poFS =
nullptr;
508 int m_nBufferOff = 0;
509 int m_nBufferSize = 0;
510 int m_nBufferOffReadCallback = 0;
511 bool m_bClosed =
false;
512 GByte *m_pabyBuffer =
nullptr;
513 bool m_bError =
false;
515 static size_t ReadCallBackBuffer(
char *buffer,
size_t size,
516 size_t nitems,
void *instream );
517 virtual bool Send(
bool bIsLastBlock) = 0;
520 VSIAppendWriteHandle( VSICurlFilesystemHandler* poFS,
521 const char* pszFSPrefix,
522 const char* pszFilename,
524 virtual ~VSIAppendWriteHandle();
528 size_t Read(
void *pBuffer,
size_t nSize,
size_t nMemb )
override;
529 size_t Write(
const void *pBuffer,
size_t nSize,
size_t nMemb )
override;
531 int Close()
override;
533 bool IsOK() {
return m_pabyBuffer !=
nullptr; }
536 int VSICURLGetDownloadChunkSize();
538 void VSICURLInitWriteFuncStruct( WriteFuncStruct *psStruct,
540 VSICurlReadCbkFunc pfnReadCbk,
541 void *pReadCbkUserData );
542 size_t VSICurlHandleWriteFunc(
void *buffer,
size_t count,
543 size_t nmemb,
void *req );
544 void MultiPerform(CURLM* hCurlMultiHandle,
545 CURL* hEasyHandle =
nullptr);
546 void VSICURLResetHeaderAndWriterFunctions(CURL* hCurlHandle);
554 #endif // CPL_VSIL_CURL_CLASS_H_INCLUDED Definition: cpl_conv.h:367
Core portability definitions for CPL.
FILE VSILFILE
Opaque type for a FILE that implements the VSIVirtualHandle API.
Definition: cpl_vsi.h:156
unsigned char GByte
Unsigned byte type.
Definition: cpl_port.h:215
Virtual file handle.
Definition: cpl_vsi_virtual.h:56
Convenient string class based on std::string.
Definition: cpl_string.h:329
Various convenience functions for working with strings and string lists.
struct VSI_STAT64_T VSIStatBufL
Type for VSIStatL()
Definition: cpl_vsi.h:192
#define EQUAL(a, b)
Alias for strcasecmp() == 0.
Definition: cpl_port.h:561
String list class designed around our use of C "char**" string lists.
Definition: cpl_string.h:438
GUIntBig vsi_l_offset
Type for a file offset.
Definition: cpl_vsi.h:140
long long GIntBig
Large signed integer type (generally 64-bit integer type).
Definition: cpl_port.h:248
struct VSIDIR VSIDIR
Opaque type for a directory iterator.
Definition: cpl_vsi.h:307
#define CPL_DISALLOW_COPY_ASSIGN(ClassName)
Helper to remove the copy and assignment constructors so that the compiler will not generate the defa...
Definition: cpl_port.h:989
#define VSI_L_OFFSET_MAX
Maximum value for a file offset.
Definition: cpl_vsi.h:142