2011-08-01 106 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