简体   繁体   中英

Access Amazon S3 services with C++ GSOAP client

I am starting to develop an app to access the Amazon S3 storage using the SOAP API.

I have read the documents that says the the method PutObject must be used if the file size is greater than 1 MB. Now PutObject uses DIME attachment.

Is there a sample code or example or a fragment of code that someone can show me on how to do DIME attachement with GSOAP for the PutObject method of Amazon S3.

I want to use GSOAP because of portability and to make it generic. I do not want to use the .NET API provided by Amazon for the same reason. I want in GSOAP particularly as I have worked in GSOAP earlier.

Thanks,

david

I put together something that uploads files larger than 1MB using PutObject, it should also work for smaller files. I share it for others who might find it useful.

Also see my previous post on using GSOAP to access S3 AMAZON AWS S3 using GSOAP C C++ The link also contains the method to generate the signature.

Here is the code for PutObject.

It uses the latest GSOAP from sourceforge.

After wsdl2h to generate the header and soapcpp2 to generate the gsoap client code the following will be the code to access the service PutObject......

Requirements : OpenSSL GSOAP Build with the compiler preprocessor directive WITH_OPENSSL. Include the library files libeay32 and ssleay32. Take the methods to generate signature from the link above.

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);
}

Hope it helps.

Thanks, david

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM