gpt4 book ai didi

c++ - 如何使用适用于 C 和 C++ 的 GSOAP 访问 Amazon AWS S3?

转载 作者:可可西里 更新时间:2023-11-01 15:25:21 25 4
gpt4 key购买 nike

我到处搜索这个,但找不到一个像样的代码。如何访问 Amazon AWS S3服务使用GSOAP

最佳答案

以下代码来自OP。本来,这个帖子包含问题和答案,我正在把它变成一个问答的格式。

签名必须是这样的格式

base64encode((HMAC-SHA1(ActionName+"AmazonS3"+XMLTimestamp)))

HMAC、SHA1 和 B64 实用程序可在 openssl .

SOAP 请求的格式由 wsdl .

REST 接口(interface)不同。

wsdl2h 生成 header 和 soapcpp2 之后生成 GSOAP客户端代码以下将是访问服务的代码:

要求:OpenSSL , GSOAP .

使用编译器预处理器指令 WITH_OPENSSL 构建。连结于库 libeay32ssleay32

#include "AmazonS3SoapBinding.nsmap" //generated from soapcpp2
#include "soapAmazonS3SoapBindingProxy.h" //generated from soapcpp2
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include <openssl/evp.h>

/* convert to base64 */
std::string base64_encodestring(char* text, int len) {
EVP_ENCODE_CTX ectx;
int size = len*2;
size = size > 64 ? size : 64;
unsigned char* out = (unsigned char*)malloc( size );
int outlen = 0;
int tlen = 0;

EVP_EncodeInit(&ectx);
EVP_EncodeUpdate(&ectx,
out,
&outlen,
(const unsigned char*)text,
len
);
tlen += outlen;
EVP_EncodeFinal( &ectx, out+tlen, &outlen );
tlen += outlen;

std::string str((char*)out, tlen );
free( out );
return str;
}

/* return the utc date+time in xml format */
const char* xml_datetime() {

/*"YYYY-mm-ddTHH:MM:SS.000Z\"*/
const int MAX=25;
static char output[MAX+1];
time_t now = time(NULL);

strftime( output, MAX+1, "%Y-%m-%dT%H:%M:%S.000Z", gmtime( &now ) );

std::cout <<output<<std::endl;
return output;
}

/* first argument is the signing key */
/* all subsequent argumets are concatenated */
/* must end list with NULL */
char* aws_signature(char* key, ...) {
unsigned int i, len;
char *data, **list = &key;

static char hmac[EVP_MAX_MD_SIZE];

for (i = 1, len = 0; *(list+i) != NULL; ++i) {
len += strlen( *(list+i) );
}

data = (char*)malloc(sizeof(char) * (len+1));

if (data) {
for ( i = 1, len = 0 ; *(list+i) != NULL ; ++i ) {
strncpy( data+len, *(list+i), strlen(*(list+i)) );
len += strlen(*(list+i));
}
data[len]='\0';

std::cout<<data<<std::endl;
HMAC( EVP_sha1(),
key, strlen(key),
(unsigned char*)data, strlen(data),
(unsigned char*) hmac, &len
);
free(data);
}

std::string b64data=base64_encodestring(hmac, len);

strcpy(hmac,b64data.c_str());

return hmac;
};

int main(void) {
AmazonS3SoapBindingProxy client;

soap_ssl_client_context(&client,
/* for encryption w/o authentication */
SOAP_SSL_NO_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 server.....
client.proxy_host="proxyserver"; // proxy hostname
client.proxy_port=4250;
client.proxy_userid="username"; // user pass if proxy
client.proxy_passwd="password"; // requires authentication
client.proxy_http_version="1.1"; // http version
*/
_ns1__ListAllMyBuckets buk_req;
_ns1__ListAllMyBucketsResponse buk_resp;
ns1__ListAllMyBucketsResult buk_res;
buk_res.soap=&client;

buk_req.AWSAccessKeyId=new std::string("ACCESSKEY");
buk_req.soap=&client;

/* ListAllMyBuckets is the method I want to call here.
* change it for other S3 services that you wish to call.*/

char *sig=aws_signature(
"SECRETKEY",
"AmazonS3",
"ListAllMyBuckets",
xml_datetime(),
NULL
);


buk_req.Signature=new std::string(sig);
buk_req.Timestamp=new time_t(time(NULL));

buk_resp.soap=&client;
buk_resp.ListAllMyBucketsResponse=&buk_res;

client.ListAllMyBuckets(&buk_req,&buk_resp);

client.soap_stream_fault(std::cout);

std::vector<ns1__ListAllMyBucketsEntry * >::iterator itr;

for(itr=buk_resp.ListAllMyBucketsResponse->Buckets->Bucket.begin();
itr!=buk_resp.ListAllMyBucketsResponse->Buckets->Bucket.end();
itr++
) {
std::cout<<(*itr)->Name<<std::endl;
}

}

关于c++ - 如何使用适用于 C 和 C++ 的 GSOAP 访问 Amazon AWS S3?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7010703/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com