【问题标题】:Access Amazon S3 services with C++ GSOAP client使用 C++ GSOAP 客户端访问 Amazon S3 服务
【发布时间】:2011-08-01 12:48:24
【问题描述】:

我开始开发一个使用 SOAP API 访问 Amazon S3 存储的应用程序。

我已阅读文档,说明如果文件大小大于 1 MB,则必须使用方法 PutObject。 现在 PutObject 使用 DIME 附件。

是否有人可以向我展示如何使用 GSOAP 为 Amazon S3 的 PutObject 方法执行 DIME 附加的示例代码或示例或代码片段。

由于可移植性和通用性,我想使用 GSOAP。出于同样的原因,我不想使用 Amazon 提供的 .NET API。我特别想要 GSOAP,因为我之前曾在 GSOAP 工作过。

谢谢,

大卫

【问题讨论】:

    标签: c++ amazon-s3 amazon gsoap


    【解决方案1】:

    我整理了一些使用 PutObject 上传大于 1MB 的文件的东西,它也应该适用于较小的文件。 我分享给其他可能觉得有用的人。

    另请参阅我之前关于使用 GSOAP 访问 S3 AMAZON AWS S3 using GSOAP C C++ 的帖子 该链接还包含生成签名的方法。

    这是 PutObject 的代码。

    它使用来自 sourceforge 的最新 GSOAP。

    wsdl2h生成header和soapcpp2生成gsoap客户端代码之后将是访问服务PutObject的代码......

    要求:OpenSSL GSOAP 使用编译器预处理指令 WITH_OPENSSL 构建。包括库文件 libeay32 和 ssleay32。从上面的链接中获取生成签名的方法。

    void PutObject(char *filename)
    {
    
        AmazonS3SoapBindingProxy amazonS3Interface;   
        struct soap*                         soapPtr;
       soapPtr = dynamic_cast<struct soap*>(&amazonS3Interface);  
       soap_init2(soapPtr, SOAP_IO_DEFAULT|SOAP_IO_KEEPALIVE, SOAP_IO_DEFAULT|SOAP_IO_KEEPALIVE);
    
        soap_ssl_client_context(&amazonS3Interface,
         SOAP_SSL_NO_AUTHENTICATION,  /* for encryption w/o authentication */
        /* SOAP_SSL_DEFAULT | SOAP_SSL_SKIP_HOST_CHECK, */  /* if we don't want the host name checks since these will change from machine to machine */
        /*SOAP_SSL_DEFAULT,*/   /* use SOAP_SSL_DEFAULT in production code */
        NULL,               /* keyfile (cert+key): required only when client must authenticate to server (see SSL docs to create this file) */
        NULL,               /* password to read the keyfile */
        NULL,       /* optional cacert file to store trusted certificates, use cacerts.pem for all public certificates issued by common CAs */
        NULL,               /* optional capath to directory with trusted certificates */
        NULL                /* if randfile!=NULL: use a file with random data to seed randomness */
      );
    
    
        //use this if you are behind a proxy to connect to internet
        amazonS3Interface.proxy_host="proxyservername"; //proxyservername
        amazonS3Interface.proxy_port=4050; //proxy port
        amazonS3Interface.proxy_userid="username"; //proxy authentication
        amazonS3Interface.proxy_passwd="password";
        amazonS3Interface.proxy_http_version="1.1"; //http ver
    
        amazonS3Interface.dime_id_format ="uuid:09233523-345b-4351-b623-5dsf35sgs5d6-%x"; 
       // Set callback functions   
       soapPtr->fdimereadopen   = dime_read_open;  
       soapPtr->fdimereadclose  = dime_read_close;   
       soapPtr->fdimeread       =dime_read;      
    
        _ns1__PutObject preq;
        _ns1__PutObjectResponse presp;
        ns1__PutObjectResult res;
    
        FILE *fp=fopen(filename,"rb");
        fseek(fp, 0L, SEEK_END); 
        size_t sz = ftell(fp);
    
        fseek(fp, 0L, SEEK_SET); 
    
        preq.Bucket=std::string("FGTSDrive");//bucket name to put file in
        preq.AWSAccessKeyId=new std::string("ACCESSKEY");//access key here
        char *sig=aws_signature("SECRETKEY","AmazonS3","PutObject",xml_datetime(),NULL);//correct secretkey here
    
        preq.Signature=new std::string(sig);
        preq.Timestamp=new time_t(time(NULL));
        preq.Key=std::string(filename);//name of the key ie the filename
    
       int result(0);   
       preq.ContentLength=sz; //length of the file
    
       ns1__MetadataEntry med;
       med.Name=std::string("Content-Type");
       med.Value=std::string("application/zip");//change the type depending on the file extenstion
       med.soap=&amazonS3Interface;
    
       preq.Metadata.push_back(&med);
    
       soap_set_dime(soapPtr);   
    
       result =soap_set_dime_attachment(soapPtr,  (char*)fp, sz,"application/zip", NULL, 0,filename);//change the content type depending on the file extenstion
    
      if (result != SOAP_OK) {     }
      result = amazonS3Interface.PutObject(&preq, &presp);
       if (result != SOAP_OK) {   }
    
    amazonS3Interface.soap_stream_fault(std::cout);
    }
    
    
    static void *dime_read_open(struct soap *soap, void *handle, const char *id, const char *type, const char *options)
    { // we should return NULL without setting soap->error if we don't want to use the streaming callback for this DIME attachment. The handle contains the non-NULL __ptr field value which should have been set in the application.
      // return value of this function will be passed on to the fdimeread and fdimereadclose callbacks. The return value will not affect the __ptr field.
        std::cout <<"dime_read_open"<<std::endl;
      return handle;
    }
    
    static void dime_read_close(struct soap *soap, void *handle)
    { 
        std::cout <<"dime_read_close"<<std::endl;
        fclose((FILE*)handle);
    }
    
    static size_t dime_read(struct soap *soap, void *handle, char *buf, size_t len)
    { 
        std::cout <<"dime_read_read"<<std::endl;
        return fread(buf, 1, len, (FILE*)handle);
    }
    

    希望对你有帮助。

    谢谢, 大卫

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-02
      • 2013-02-13
      • 1970-01-01
      • 1970-01-01
      • 2011-08-31
      相关资源
      最近更新 更多