LCOV - code coverage report
Current view: top level - port - cpl_vsil_oss.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 70 75 93.3 %
Date: 2024-04-29 01:40:10 Functions: 18 19 94.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  CPL - Common Portability Library
       4             :  * Purpose:  Implement VSI large file api for Alibaba Object Storage Service
       5             :  * Author:   Even Rouault, even.rouault at spatialys.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2017-2018, Even Rouault <even.rouault at spatialys.com>
       9             :  *
      10             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the "Software"),
      12             :  * to deal in the Software without restriction, including without limitation
      13             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14             :  * and/or sell copies of the Software, and to permit persons to whom the
      15             :  * Software is furnished to do so, subject to the following conditions:
      16             :  *
      17             :  * The above copyright notice and this permission notice shall be included
      18             :  * in all copies or substantial portions of the Software.
      19             :  *
      20             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26             :  * DEALINGS IN THE SOFTWARE.
      27             :  ****************************************************************************/
      28             : 
      29             : #include "cpl_port.h"
      30             : #include "cpl_http.h"
      31             : #include "cpl_minixml.h"
      32             : #include "cpl_vsil_curl_priv.h"
      33             : #include "cpl_vsil_curl_class.h"
      34             : 
      35             : #include <errno.h>
      36             : 
      37             : #include <algorithm>
      38             : #include <set>
      39             : #include <map>
      40             : #include <memory>
      41             : 
      42             : #include "cpl_alibaba_oss.h"
      43             : 
      44             : #ifndef HAVE_CURL
      45             : 
      46             : void VSIInstallOSSFileHandler(void)
      47             : {
      48             :     // Not supported
      49             : }
      50             : 
      51             : #else
      52             : 
      53             : //! @cond Doxygen_Suppress
      54             : #ifndef DOXYGEN_SKIP
      55             : 
      56             : #define ENABLE_DEBUG 0
      57             : 
      58             : namespace cpl
      59             : {
      60             : 
      61             : /************************************************************************/
      62             : /*                         VSIOSSFSHandler                              */
      63             : /************************************************************************/
      64             : 
      65             : class VSIOSSFSHandler final : public IVSIS3LikeFSHandler
      66             : {
      67             :     CPL_DISALLOW_COPY_ASSIGN(VSIOSSFSHandler)
      68             : 
      69             :   protected:
      70             :     VSICurlHandle *CreateFileHandle(const char *pszFilename) override;
      71             :     std::string GetURLFromFilename(const std::string &osFilename) override;
      72             : 
      73         110 :     const char *GetDebugKey() const override
      74             :     {
      75         110 :         return "OSS";
      76             :     }
      77             : 
      78             :     IVSIS3LikeHandleHelper *CreateHandleHelper(const char *pszURI,
      79             :                                                bool bAllowNoObject) override;
      80             : 
      81         786 :     std::string GetFSPrefix() const override
      82             :     {
      83         786 :         return "/vsioss/";
      84             :     }
      85             : 
      86             :     void ClearCache() override;
      87             : 
      88             :     VSIVirtualHandleUniquePtr
      89             :     CreateWriteHandle(const char *pszFilename,
      90             :                       CSLConstList papszOptions) override;
      91             : 
      92             :   public:
      93        1228 :     VSIOSSFSHandler() = default;
      94             :     ~VSIOSSFSHandler() override;
      95             : 
      96             :     const char *GetOptions() override;
      97             : 
      98             :     char *GetSignedURL(const char *pszFilename,
      99             :                        CSLConstList papszOptions) override;
     100             : 
     101             :     std::string
     102           0 :     GetStreamingFilename(const std::string &osFilename) const override
     103             :     {
     104           0 :         return osFilename;
     105             :     }
     106             : };
     107             : 
     108             : /************************************************************************/
     109             : /*                            VSIOSSHandle                              */
     110             : /************************************************************************/
     111             : 
     112             : class VSIOSSHandle final : public IVSIS3LikeHandle
     113             : {
     114             :     CPL_DISALLOW_COPY_ASSIGN(VSIOSSHandle)
     115             : 
     116             :     VSIOSSHandleHelper *m_poHandleHelper = nullptr;
     117             : 
     118             :   protected:
     119             :     struct curl_slist *
     120             :     GetCurlHeaders(const std::string &osVerb,
     121             :                    const struct curl_slist *psExistingHeaders) override;
     122             :     bool CanRestartOnError(const char *, const char *, bool) override;
     123             : 
     124             :   public:
     125             :     VSIOSSHandle(VSIOSSFSHandler *poFS, const char *pszFilename,
     126             :                  VSIOSSHandleHelper *poHandleHelper);
     127             :     ~VSIOSSHandle() override;
     128             : };
     129             : 
     130             : /************************************************************************/
     131             : /*                       ~VSIOSSFSHandler()                             */
     132             : /************************************************************************/
     133             : 
     134        1704 : VSIOSSFSHandler::~VSIOSSFSHandler()
     135             : {
     136         852 :     VSIOSSFSHandler::ClearCache();
     137        1704 : }
     138             : 
     139             : /************************************************************************/
     140             : /*                          CreateWriteHandle()                         */
     141             : /************************************************************************/
     142             : 
     143             : VSIVirtualHandleUniquePtr
     144          16 : VSIOSSFSHandler::CreateWriteHandle(const char *pszFilename,
     145             :                                    CSLConstList papszOptions)
     146             : {
     147             :     auto poHandleHelper =
     148          16 :         CreateHandleHelper(pszFilename + GetFSPrefix().size(), false);
     149          16 :     if (poHandleHelper == nullptr)
     150           1 :         return nullptr;
     151             :     auto poHandle = std::make_unique<VSIS3WriteHandle>(
     152          30 :         this, pszFilename, poHandleHelper, false, papszOptions);
     153          15 :     if (!poHandle->IsOK())
     154             :     {
     155           0 :         return nullptr;
     156             :     }
     157          15 :     return VSIVirtualHandleUniquePtr(poHandle.release());
     158             : }
     159             : 
     160             : /************************************************************************/
     161             : /*                            ClearCache()                              */
     162             : /************************************************************************/
     163             : 
     164        1098 : void VSIOSSFSHandler::ClearCache()
     165             : {
     166        1098 :     VSICurlFilesystemHandlerBase::ClearCache();
     167             : 
     168        1098 :     VSIOSSUpdateParams::ClearCache();
     169        1098 : }
     170             : 
     171             : /************************************************************************/
     172             : /*                           GetOptions()                               */
     173             : /************************************************************************/
     174             : 
     175           2 : const char *VSIOSSFSHandler::GetOptions()
     176             : {
     177             :     static std::string osOptions(
     178           2 :         std::string("<Options>") +
     179             :         "  <Option name='OSS_SECRET_ACCESS_KEY' type='string' "
     180             :         "description='Secret access key. To use with OSS_ACCESS_KEY_ID'/>"
     181             :         "  <Option name='OSS_ACCESS_KEY_ID' type='string' "
     182             :         "description='Access key id'/>"
     183             :         "  <Option name='OSS_ENDPOINT' type='string' "
     184             :         "description='Default endpoint' default='oss-us-east-1.aliyuncs.com'/>"
     185             :         "  <Option name='VSIOSS_CHUNK_SIZE' type='int' "
     186             :         "description='Size in MB for chunks of files that are uploaded. The"
     187             :         "default value of 50 MB allows for files up to 500 GB each' "
     188           3 :         "default='50' min='1' max='1000'/>" +
     189           3 :         VSICurlFilesystemHandlerBase::GetOptionsStatic() + "</Options>");
     190           2 :     return osOptions.c_str();
     191             : }
     192             : 
     193             : /************************************************************************/
     194             : /*                           GetSignedURL()                             */
     195             : /************************************************************************/
     196             : 
     197           2 : char *VSIOSSFSHandler::GetSignedURL(const char *pszFilename,
     198             :                                     CSLConstList papszOptions)
     199             : {
     200           2 :     if (!STARTS_WITH_CI(pszFilename, GetFSPrefix().c_str()))
     201           0 :         return nullptr;
     202             : 
     203           4 :     VSIOSSHandleHelper *poHandleHelper = VSIOSSHandleHelper::BuildFromURI(
     204           6 :         pszFilename + GetFSPrefix().size(), GetFSPrefix().c_str(), false,
     205             :         papszOptions);
     206           2 :     if (poHandleHelper == nullptr)
     207             :     {
     208           1 :         return nullptr;
     209             :     }
     210             : 
     211           2 :     std::string osRet(poHandleHelper->GetSignedURL(papszOptions));
     212             : 
     213           1 :     delete poHandleHelper;
     214           1 :     return CPLStrdup(osRet.c_str());
     215             : }
     216             : 
     217             : /************************************************************************/
     218             : /*                          CreateFileHandle()                          */
     219             : /************************************************************************/
     220             : 
     221          45 : VSICurlHandle *VSIOSSFSHandler::CreateFileHandle(const char *pszFilename)
     222             : {
     223          90 :     VSIOSSHandleHelper *poHandleHelper = VSIOSSHandleHelper::BuildFromURI(
     224         135 :         pszFilename + GetFSPrefix().size(), GetFSPrefix().c_str(), false);
     225          45 :     if (poHandleHelper)
     226             :     {
     227          43 :         return new VSIOSSHandle(this, pszFilename, poHandleHelper);
     228             :     }
     229           2 :     return nullptr;
     230             : }
     231             : 
     232             : /************************************************************************/
     233             : /*                          GetURLFromFilename()                         */
     234             : /************************************************************************/
     235             : 
     236          17 : std::string VSIOSSFSHandler::GetURLFromFilename(const std::string &osFilename)
     237             : {
     238             :     std::string osFilenameWithoutPrefix =
     239          34 :         osFilename.substr(GetFSPrefix().size());
     240             : 
     241          17 :     VSIOSSHandleHelper *poHandleHelper = VSIOSSHandleHelper::BuildFromURI(
     242          34 :         osFilenameWithoutPrefix.c_str(), GetFSPrefix().c_str(), true);
     243          17 :     if (poHandleHelper == nullptr)
     244             :     {
     245           0 :         return "";
     246             :     }
     247             : 
     248          34 :     std::string osBaseURL(poHandleHelper->GetURL());
     249          17 :     if (!osBaseURL.empty() && osBaseURL.back() == '/')
     250           7 :         osBaseURL.resize(osBaseURL.size() - 1);
     251          17 :     delete poHandleHelper;
     252             : 
     253          17 :     return osBaseURL;
     254             : }
     255             : 
     256             : /************************************************************************/
     257             : /*                          CreateHandleHelper()                        */
     258             : /************************************************************************/
     259             : 
     260          28 : IVSIS3LikeHandleHelper *VSIOSSFSHandler::CreateHandleHelper(const char *pszURI,
     261             :                                                             bool bAllowNoObject)
     262             : {
     263          56 :     return VSIOSSHandleHelper::BuildFromURI(pszURI, GetFSPrefix().c_str(),
     264          56 :                                             bAllowNoObject);
     265             : }
     266             : 
     267             : /************************************************************************/
     268             : /*                            VSIOSSHandle()                            */
     269             : /************************************************************************/
     270             : 
     271          43 : VSIOSSHandle::VSIOSSHandle(VSIOSSFSHandler *poFSIn, const char *pszFilename,
     272          43 :                            VSIOSSHandleHelper *poHandleHelper)
     273          43 :     : IVSIS3LikeHandle(poFSIn, pszFilename, poHandleHelper->GetURL().c_str()),
     274          43 :       m_poHandleHelper(poHandleHelper)
     275             : {
     276          43 : }
     277             : 
     278             : /************************************************************************/
     279             : /*                            ~VSIOSSHandle()                           */
     280             : /************************************************************************/
     281             : 
     282          86 : VSIOSSHandle::~VSIOSSHandle()
     283             : {
     284          43 :     delete m_poHandleHelper;
     285          86 : }
     286             : 
     287             : /************************************************************************/
     288             : /*                           GetCurlHeaders()                           */
     289             : /************************************************************************/
     290             : 
     291             : struct curl_slist *
     292          43 : VSIOSSHandle::GetCurlHeaders(const std::string &osVerb,
     293             :                              const struct curl_slist *psExistingHeaders)
     294             : {
     295          43 :     return m_poHandleHelper->GetCurlHeaders(osVerb, psExistingHeaders);
     296             : }
     297             : 
     298             : /************************************************************************/
     299             : /*                          CanRestartOnError()                         */
     300             : /************************************************************************/
     301             : 
     302           2 : bool VSIOSSHandle::CanRestartOnError(const char *pszErrorMsg,
     303             :                                      const char *pszHeaders, bool bSetError)
     304             : {
     305           2 :     if (m_poHandleHelper->CanRestartOnError(pszErrorMsg, pszHeaders, bSetError))
     306             :     {
     307           1 :         SetURL(m_poHandleHelper->GetURL().c_str());
     308           1 :         return true;
     309             :     }
     310           1 :     return false;
     311             : }
     312             : 
     313             : } /* end of namespace cpl */
     314             : 
     315             : #endif  // DOXYGEN_SKIP
     316             : //! @endcond
     317             : 
     318             : /************************************************************************/
     319             : /*                      VSIInstallOSSFileHandler()                      */
     320             : /************************************************************************/
     321             : 
     322             : /*!
     323             :  \brief Install /vsioss/ Alibaba Cloud Object Storage Service (OSS) file
     324             :  system handler (requires libcurl)
     325             : 
     326             :  \verbatim embed:rst
     327             :  See :ref:`/vsioss/ documentation <vsioss>`
     328             :  \endverbatim
     329             : 
     330             :  @since GDAL 2.3
     331             :  */
     332        1228 : void VSIInstallOSSFileHandler(void)
     333             : {
     334        1228 :     VSIFileManager::InstallHandler("/vsioss/", new cpl::VSIOSSFSHandler);
     335        1228 : }
     336             : 
     337             : #endif /* HAVE_CURL */

Generated by: LCOV version 1.14