2011-08-01 75 views
1

我开始开发应用程序以使用SOAP API访问Amazon S3存储。使用C++ GSOAP客户端访问Amazon S3服务

我读过的文件说如果文件大小大于1 MB,必须使用PutObject方法。 现在,PutObject使用DIME附件。

是否有示例代码或示例或者代码片段,可以让我知道如何使用GSOAP为Amazon S3的PutObject方法执行DIME附件。

我想使用GSOAP,因为它具有可移植性并使其具有通用性。我不想使用亚马逊提供的.NET API,原因相同。特别是因为我之前曾在GSOAP中工作过,所以希望参加GSOAP。

感谢,

大卫

回答

0

我放在一起的东西,上传的文件比使用PutObject,也应该对小文件的工作1MB的。 我分享给其他可能会觉得有用的人。

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

这里是PutObject的代码。

它使用来自sourceforge的最新GSOAP。

wsdl2h生成标题和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); 
} 

希望它有帮助。

谢谢, david