Доступ к сервисам Amazon S3 с помощью клиента C ++ GSOAP - PullRequest
1 голос
/ 01 августа 2011

Я начинаю разрабатывать приложение для доступа к хранилищу Amazon S3 с использованием SOAP API.

Я прочитал документы, в которых говорится, что метод PutObject должен использоваться, если размер файла превышает 1 МБ. Теперь PutObject использует вложение DIME.

Есть ли пример кода или пример или фрагмент кода, который кто-то может показать мне о том, как выполнить вложение DIME с GSOAP для метода PutObject в Amazon S3.

Я хочу использовать GSOAP из-за переносимости и сделать его универсальным. Я не хочу использовать .NET API, предоставляемый Amazon по той же причине. Я хочу в GSOAP особенно, поскольку я работал в GSOAP ранее.

Спасибо

1011 * Дэвид *

1 Ответ

0 голосов
/ 16 августа 2011

Я собрал что-то, что загружает файлы размером более 1 МБ, используя PutObject, это также должно работать для меньших файлов.Я делюсь этим с другими, кто может найти это полезным.

Также см. Мой предыдущий пост об использовании GSOAP для доступа к S3 AMAZON AWS ​​S3 с использованием GSOAP C C ++ Ссылка также содержит метод для генерацииsignature.

Вот код для PutObject.

Он использует последний GSOAP от sourceforge.

После 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);
}

Надеюсь, это поможет.

Спасибо, Дэвид

...