This commit is contained in:
Jean-Marie Verdun
2020-06-16 21:55:11 -04:00
committed by Yorik van Havre
parent b393cf67df
commit 575df24435

View File

@@ -75,7 +75,7 @@ Py::Object Cloud::Module::sCloudURL(const Py::Tuple& args)
}
Py::Object Cloud::Module::sCloudTokenAuth(const Py::Tuple& args)
{
{
char *TokenAuth;
if (!PyArg_ParseTuple(args.ptr(), "et","utf-8", &TokenAuth)) // convert args: Python->C
return Py::None();
@@ -213,7 +213,7 @@ void Cloud::CloudWriter::checkText(DOMText* text) {
delete[] buffer;
if ( print )
{
strcpy(errorCode,content);
strcpy(errorCode,content);
}
print=0;
XMLString::release(&content);
@@ -229,43 +229,43 @@ void Cloud::CloudWriter::createBucket()
struct data_buffer curl_buffer;
char path[1024];
char path[1024];
sprintf(path, "/%s/", this->Bucket);
std::string strURL(this->URL);
eraseSubStr(strURL,"http://");
eraseSubStr(strURL,"https://");
if ( this->ProtocolVersion == "2" )
RequestData = Cloud::ComputeDigestAmzS3v2("PUT", "application/xml", path, this->TokenSecret, NULL, 0);
else
RequestDatav4 = Cloud::ComputeDigestAmzS3v4("PUT", strURL.c_str(), "application/xml", path, this->TokenSecret, NULL, 0, NULL, this->Region);
if ( this->ProtocolVersion == "2" )
RequestData = Cloud::ComputeDigestAmzS3v2("PUT", "application/xml", path, this->TokenSecret, NULL, 0);
else
RequestDatav4 = Cloud::ComputeDigestAmzS3v4("PUT", strURL.c_str(), "application/xml", path, this->TokenSecret, NULL, 0, NULL, this->Region);
// Let's build the Header and call to curl
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
#ifdef ALLOW_SELF_SIGNED_CERTIFICATE
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
#endif
if ( curl )
{
struct curl_slist *chunk = NULL;
char URL[256];
char URL[256];
// Let's build our own header
std::string strURL(this->URL);
eraseSubStr(strURL,"http://");
eraseSubStr(strURL,"https://");
if ( this->ProtocolVersion == "2" )
{
chunk = Cloud::BuildHeaderAmzS3v2( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestData);
delete RequestData;
}
else
{
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestDatav4);
delete RequestDatav4;
}
if ( this->ProtocolVersion == "2" )
{
chunk = Cloud::BuildHeaderAmzS3v2( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestData);
delete RequestData;
}
else
{
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestDatav4);
delete RequestDatav4;
}
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
@@ -317,9 +317,9 @@ struct Cloud::AmzDatav4 *Cloud::ComputeDigestAmzS3v4(char *operation, const char
struct AmzDatav4 *returnData;
returnData = new Cloud::AmzDatav4;
struct tm *tm;
char *canonical_request;
char *canonicalRequestHash;
char *stringToSign;
char *canonical_request;
char *canonicalRequestHash;
char *stringToSign;
strcpy(returnData->ContentType, data_type);
@@ -340,138 +340,137 @@ struct Cloud::AmzDatav4 *Cloud::ComputeDigestAmzS3v4(char *operation, const char
returnData->MD5=NULL;
// We must evaluate the canonical request
canonical_request=(char *) malloc(4096*(sizeof(char*)));
strcpy(canonical_request,operation);
strcat(canonical_request,"\n");
strcat(canonical_request,target);
strcat(canonical_request,"\n");
if ( parameters == NULL )
strcat(canonical_request,"\n");
else
{
strcat(canonical_request,parameters);
canonical_request=(char *) malloc(4096*(sizeof(char*)));
strcpy(canonical_request,operation);
strcat(canonical_request,"\n");
strcat(canonical_request,target);
strcat(canonical_request,"\n");
if ( parameters == NULL )
strcat(canonical_request,"\n");
}
strcat(canonical_request,"host:");
strcat(canonical_request,server);
strcat(canonical_request, "\n");
strcat(canonical_request, "x-amz-date:");
strcat(canonical_request, returnData->dateFormattedS);
strcat(canonical_request, "\n\n");
strcat(canonical_request, "host;x-amz-date\n");
// We must add there the file SHA256 Hash
returnData->SHA256Sum=NULL;
if ( strcmp(operation,"PUT") == 0 )
{
if ( ptr != NULL )
else
{
strcat(canonical_request,parameters);
strcat(canonical_request,"\n");
}
strcat(canonical_request,"host:");
strcat(canonical_request,server);
strcat(canonical_request, "\n");
strcat(canonical_request, "x-amz-date:");
strcat(canonical_request, returnData->dateFormattedS);
strcat(canonical_request, "\n\n");
strcat(canonical_request, "host;x-amz-date\n");
// We must add there the file SHA256 Hash
returnData->SHA256Sum=NULL;
if ( strcmp(operation,"PUT") == 0 )
{
if ( ptr != NULL )
{
returnData->SHA256Sum=Cloud::SHA256Sum(ptr,size);
strcat(canonical_request, returnData->SHA256Sum);
}
else
strcat(canonical_request,"UNSIGNED-PAYLOAD");
}
else
{
strcat(canonical_request,"UNSIGNED-PAYLOAD");
}
canonicalRequestHash = Cloud::SHA256Sum(canonical_request, strlen(canonical_request));
// returnData->digest = string(digest);
returnData->SHA256Sum=Cloud::SHA256Sum(ptr,size);
strcat(canonical_request, returnData->SHA256Sum);
}
else
strcat(canonical_request,"UNSIGNED-PAYLOAD");
}
else
{
strcat(canonical_request,"UNSIGNED-PAYLOAD");
}
canonicalRequestHash = Cloud::SHA256Sum(canonical_request, strlen(canonical_request));
// returnData->digest = string(digest);
// We need now to sign a string which contain the digest
// The format is as follow
// ${authType}
// ${dateValueL}
// ${dateValueS}/${Region}/${service}/aws4_request
// ${canonicalRequestHash}"
// We need now to sign a string which contain the digest
// The format is as follow
// ${authType}
// ${dateValueL}
// ${dateValueS}/${Region}/${service}/aws4_request
// ${canonicalRequestHash}"
stringToSign = (char *)malloc(4096*sizeof(char));
strcat(stringToSign, "AWS4-HMAC-SHA256");
strcat(stringToSign,"\n");
strcat(stringToSign,returnData->dateFormattedS);
stringToSign = (char *)malloc(4096*sizeof(char));
strcat(stringToSign, "AWS4-HMAC-SHA256");
strcat(stringToSign,"\n");
strcat(stringToSign,returnData->dateFormattedD);
strcat(stringToSign,"/us/s3/aws4_request");
strcat(stringToSign,returnData->dateFormattedS);
strcat(stringToSign,"\n");
strcat(stringToSign,canonicalRequestHash);
strcat(stringToSign,"\0");
strcat(stringToSign,returnData->dateFormattedD);
strcat(stringToSign,"/us/s3/aws4_request");
strcat(stringToSign,"\n");
strcat(stringToSign,canonicalRequestHash);
strcat(stringToSign,"\0");
// We must now compute the signature
// Everything starts with the secret key and an SHA256 HMAC encryption
char kSecret[256];
unsigned char *kDate, *kRegion, *kService, *kSigned, *kSigning;
// We must now compute the signature
// Everything starts with the secret key and an SHA256 HMAC encryption
char kSecret[256];
unsigned char *kDate, *kRegion, *kService, *kSigned, *kSigning;
strcpy(kSecret,"AWS4");
strcat(kSecret,Secret);
strcpy(kSecret,"AWS4");
strcat(kSecret,Secret);
unsigned int HMACLength;
std::string temporary;
std::string temporary;
kDate = HMAC(EVP_sha256(),kSecret,strlen(kSecret),
(const unsigned char *)returnData->dateFormattedD,strlen(returnData->dateFormattedD),NULL,&HMACLength);
kDate = HMAC(EVP_sha256(),kSecret,strlen(kSecret),
(const unsigned char *)returnData->dateFormattedD,strlen(returnData->dateFormattedD),NULL,&HMACLength);
temporary = getHexValue(kDate,HMACLength);
temporary = getHexValue(kDate,HMACLength);
temporary = getHexValue(kDate,HMACLength);
// We can now compute the remaining parts
kRegion = HMAC(EVP_sha256(),kDate,HMACLength,
// We can now compute the remaining parts
kRegion = HMAC(EVP_sha256(),kDate,HMACLength,
(const unsigned char *)Region.c_str(),strlen(Region.c_str()),NULL,&HMACLength);
temporary = getHexValue(kRegion,HMACLength);
temporary = getHexValue(kRegion,HMACLength);
kService = HMAC(EVP_sha256(),kRegion,HMACLength,
kService = HMAC(EVP_sha256(),kRegion,HMACLength,
(const unsigned char *)"s3",strlen("s3"),NULL,&HMACLength);
temporary = getHexValue(kService,HMACLength);
kSigning = HMAC(EVP_sha256(),kService,HMACLength,
kSigning = HMAC(EVP_sha256(),kService,HMACLength,
(const unsigned char *)"aws4_request",strlen("aws4_request"),NULL,&HMACLength);
temporary = getHexValue(kService,HMACLength);
kSigned = HMAC(EVP_sha256(),kSigning,HMACLength,
kSigned = HMAC(EVP_sha256(),kSigning,HMACLength,
(const unsigned char *)stringToSign,strlen(stringToSign),NULL,&HMACLength);
temporary = getHexValue(kSigned,HMACLength);
returnData->digest=string(temporary);
returnData->Region = Region;
free(canonical_request);
return(returnData);
returnData->digest=string(temporary);
returnData->Region = Region;
free(canonical_request);
return(returnData);
}
std::string Cloud::getHexValue(unsigned char *input, unsigned int HMACLength)
{
char *Hex;
unsigned char *ptr = input;
unsigned char *ptr = input;
std::string resultReadable;
Hex = (char *)malloc(HMACLength*2*sizeof(char)+1);
for ( unsigned int i = 0 ; i < HMACLength ; i++ ) {
sprintf(Hex,"%02x", *ptr);
ptr++;
ptr++;
Hex[2]='\0';
resultReadable+= Hex;
}
return resultReadable;
return resultReadable;
}
struct Cloud::AmzData *Cloud::ComputeDigestAmzS3v2(char *operation, char *data_type, const char *target, const char *Secret, const char *ptr, long size)
{
struct AmzData *returnData;
struct AmzData *returnData;
//struct timeval tv;
struct tm *tm;
char date_formatted[256];
char StringToSign[1024];
unsigned char *digest;
unsigned int HMACLength;
char StringToSign[1024];
unsigned char *digest;
unsigned int HMACLength;
// Amazon S3 and Swift require the timezone to be define to GMT.
// As to simplify the conversion this is performed through the TZ
// environment variable and a call to localtime as to convert output of gettimeofday
returnData = new Cloud::AmzData;
strcpy(returnData->ContentType, data_type);
returnData = new Cloud::AmzData;
strcpy(returnData->ContentType, data_type);
#if defined(FC_OS_WIN32)
_putenv("TZ=GMT");
time_t rawtime;
@@ -485,54 +484,53 @@ struct Cloud::AmzData *Cloud::ComputeDigestAmzS3v2(char *operation, char *data_t
tm = localtime(&tv.tv_sec);
#endif
strftime(date_formatted,256,"%a, %d %b %Y %T %z", tm);
returnData->MD5=NULL;
if ( strcmp(operation,"PUT") == 0 )
{
if ( ptr != NULL )
{
returnData->MD5=Cloud::MD5Sum(ptr,size);
sprintf(StringToSign,"%s\n%s\n%s\n%s\n%s", operation, returnData->MD5, data_type, date_formatted, target);
}
else
sprintf(StringToSign,"%s\n\n%s\n%s\n%s", operation, data_type, date_formatted, target);
}
else
sprintf(StringToSign,"%s\n\n%s\n%s\n%s", operation, data_type, date_formatted, target);
// We have to use HMAC encoding and SHA1
returnData->MD5=NULL;
if ( strcmp(operation,"PUT") == 0 )
{
if ( ptr != NULL )
{
returnData->MD5=Cloud::MD5Sum(ptr,size);
sprintf(StringToSign,"%s\n%s\n%s\n%s\n%s", operation, returnData->MD5, data_type, date_formatted, target);
}
else
sprintf(StringToSign,"%s\n\n%s\n%s\n%s", operation, data_type, date_formatted, target);
}
else
sprintf(StringToSign,"%s\n\n%s\n%s\n%s", operation, data_type, date_formatted, target);
// We have to use HMAC encoding and SHA1
digest=HMAC(EVP_sha1(),Secret,strlen(Secret),
(const unsigned char *)&StringToSign,strlen(StringToSign),NULL,&HMACLength);
returnData->digest = Base::base64_encode(digest,HMACLength);
strcpy(returnData->dateFormatted,date_formatted);
return returnData;
returnData->digest = Base::base64_encode(digest,HMACLength);
strcpy(returnData->dateFormatted,date_formatted);
return returnData;
}
char *Cloud::SHA256Sum(const char *ptr, long size)
{
char *output;
std::string local;
std::string resultReadable;
std::string resultReadable;
unsigned char result[SHA256_DIGEST_LENGTH];
char *Hex;
output=(char *)malloc(2*SHA256_DIGEST_LENGTH*sizeof(char)+1);
Hex = (char *)malloc(2*sizeof(char)+1);
Hex = (char *)malloc(2*sizeof(char)+1);
SHA256((unsigned char*) ptr, size, result);
strcpy(output,getHexValue(result, SHA256_DIGEST_LENGTH).c_str());
strcpy(output,getHexValue(result, SHA256_DIGEST_LENGTH).c_str());
return(output);
}
char *Cloud::MD5Sum(const char *ptr, long size)
{
char *output;
std::string local;
unsigned char result[MD5_DIGEST_LENGTH];
output=(char *)malloc(2*MD5_DIGEST_LENGTH*sizeof(char)+1);
char *output;
std::string local;
unsigned char result[MD5_DIGEST_LENGTH];
output=(char *)malloc(2*MD5_DIGEST_LENGTH*sizeof(char)+1);
MD5((unsigned char*) ptr, size, result);
local= Base::base64_encode(result,MD5_DIGEST_LENGTH);
strcpy(output,local.c_str());
return(output);
local= Base::base64_encode(result,MD5_DIGEST_LENGTH);
strcpy(output,local.c_str());
return(output);
}
struct curl_slist *Cloud::BuildHeaderAmzS3v4(const char *URL, const char *TCPPort, const char *PublicKey, struct Cloud::AmzDatav4 *Data)
@@ -565,17 +563,17 @@ struct curl_slist *Cloud::BuildHeaderAmzS3v4(const char *URL, const char *TCPPor
free((void *)Data->MD5);
}
if ( Data->SHA256Sum != NULL )
{
sprintf(header_data,"x-amz-content-sha256: %s", Data->SHA256Sum);
if ( Data->SHA256Sum != NULL )
{
sprintf(header_data,"x-amz-content-sha256: %s", Data->SHA256Sum);
chunk = curl_slist_append(chunk, header_data);
// We don't need it anymore we can free it
free((void *)Data->SHA256Sum);
}
else
{
chunk = curl_slist_append(chunk, "x-amz-content-sha256: UNSIGNED-PAYLOAD");
}
}
else
{
chunk = curl_slist_append(chunk, "x-amz-content-sha256: UNSIGNED-PAYLOAD");
}
// build the Auth entry
sprintf(header_data,"Authorization: AWS4-HMAC-SHA256 Credential=%s/%s/%s/%s/aws4_request, SignedHeaders=%s, Signature=%s", PublicKey, Data->dateFormattedD,"us","s3","host;x-amz-date",
@@ -588,40 +586,38 @@ struct curl_slist *Cloud::BuildHeaderAmzS3v4(const char *URL, const char *TCPPor
struct curl_slist *Cloud::BuildHeaderAmzS3v2(const char *URL, const char *TCPPort, const char *PublicKey, struct Cloud::AmzData *Data)
{
char header_data[1024];
struct curl_slist *chunk = NULL;
struct curl_slist *chunk = NULL;
// Build the Host: entry
// Build the Host: entry
sprintf(header_data,"Host: %s:%s", URL, TCPPort);
sprintf(header_data,"Host: %s:%s", URL, TCPPort);
chunk = curl_slist_append(chunk, header_data);
// Build the Date entry
// Build the Date entry
sprintf(header_data,"Date: %s", Data->dateFormatted);
chunk = curl_slist_append(chunk, header_data);
// Build the Content-Type entry
sprintf(header_data,"Date: %s", Data->dateFormatted);
chunk = curl_slist_append(chunk, header_data);
// Build the Content-Type entry
sprintf(header_data,"Content-Type:%s", Data->ContentType);
chunk = curl_slist_append(chunk, header_data);
sprintf(header_data,"Content-Type:%s", Data->ContentType);
chunk = curl_slist_append(chunk, header_data);
// If ptr is not null we must compute the MD5-Sum as to validate later the ETag
// and add the MD5-Content: entry to the header
if ( Data->MD5 != NULL )
{
sprintf(header_data,"Content-MD5: %s", Data->MD5);
chunk = curl_slist_append(chunk, header_data);
// We don't need it anymore we can free it
free((void *)Data->MD5);
}
// If ptr is not null we must compute the MD5-Sum as to validate later the ETag
// and add the MD5-Content: entry to the header
if ( Data->MD5 != NULL )
{
sprintf(header_data,"Content-MD5: %s", Data->MD5);
chunk = curl_slist_append(chunk, header_data);
// We don't need it anymore we can free it
free((void *)Data->MD5);
}
// build the Auth entry
// build the Auth entry
sprintf(header_data,"Authorization: AWS %s:%s", PublicKey,
sprintf(header_data,"Authorization: AWS %s:%s", PublicKey,
Data->digest.c_str());
chunk = curl_slist_append(chunk, header_data);
return chunk;
return chunk;
}
Cloud::CloudWriter::CloudWriter(const char* URL, const char* TokenAuth, const char* TokenSecret, const char* TCPPort, const char* Bucket, std::string ProtocolVersion, std::string Region)
@@ -638,52 +634,52 @@ Cloud::CloudWriter::CloudWriter(const char* URL, const char* TokenAuth, const ch
this->TokenSecret=TokenSecret;
this->TCPPort=TCPPort;
this->Bucket=Bucket;
if ( !ProtocolVersion.empty() )
this->ProtocolVersion=ProtocolVersion;
else
this->ProtocolVersion="2";
this->Region=Region;
if ( !ProtocolVersion.empty() )
this->ProtocolVersion=ProtocolVersion;
else
this->ProtocolVersion="2";
this->Region=Region;
this->FileName="";
char path[1024];
sprintf(path,"/%s/", this->Bucket);
std::string strURL(this->URL);
char path[1024];
sprintf(path,"/%s/", this->Bucket);
std::string strURL(this->URL);
eraseSubStr(strURL,"http://");
eraseSubStr(strURL,"https://");
if ( this->ProtocolVersion == "2" )
RequestData = Cloud::ComputeDigestAmzS3v2("GET", "application/xml", path, this->TokenSecret, NULL, 0);
else
RequestDatav4 = Cloud::ComputeDigestAmzS3v4("GET", strURL.c_str(), "application/xml", path, this->TokenSecret, NULL, 0, NULL, this->Region);
if ( this->ProtocolVersion == "2" )
RequestData = Cloud::ComputeDigestAmzS3v2("GET", "application/xml", path, this->TokenSecret, NULL, 0);
else
RequestDatav4 = Cloud::ComputeDigestAmzS3v4("GET", strURL.c_str(), "application/xml", path, this->TokenSecret, NULL, 0, NULL, this->Region);
// Let's build the Header and call to curl
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
#ifdef ALLOW_SELF_SIGNED_CERTIFICATE
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
#endif
if ( curl )
{
// Let's build our own header
struct curl_slist *chunk = NULL;
char URL[256];
struct curl_slist *chunk = NULL;
char URL[256];
std::string strURL(this->URL);
eraseSubStr(strURL,"http://");
eraseSubStr(strURL,"https://");
if ( this->ProtocolVersion == "2")
{
chunk = Cloud::BuildHeaderAmzS3v2( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestData);
delete RequestData;
}
else
{
if ( this->ProtocolVersion == "2")
{
chunk = Cloud::BuildHeaderAmzS3v2( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestData);
delete RequestData;
}
else
{
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestDatav4);
delete RequestDatav4;
}
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
// Lets build the URL for our Curl call
// Lets build the URL for our Curl call
sprintf(URL,"%s:%s/%s/", this->URL,this->TCPPort,
sprintf(URL,"%s:%s/%s/", this->URL,this->TCPPort,
this->Bucket);
curl_easy_setopt(curl, CURLOPT_URL, URL);
@@ -695,8 +691,8 @@ Cloud::CloudWriter::CloudWriter(const char* URL, const char* TokenAuth, const ch
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
curl_easy_cleanup(curl);
createBucket();
// Lets dump temporarily for debug purposes of s3v4 implementation
createBucket();
// Lets dump temporarily for debug purposes of s3v4 implementation
std::stringstream input(s);
try { XMLPlatformUtils::Initialize(); }
@@ -717,16 +713,15 @@ Cloud::CloudWriter::CloudWriter(const char* URL, const char* TokenAuth, const ch
parser->parse(myxml_buf);
auto* dom=parser->getDocument();
// Is there an Error entry into the document ?
// if yes, then we must create the Bucket
// Is there an Error entry into the document ?
// if yes, then we must create the Bucket
checkXML(dom);
if ( strcmp(errorCode,"NoSuchBucket") == 0 )
{
// we must create the Bucket using a PUT request
createBucket();
}
}
if ( strcmp(errorCode,"NoSuchBucket") == 0 )
{
// we must create the Bucket using a PUT request
createBucket();
}
}
}
@@ -755,11 +750,11 @@ void Cloud::CloudReader::checkElement(DOMElement* element) {
file=1;
if ( strcmp(name, "NextContinuationToken") == 0 )
{
continuation=1;
continuation=1;
}
if ( strcmp(name, "IsTruncated") == 0 )
{
truncated=1;
truncated=1;
}
XMLString::release(&name);
@@ -781,14 +776,14 @@ void Cloud::CloudReader::checkText(DOMText* text) {
}
file=0;
if ( continuation == 1 ) {
strcpy(Cloud::CloudReader::NextFileName, content);
strcpy(Cloud::CloudReader::NextFileName, content);
continuation = 0;
}
if ( truncated == 1 ) {
if ( strncmp(content, "true", 4) != 0 )
truncated = 0;
else
truncated = 2;
if ( strncmp(content, "true", 4) != 0 )
truncated = 0;
else
truncated = 2;
}
XMLString::release(&content);
}
@@ -831,9 +826,9 @@ Cloud::CloudReader::CloudReader(const char* URL, const char* TokenAuth, const ch
struct Cloud::AmzDatav4 *RequestDatav4;
CURL *curl;
CURLcode res;
bool GetBucketContentList=true;
struct curl_slist *chunk = NULL;
char parameters[1024];
bool GetBucketContentList=true;
struct curl_slist *chunk = NULL;
char parameters[1024];
this->URL=URL;
@@ -841,108 +836,107 @@ Cloud::CloudReader::CloudReader(const char* URL, const char* TokenAuth, const ch
this->TokenSecret=TokenSecret;
this->TCPPort=TCPPort;
this->Bucket=Bucket;
if ( !ProtocolVersion.empty() )
this->ProtocolVersion=ProtocolVersion;
else
this->ProtocolVersion="2";
this->Region=Region;
if ( !ProtocolVersion.empty() )
this->ProtocolVersion=ProtocolVersion;
else
this->ProtocolVersion="2";
this->Region=Region;
char path[1024];
char path[1024];
sprintf(path,"/%s/", this->Bucket);
Cloud::CloudReader::NextFileName = ( char* ) malloc(sizeof(char)*1024);
for ( int i = 0 ; i < 1024 ; i++ )
NextFileName[i]='\0';
Cloud::CloudReader::NextFileName = ( char* ) malloc(sizeof(char)*1024);
for ( int i = 0 ; i < 1024 ; i++ )
NextFileName[i]='\0';
// Let's build the Header and call to curl
curl_global_init(CURL_GLOBAL_ALL);
while ( GetBucketContentList )
{
std::string s;
curl = curl_easy_init();
while ( GetBucketContentList )
{
std::string s;
curl = curl_easy_init();
#ifdef ALLOW_SELF_SIGNED_CERTIFICATE
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
#endif
if ( curl )
{
// Let's build our own header
char URL[256];
std::string strURL(this->URL);
eraseSubStr(strURL,"http://");
eraseSubStr(strURL,"https://");
if ( strlen(NextFileName) == 0 )
{
sprintf(parameters,"list-type=2");
}
else
{
sprintf(parameters,"list-type=2&continuation-token=%s", NextFileName);
}
sprintf(URL,"%s:%s/%s/?%s", this->URL,this->TCPPort,
this->Bucket, parameters);
curl_easy_setopt(curl, CURLOPT_URL, URL);
if ( curl )
{
// Let's build our own header
char URL[256];
std::string strURL(this->URL);
eraseSubStr(strURL,"http://");
eraseSubStr(strURL,"https://");
if ( strlen(NextFileName) == 0 )
{
sprintf(parameters,"list-type=2");
}
else
{
sprintf(parameters,"list-type=2&continuation-token=%s", NextFileName);
}
sprintf(URL,"%s:%s/%s/?%s", this->URL,this->TCPPort,
this->Bucket, parameters);
curl_easy_setopt(curl, CURLOPT_URL, URL);
if ( this->ProtocolVersion == "2" )
{
RequestData = Cloud::ComputeDigestAmzS3v2("GET", "application/xml", path, this->TokenSecret, NULL, 0);
RequestData = Cloud::ComputeDigestAmzS3v2("GET", "application/xml", path, this->TokenSecret, NULL, 0);
chunk = Cloud::BuildHeaderAmzS3v2(strURL.c_str(), this->TCPPort, this->TokenAuth, RequestData);
delete RequestData;
}
else
{
RequestDatav4 = Cloud::ComputeDigestAmzS3v4("GET", strURL.c_str(),"application/xml", path, this->TokenSecret, NULL, 0, (char *)&parameters[0], this->Region);
RequestDatav4 = Cloud::ComputeDigestAmzS3v4("GET", strURL.c_str(),"application/xml", path, this->TokenSecret, NULL, 0, (char *)&parameters[0], this->Region);
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestDatav4);
delete RequestDatav4;
}
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWrite_CallbackFunc_StdString);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
// curl read a file not a memory buffer (it shall be able to do it)
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWrite_CallbackFunc_StdString);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
// curl read a file not a memory buffer (it shall be able to do it)
res = curl_easy_perform(curl);
res = curl_easy_perform(curl);
for ( int i = 0 ; i < 1024 ; i++ )
NextFileName[i]='\0';
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
curl_easy_cleanup(curl);
for ( int i = 0 ; i < 1024 ; i++ )
NextFileName[i]='\0';
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
curl_easy_cleanup(curl);
std::stringstream input(s);
std::stringstream input(s);
try { XMLPlatformUtils::Initialize(); }
catch (const XMLException& toCatch) {
char* message = XMLString::transcode(toCatch.getMessage());
cout << "Error during initialization! :\n"
<< message << "\n";
XMLString::release(&message);
return ;
}
try { XMLPlatformUtils::Initialize(); }
catch (const XMLException& toCatch) {
char* message = XMLString::transcode(toCatch.getMessage());
cout << "Error during initialization! :\n"
<< message << "\n";
XMLString::release(&message);
return ;
}
XercesDOMParser* parser = new XercesDOMParser();
parser->setValidationScheme(XercesDOMParser::Val_Always);
parser->setDoNamespaces(true);
XercesDOMParser* parser = new XercesDOMParser();
parser->setValidationScheme(XercesDOMParser::Val_Always);
parser->setDoNamespaces(true);
xercesc::MemBufInputSource myxml_buf((const XMLByte *const)s.c_str(), s.size(),
"myxml (in memory)");
xercesc::MemBufInputSource myxml_buf((const XMLByte *const)s.c_str(), s.size(),
"myxml (in memory)");
parser->parse(myxml_buf);
auto* dom=parser->getDocument();
checkXML(dom);
}
if ( truncated == 0 )
GetBucketContentList = false;
else
{
truncated = 0;
continuation = 0;
file = 0;
}
}
parser->parse(myxml_buf);
auto* dom=parser->getDocument();
checkXML(dom);
}
if ( truncated == 0 )
GetBucketContentList = false;
else
{
truncated = 0;
continuation = 0;
file = 0;
}
}
}
@@ -956,41 +950,41 @@ void Cloud::CloudReader::DownloadFile(Cloud::CloudReader::FileEntry *entry)
std::string s;
// We must get the directory content
char path[1024];
sprintf(path, "/%s/%s", this->Bucket, entry->FileName);
std::string strURL(this->URL);
char path[1024];
sprintf(path, "/%s/%s", this->Bucket, entry->FileName);
std::string strURL(this->URL);
eraseSubStr(strURL,"http://");
eraseSubStr(strURL,"https://");
if ( this->ProtocolVersion == "2" )
RequestData = Cloud::ComputeDigestAmzS3v2("GET", "application/octet-stream", path, this->TokenSecret, NULL, 0);
else
RequestDatav4 = Cloud::ComputeDigestAmzS3v4("GET", strURL.c_str(), "application/octet-stream", path, this->TokenSecret, NULL, 0, NULL, this->Region);
if ( this->ProtocolVersion == "2" )
RequestData = Cloud::ComputeDigestAmzS3v2("GET", "application/octet-stream", path, this->TokenSecret, NULL, 0);
else
RequestDatav4 = Cloud::ComputeDigestAmzS3v4("GET", strURL.c_str(), "application/octet-stream", path, this->TokenSecret, NULL, 0, NULL, this->Region);
// Let's build the Header and call to curl
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
#ifdef ALLOW_SELF_SIGNED_CERTIFICATE
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
#endif
if ( curl )
{
struct curl_slist *chunk = NULL;
char URL[256];
// Let's build our own header
std::string strURL(this->URL);
std::string strURL(this->URL);
eraseSubStr(strURL,"http://");
eraseSubStr(strURL,"https://");
if ( this->ProtocolVersion == "2" )
{
chunk = Cloud::BuildHeaderAmzS3v2( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestData);
delete RequestData;
}
else
{
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestDatav4);
delete RequestDatav4;
}
{
chunk = Cloud::BuildHeaderAmzS3v2( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestData);
delete RequestData;
}
else
{
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestDatav4);
delete RequestDatav4;
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
@@ -1051,11 +1045,11 @@ int Cloud::CloudReader::isTouched(std::string FileName)
void Cloud::eraseSubStr(std::string & Str, const std::string & toErase)
{
size_t pos = Str.find(toErase);
if (pos != std::string::npos)
{
Str.erase(pos, toErase.length());
}
size_t pos = Str.find(toErase);
if (pos != std::string::npos)
{
Str.erase(pos, toErase.length());
}
}
@@ -1081,44 +1075,44 @@ void Cloud::CloudWriter::pushCloud(const char *FileName, const char *data, long
struct Cloud::AmzDatav4 *RequestDatav4;
CURL *curl;
CURLcode res;
struct data_buffer curl_buffer;
struct data_buffer curl_buffer;
char path[1024];
char path[1024];
sprintf(path, "/%s/%s", this->Bucket, FileName);
std::string strURL(this->URL);
eraseSubStr(strURL,"http://");
eraseSubStr(strURL,"https://");
if ( this->ProtocolVersion == "2" )
RequestData = Cloud::ComputeDigestAmzS3v2("PUT", "application/octet-stream", path, this->TokenSecret, data, size);
else
RequestDatav4 = Cloud::ComputeDigestAmzS3v4("PUT", strURL.c_str(), "application/octet-stream", path, this->TokenSecret, data, size, NULL, this->Region);
if ( this->ProtocolVersion == "2" )
RequestData = Cloud::ComputeDigestAmzS3v2("PUT", "application/octet-stream", path, this->TokenSecret, data, size);
else
RequestDatav4 = Cloud::ComputeDigestAmzS3v4("PUT", strURL.c_str(), "application/octet-stream", path, this->TokenSecret, data, size, NULL, this->Region);
// Let's build the Header and call to curl
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
#ifdef ALLOW_SELF_SIGNED_CERTIFICATE
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
#endif
if ( curl )
{
struct curl_slist *chunk = NULL;
char URL[256];
char URL[256];
// Let's build our own header
std::string strURL(this->URL);
eraseSubStr(strURL,"http://");
eraseSubStr(strURL,"https://");
if ( this->ProtocolVersion == "2" )
{
chunk = Cloud::BuildHeaderAmzS3v2( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestData);
delete RequestData;
}
else
{
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestDatav4);
std::string strURL(this->URL);
eraseSubStr(strURL,"http://");
eraseSubStr(strURL,"https://");
if ( this->ProtocolVersion == "2" )
{
chunk = Cloud::BuildHeaderAmzS3v2( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestData);
delete RequestData;
}
else
{
chunk = Cloud::BuildHeaderAmzS3v4( strURL.c_str(), this->TCPPort, this->TokenAuth, RequestDatav4);
delete RequestDatav4;
}
}
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
@@ -1128,7 +1122,6 @@ void Cloud::CloudWriter::pushCloud(const char *FileName, const char *data, long
this->Bucket,FileName);
curl_easy_setopt(curl, CURLOPT_URL, URL);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(curl, CURLOPT_PUT, 1L);
// curl read a file not a memory buffer (it shall be able to do it)
@@ -1189,7 +1182,7 @@ void Cloud::CloudWriter::writeFiles(void)
bool Cloud::Module::cloudSave(const char *BucketName)
{
Document* doc = GetApplication().getActiveDocument();
Document* doc = GetApplication().getActiveDocument();
auto hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Document");
@@ -1216,8 +1209,8 @@ bool Cloud::Module::cloudSave(const char *BucketName)
(const char*)this->TokenSecret.getStrValue().c_str(),
(const char*)this->TCPPort.getStrValue().c_str(),
BucketName,
(const char*)this->ProtocolVersion.getStrValue().c_str(),
this->Region.getStrValue());
(const char*)this->ProtocolVersion.getStrValue().c_str(),
this->Region.getStrValue());
mywriter.putNextEntry("Document.xml");
@@ -1262,7 +1255,6 @@ void readFiles(Cloud::CloudReader reader, Base::XMLReader *xmlreader)
auto aString = ss.str();
aString = "";
}
it->Object->RestoreDocFile(localreader);
if ( localreader.getLocalReader() != nullptr )
{
@@ -1292,7 +1284,7 @@ bool Cloud::Module::cloudRestore (const char *BucketName)
(const char*)this->TokenSecret.getStrValue().c_str(),
(const char*)this->TCPPort.getStrValue().c_str(),
BucketName, (const char*)this->ProtocolVersion.getStrValue().c_str(),
this->Region.getStrValue());
this->Region.getStrValue());
// we shall pass there the initial Document.xml file