Merge branch 'master' into feature/holding-tags-copy
This commit is contained in:
@@ -28,6 +28,8 @@
|
||||
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/md5.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <App/Application.h>
|
||||
@@ -193,31 +195,15 @@ void Cloud::CloudWriter::checkText(DOMText* text) {
|
||||
|
||||
void Cloud::CloudWriter::createBucket()
|
||||
{
|
||||
printf("CREATING BUCKET %s\n", this->Bucket);
|
||||
struct timeval tv;
|
||||
struct tm *tm;
|
||||
char date_formatted[256];
|
||||
char StringToSign[1024];
|
||||
unsigned char *digest;
|
||||
|
||||
struct Cloud::AmzData *RequestData;
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
struct data_buffer curl_buffer;
|
||||
|
||||
#if defined(FC_OS_WIN32)
|
||||
#else
|
||||
gettimeofday(&tv,NULL);
|
||||
tm = localtime(&tv.tv_sec);
|
||||
strftime(date_formatted,256,"%a, %d %b %Y %T %z", tm);
|
||||
#endif
|
||||
|
||||
// CHANGEME
|
||||
sprintf(StringToSign,"PUT\n\napplication/xml\n%s\n/%s/", date_formatted, this->Bucket);
|
||||
|
||||
// We have to use HMAC encoding and SHA1
|
||||
digest=HMAC(EVP_sha1(),this->SecretKey,strlen(this->SecretKey),
|
||||
(const unsigned char *)&StringToSign,strlen(StringToSign),NULL,NULL);
|
||||
char path[1024];
|
||||
sprintf(path, "/%s/", this->Bucket);
|
||||
RequestData = Cloud::ComputeDigestAmzS3v2("PUT", "application/xml", path, this->SecretKey, NULL, 0);
|
||||
|
||||
// Let's build the Header and call to curl
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
@@ -225,27 +211,22 @@ void Cloud::CloudWriter::createBucket()
|
||||
if ( curl )
|
||||
{
|
||||
struct curl_slist *chunk = NULL;
|
||||
char header_data[1024];
|
||||
char Url[256];
|
||||
// Let's build our own header
|
||||
std::string strUrl(this->Url);
|
||||
eraseSubStr(strUrl,"http://");
|
||||
eraseSubStr(strUrl,"https://");
|
||||
|
||||
sprintf(header_data,"Host: %s", strUrl.c_str());
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
sprintf(header_data,"Date: %s", date_formatted);
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
chunk = curl_slist_append(chunk, "Content-Type: application/xml");
|
||||
std::string digest_str;
|
||||
digest_str=Base::base64_encode(digest,strlen((const char *)digest));
|
||||
sprintf(header_data,"Authorization: AWS %s:%s", this->AccessKey,
|
||||
digest_str.c_str());
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
chunk = Cloud::BuildHeaderAmzS3v2( strUrl.c_str(), this->TcpPort, this->AccessKey, RequestData);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
// curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
sprintf(header_data,"%s:%s/%s/", this->Url,this->TcpPort,
|
||||
|
||||
// Lets build the Url for our Curl call
|
||||
|
||||
sprintf(Url,"%s:%s/%s/", this->Url,this->TcpPort,
|
||||
this->Bucket);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, header_data);
|
||||
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)
|
||||
@@ -266,13 +247,113 @@ void Cloud::CloudWriter::createBucket()
|
||||
}
|
||||
}
|
||||
|
||||
Cloud::CloudWriter::CloudWriter(const char* Url, const char* AccessKey, const char* SecretKey, const char* TcpPort, const char* Bucket)
|
||||
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 timeval tv;
|
||||
struct tm *tm;
|
||||
char date_formatted[256];
|
||||
char StringToSign[1024];
|
||||
unsigned char *digest;
|
||||
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 = ( struct Cloud::AmzData *) malloc(sizeof(struct Cloud::AmzData));
|
||||
|
||||
strcpy(returnData->ContentType, data_type);
|
||||
|
||||
#if defined(FC_OS_WIN32)
|
||||
_putenv("TZ=GMT");
|
||||
#else
|
||||
setenv("TZ","GMT",1);
|
||||
#endif
|
||||
// We must check that the bucket exists or not. If not, we have to create it.
|
||||
// We must request the bucketlist if we receive a 404 error. This means that it
|
||||
// doesn't exist. The other option is that the content list is empty.
|
||||
// This piece of code is the same as the Reader except we do not interpret it !
|
||||
#if defined(FC_OS_WIN32)
|
||||
#else
|
||||
gettimeofday(&tv,NULL);
|
||||
tm = localtime(&tv.tv_sec);
|
||||
strftime(date_formatted,256,"%a, %d %b %Y %T %z", tm);
|
||||
#endif
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
MD5((unsigned char*) ptr, size, result);
|
||||
local= Base::base64_encode(result,MD5_DIGEST_LENGTH);
|
||||
strcpy(output,local.c_str());
|
||||
return(output);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// Build the Host: entry
|
||||
|
||||
sprintf(header_data,"Host: %s:%s", Url, TcpPort);
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
|
||||
// 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,"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);
|
||||
}
|
||||
|
||||
// build the Auth entry
|
||||
|
||||
sprintf(header_data,"Authorization: AWS %s:%s", PublicKey,
|
||||
Data->digest.c_str());
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
Cloud::CloudWriter::CloudWriter(const char* Url, const char* AccessKey, const char* SecretKey, const char* TcpPort, const char* Bucket)
|
||||
{
|
||||
struct Cloud::AmzData *RequestData;
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
@@ -284,58 +365,31 @@ Cloud::CloudWriter::CloudWriter(const char* Url, const char* AccessKey, const ch
|
||||
this->TcpPort=TcpPort;
|
||||
this->Bucket=Bucket;
|
||||
this->FileName="";
|
||||
// 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
|
||||
#if defined(FC_OS_WIN32)
|
||||
_putenv("TZ=GMT");
|
||||
#else
|
||||
setenv("TZ","GMT",1);
|
||||
#endif
|
||||
// We must check that the bucket exists or not. If not, we have to create it.
|
||||
// We must request the bucketlist if we receive a 404 error. This means that it
|
||||
// doesn't exist. The other option is that the content list is empty.
|
||||
// This piece of code is the same as the Reader except we do not interpret it !
|
||||
#if defined(FC_OS_WIN32)
|
||||
#else
|
||||
gettimeofday(&tv,NULL);
|
||||
tm = localtime(&tv.tv_sec);
|
||||
strftime(date_formatted,256,"%a, %d %b %Y %T %z", tm);
|
||||
#endif
|
||||
|
||||
sprintf(StringToSign,"GET\n\napplication/xml\n%s\n/%s/", date_formatted, this->Bucket);
|
||||
|
||||
// We have to use HMAC encoding and SHA1
|
||||
digest=HMAC(EVP_sha1(),this->SecretKey,strlen(this->SecretKey),
|
||||
(const unsigned char *)&StringToSign,strlen(StringToSign),NULL,NULL);
|
||||
|
||||
char path[1024];
|
||||
sprintf(path,"/%s/", this->Bucket);
|
||||
RequestData = Cloud::ComputeDigestAmzS3v2("GET", "application/xml", path, this->SecretKey, NULL, 0);
|
||||
// Let's build the Header and call to curl
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curl = curl_easy_init();
|
||||
if ( curl )
|
||||
{
|
||||
struct curl_slist *chunk = NULL;
|
||||
char header_data[1024];
|
||||
// Let's build our own header
|
||||
struct curl_slist *chunk = NULL;
|
||||
char Url[256];
|
||||
std::string strUrl(this->Url);
|
||||
eraseSubStr(strUrl,"http://");
|
||||
eraseSubStr(strUrl,"https://");
|
||||
|
||||
sprintf(header_data,"Host: %s:%s", strUrl.c_str(),
|
||||
this->TcpPort);
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
sprintf(header_data,"Date: %s", date_formatted);
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
chunk = curl_slist_append(chunk, "Content-Type: application/xml");
|
||||
std::string digest_str;
|
||||
digest_str=Base::base64_encode(digest,strlen((const char *)digest));
|
||||
sprintf(header_data,"Authorization: AWS %s:%s", this->AccessKey,
|
||||
digest_str.c_str());
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
chunk = Cloud::BuildHeaderAmzS3v2( strUrl.c_str(), this->TcpPort, this->AccessKey, RequestData);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
sprintf(header_data,"%s:%s/%s/", this->Url,this->TcpPort,
|
||||
|
||||
// Lets build the Url for our Curl call
|
||||
|
||||
sprintf(Url,"%s:%s/%s/", this->Url,this->TcpPort,
|
||||
this->Bucket);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, header_data);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, Url);
|
||||
|
||||
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)
|
||||
@@ -344,7 +398,8 @@ Cloud::CloudWriter::CloudWriter(const char* Url, const char* AccessKey, const ch
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
free( RequestData);
|
||||
// Let's dump temporarly for debug purpose of s3v4 implementation
|
||||
|
||||
std::stringstream input(s);
|
||||
|
||||
@@ -458,11 +513,7 @@ Cloud::CloudReader::~CloudReader()
|
||||
|
||||
Cloud::CloudReader::CloudReader(const char* Url, const char* AccessKey, const char* SecretKey, const char* TcpPort, const char* Bucket)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct tm *tm;
|
||||
char date_formatted[256];
|
||||
char StringToSign[1024];
|
||||
unsigned char *digest;
|
||||
struct Cloud::AmzData *RequestData;
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
@@ -475,58 +526,32 @@ Cloud::CloudReader::CloudReader(const char* Url, const char* AccessKey, const ch
|
||||
this->TcpPort=TcpPort;
|
||||
this->Bucket=Bucket;
|
||||
|
||||
// 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
|
||||
#if defined(FC_OS_WIN32)
|
||||
_putenv("TZ=GMT");
|
||||
#else
|
||||
setenv("TZ","GMT",1);
|
||||
#endif
|
||||
char path[1024];
|
||||
sprintf(path,"/%s/", this->Bucket);
|
||||
RequestData = Cloud::ComputeDigestAmzS3v2("GET", "application/xml", path, this->SecretKey, NULL, 0);
|
||||
|
||||
// We must get the directory content
|
||||
|
||||
|
||||
#if defined(FC_OS_WIN32)
|
||||
#else
|
||||
gettimeofday(&tv,NULL);
|
||||
tm = localtime(&tv.tv_sec);
|
||||
strftime(date_formatted,256,"%a, %d %b %Y %T %z", tm);
|
||||
#endif
|
||||
|
||||
sprintf(StringToSign,"GET\n\napplication/xml\n%s\n/%s/", date_formatted, this->Bucket);
|
||||
|
||||
// We have to use HMAC encoding and SHA1
|
||||
digest=HMAC(EVP_sha1(),this->SecretKey,strlen(this->SecretKey),
|
||||
(const unsigned char *)&StringToSign,strlen(StringToSign),NULL,NULL);
|
||||
|
||||
// Let's build the Header and call to curl
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curl = curl_easy_init();
|
||||
if ( curl )
|
||||
{
|
||||
// Let's build our own header
|
||||
struct curl_slist *chunk = NULL;
|
||||
char header_data[1024];
|
||||
// Let's build our own header
|
||||
std::string strUrl(this->Url);
|
||||
char Url[256];
|
||||
std::string strUrl(this->Url);
|
||||
eraseSubStr(strUrl,"http://");
|
||||
eraseSubStr(strUrl,"https://");
|
||||
|
||||
sprintf(header_data,"Host: %s:%s", strUrl.c_str(),
|
||||
this->TcpPort);
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
sprintf(header_data,"Date: %s", date_formatted);
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
chunk = curl_slist_append(chunk, "Content-Type: application/xml");
|
||||
std::string digest_str;
|
||||
digest_str=Base::base64_encode(digest,strlen((const char *)digest));
|
||||
sprintf(header_data,"Authorization: AWS %s:%s", this->AccessKey,
|
||||
digest_str.c_str());
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
chunk = Cloud::BuildHeaderAmzS3v2( strUrl.c_str(), this->TcpPort, this->AccessKey, RequestData);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
sprintf(header_data,"%s:%s/%s/", this->Url,this->TcpPort,
|
||||
|
||||
sprintf(Url,"%s:%s/%s/", this->Url,this->TcpPort,
|
||||
this->Bucket);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, header_data);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, Url);
|
||||
|
||||
|
||||
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)
|
||||
@@ -564,31 +589,16 @@ Cloud::CloudReader::CloudReader(const char* Url, const char* AccessKey, const ch
|
||||
|
||||
void Cloud::CloudReader::DownloadFile(Cloud::CloudReader::FileEntry *entry)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct tm *tm;
|
||||
char date_formatted[256];
|
||||
char StringToSign[1024];
|
||||
unsigned char *digest;
|
||||
struct Cloud::AmzData *RequestData;
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
std::string s;
|
||||
|
||||
// We must get the directory content
|
||||
|
||||
|
||||
#if defined(FC_OS_WIN32)
|
||||
#else
|
||||
gettimeofday(&tv,NULL);
|
||||
tm = localtime(&tv.tv_sec);
|
||||
strftime(date_formatted,256,"%a, %d %b %Y %T %z", tm);
|
||||
#endif
|
||||
|
||||
// CHANGEME
|
||||
sprintf(StringToSign,"GET\n\napplication/octet-stream\n%s\n/%s/%s", date_formatted, this->Bucket, entry->FileName);
|
||||
// We have to use HMAC encoding and SHA1
|
||||
digest=HMAC(EVP_sha1(),this->SecretKey,strlen(this->SecretKey),
|
||||
(const unsigned char *)&StringToSign,strlen(StringToSign),NULL,NULL);
|
||||
char path[1024];
|
||||
sprintf(path, "/%s/%s", this->Bucket, entry->FileName);
|
||||
RequestData = Cloud::ComputeDigestAmzS3v2("GET", "application/octet-stream", path, this->SecretKey, NULL, 0);
|
||||
|
||||
// Let's build the Header and call to curl
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
@@ -596,26 +606,20 @@ void Cloud::CloudReader::DownloadFile(Cloud::CloudReader::FileEntry *entry)
|
||||
if ( curl )
|
||||
{
|
||||
struct curl_slist *chunk = NULL;
|
||||
char header_data[1024];
|
||||
char Url[256];
|
||||
// Let's build our own header
|
||||
std::string strUrl(this->Url);
|
||||
eraseSubStr(strUrl,"http://");
|
||||
eraseSubStr(strUrl,"https://");
|
||||
sprintf(header_data,"Host: %s:%s", strUrl.c_str(),
|
||||
this->TcpPort);
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
sprintf(header_data,"Date: %s", date_formatted);
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
chunk = curl_slist_append(chunk, "Content-Type: application/octet-stream");
|
||||
std::string digest_str;
|
||||
digest_str=Base::base64_encode(digest,strlen((const char *)digest));
|
||||
sprintf(header_data,"Authorization: AWS %s:%s", this->AccessKey,
|
||||
digest_str.c_str());
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
|
||||
chunk = Cloud::BuildHeaderAmzS3v2( strUrl.c_str(), this->TcpPort, this->AccessKey, RequestData);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
sprintf(header_data,"%s:%s/%s/%s", this->Url,this->TcpPort,
|
||||
this->Bucket,entry->FileName);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, header_data);
|
||||
|
||||
sprintf(Url,"%s:%s/%s/%s", this->Url,this->TcpPort,
|
||||
this->Bucket, entry->FileName);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, Url);
|
||||
|
||||
// curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWrite_CallbackFunc_StdString);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
|
||||
@@ -696,31 +700,14 @@ bool Cloud::CloudWriter::shouldWrite(const std::string& , const Base::Persistenc
|
||||
|
||||
void Cloud::CloudWriter::pushCloud(const char *FileName, const char *data, long size)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct tm *tm;
|
||||
char date_formatted[256];
|
||||
char StringToSign[1024];
|
||||
unsigned char *digest;
|
||||
// char my_data[1024]="a que coucou";
|
||||
|
||||
struct Cloud::AmzData *RequestData;
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct data_buffer curl_buffer;
|
||||
|
||||
struct data_buffer curl_buffer;
|
||||
|
||||
#if defined(FC_OS_WIN32)
|
||||
#else
|
||||
gettimeofday(&tv,NULL);
|
||||
tm = localtime(&tv.tv_sec);
|
||||
strftime(date_formatted,256,"%a, %d %b %Y %T %z", tm);
|
||||
#endif
|
||||
|
||||
// CHANGEME
|
||||
sprintf(StringToSign,"PUT\n\napplication/octet-stream\n%s\n/%s/%s", date_formatted, this->Bucket, FileName);
|
||||
|
||||
// We have to use HMAC encoding and SHA1
|
||||
digest=HMAC(EVP_sha1(),this->SecretKey,strlen(this->SecretKey),
|
||||
(const unsigned char *)&StringToSign,strlen(StringToSign),NULL,NULL);
|
||||
char path[1024];
|
||||
sprintf(path, "/%s/%s", this->Bucket, FileName);
|
||||
RequestData = Cloud::ComputeDigestAmzS3v2("PUT", "application/octet-stream", path, this->SecretKey, data, size);
|
||||
|
||||
// Let's build the Header and call to curl
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
@@ -728,28 +715,26 @@ void Cloud::CloudWriter::pushCloud(const char *FileName, const char *data, long
|
||||
if ( curl )
|
||||
{
|
||||
struct curl_slist *chunk = NULL;
|
||||
char header_data[1024];
|
||||
char Url[256];
|
||||
// Let's build our own header
|
||||
std::string strUrl(this->Url);
|
||||
eraseSubStr(strUrl,"http://");
|
||||
eraseSubStr(strUrl,"https://");
|
||||
|
||||
sprintf(header_data,"Host: %s:%s", strUrl.c_str(),
|
||||
this->TcpPort);
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
sprintf(header_data,"Date: %s", date_formatted);
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
chunk = curl_slist_append(chunk, "Content-Type: application/octet-stream");
|
||||
std::string digest_str;
|
||||
digest_str=Base::base64_encode(digest,strlen((const char *)digest));
|
||||
sprintf(header_data,"Authorization: AWS %s:%s", this->AccessKey,
|
||||
digest_str.c_str());
|
||||
chunk = curl_slist_append(chunk, header_data);
|
||||
|
||||
|
||||
chunk = Cloud::BuildHeaderAmzS3v2( strUrl.c_str(), this->TcpPort, this->AccessKey, RequestData);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
// curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
sprintf(header_data,"%s:%s/%s/%s", this->Url,this->TcpPort,
|
||||
|
||||
// Lets build the Url for our Curl call
|
||||
|
||||
sprintf(Url,"%s:%s/%s/%s", this->Url,this->TcpPort,
|
||||
this->Bucket,FileName);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, header_data);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, Url);
|
||||
|
||||
|
||||
// curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
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)
|
||||
|
||||
@@ -47,8 +47,19 @@ XERCES_CPP_NAMESPACE_END
|
||||
|
||||
namespace Cloud {
|
||||
|
||||
struct AmzData {
|
||||
std::string digest;
|
||||
char dateFormatted[256];
|
||||
char ContentType[256];
|
||||
char Host[256];
|
||||
char *MD5;
|
||||
};
|
||||
|
||||
void eraseSubStr(std::string & Str, const std::string & toErase);
|
||||
size_t CurlWrite_CallbackFunc_StdString(void *contents, size_t size, size_t nmemb, std::string *s);
|
||||
struct AmzData *ComputeDigestAmzS3v2(char *operation, char *data_type, const char *target, const char *Secret, const char *ptr, long size);
|
||||
struct curl_slist *BuildHeaderAmzS3v2(const char *Url, const char *TcpPort, const char *PublicKey, struct AmzData *Data);
|
||||
char *MD5Sum(const char *ptr, long size);
|
||||
|
||||
class CloudAppExport CloudReader
|
||||
{
|
||||
|
||||
@@ -31,10 +31,16 @@ Base::Vector3d toVector3d(const double* a)
|
||||
|
||||
CDxfWrite::CDxfWrite(const char* filepath) :
|
||||
//TODO: these should probably be parms in config file
|
||||
m_entityHandle(0x300),
|
||||
m_layerHandle(0x30),
|
||||
m_blockHandle(0x210),
|
||||
m_blkRecordHandle(0x110),
|
||||
//handles:
|
||||
//boilerplate 0 - A00
|
||||
//used by dxf.cpp A01 - FFFE
|
||||
//ACAD HANDSEED FFFF
|
||||
|
||||
m_handle(0xA00), //room for 2560 handles in boilerplate files
|
||||
//m_entityHandle(0x300), //don't need special ranges for handles
|
||||
//m_layerHandle(0x30),
|
||||
//m_blockHandle(0x210),
|
||||
//m_blkRecordHandle(0x110),
|
||||
m_polyOverride(false),
|
||||
m_layerName("none")
|
||||
{
|
||||
@@ -435,40 +441,53 @@ std::string CDxfWrite::getPlateFile(std::string fileSpec)
|
||||
return outString.str();
|
||||
}
|
||||
|
||||
std::string CDxfWrite::getEntityHandle(void)
|
||||
std::string CDxfWrite::getHandle(void)
|
||||
{
|
||||
m_entityHandle++;
|
||||
m_handle++;
|
||||
std::stringstream ss;
|
||||
ss << std::uppercase << std::hex << std::setfill('0') << std::setw(2);
|
||||
ss << m_entityHandle;
|
||||
ss << m_handle;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string CDxfWrite::getEntityHandle(void)
|
||||
{
|
||||
return getHandle();
|
||||
// m_entityHandle++;
|
||||
// std::stringstream ss;
|
||||
// ss << std::uppercase << std::hex << std::setfill('0') << std::setw(2);
|
||||
// ss << m_entityHandle;
|
||||
// return ss.str();
|
||||
}
|
||||
|
||||
std::string CDxfWrite::getLayerHandle(void)
|
||||
{
|
||||
m_layerHandle++;
|
||||
std::stringstream ss;
|
||||
ss << std::uppercase << std::hex << std::setfill('0') << std::setw(2);
|
||||
ss << m_layerHandle;
|
||||
return ss.str();
|
||||
return getHandle();
|
||||
// m_layerHandle++;
|
||||
// std::stringstream ss;
|
||||
// ss << std::uppercase << std::hex << std::setfill('0') << std::setw(2);
|
||||
// ss << m_layerHandle;
|
||||
// return ss.str();
|
||||
}
|
||||
|
||||
std::string CDxfWrite::getBlockHandle(void)
|
||||
{
|
||||
m_blockHandle++;
|
||||
std::stringstream ss;
|
||||
ss << std::uppercase << std::hex << std::setfill('0') << std::setw(2);
|
||||
ss << m_blockHandle;
|
||||
return ss.str();
|
||||
return getHandle();
|
||||
// m_blockHandle++;
|
||||
// std::stringstream ss;
|
||||
// ss << std::uppercase << std::hex << std::setfill('0') << std::setw(2);
|
||||
// ss << m_blockHandle;
|
||||
// return ss.str();
|
||||
}
|
||||
|
||||
std::string CDxfWrite::getBlkRecordHandle(void)
|
||||
{
|
||||
m_blkRecordHandle++;
|
||||
std::stringstream ss;
|
||||
ss << std::uppercase << std::hex << std::setfill('0') << std::setw(2);
|
||||
ss << m_blkRecordHandle;
|
||||
return ss.str();
|
||||
return getHandle();
|
||||
// m_blkRecordHandle++;
|
||||
// std::stringstream ss;
|
||||
// ss << std::uppercase << std::hex << std::setfill('0') << std::setw(2);
|
||||
// ss << m_blkRecordHandle;
|
||||
// return ss.str();
|
||||
}
|
||||
|
||||
void CDxfWrite::addBlockName(std::string b, std::string h)
|
||||
|
||||
@@ -145,6 +145,7 @@ protected:
|
||||
//! copy boiler plate file
|
||||
std::string getPlateFile(std::string fileSpec);
|
||||
void setDataDir(std::string s) { m_dataDir = s; }
|
||||
std::string getHandle(void);
|
||||
std::string getEntityHandle(void);
|
||||
std::string getLayerHandle(void);
|
||||
std::string getBlockHandle(void);
|
||||
@@ -152,6 +153,7 @@ protected:
|
||||
|
||||
std::string m_optionSource;
|
||||
int m_version;
|
||||
int m_handle;
|
||||
int m_entityHandle;
|
||||
int m_layerHandle;
|
||||
int m_blockHandle;
|
||||
|
||||
@@ -31,8 +31,24 @@ $CMLSTYLE
|
||||
2
|
||||
STANDARD
|
||||
9
|
||||
$PEXTMAX
|
||||
10
|
||||
50
|
||||
20
|
||||
50
|
||||
30
|
||||
50
|
||||
9
|
||||
$PEXTMIN
|
||||
10
|
||||
0
|
||||
20
|
||||
0
|
||||
30
|
||||
0
|
||||
9
|
||||
$HANDSEED
|
||||
5
|
||||
FFF
|
||||
FFFF
|
||||
0
|
||||
ENDSEC
|
||||
|
||||
@@ -5,7 +5,7 @@ OBJECTS
|
||||
0
|
||||
DICTIONARY
|
||||
5
|
||||
500
|
||||
F000
|
||||
330
|
||||
0
|
||||
100
|
||||
@@ -13,13 +13,13 @@ AcDbDictionary
|
||||
3
|
||||
ACAD_GROUP
|
||||
350
|
||||
501
|
||||
F001
|
||||
0
|
||||
DICTIONARY
|
||||
5
|
||||
501
|
||||
F001
|
||||
330
|
||||
500
|
||||
F000
|
||||
100
|
||||
AcDbDictionary
|
||||
0
|
||||
|
||||
@@ -3,7 +3,7 @@ TABLE
|
||||
2
|
||||
STYLE
|
||||
5
|
||||
60
|
||||
70
|
||||
330
|
||||
0
|
||||
100
|
||||
@@ -13,9 +13,9 @@ AcDbSymbolTable
|
||||
0
|
||||
STYLE
|
||||
5
|
||||
61
|
||||
71
|
||||
330
|
||||
60
|
||||
70
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
@@ -41,9 +41,9 @@ arial.ttf
|
||||
0
|
||||
STYLE
|
||||
5
|
||||
62
|
||||
72
|
||||
330
|
||||
60
|
||||
70
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
@@ -73,7 +73,7 @@ TABLE
|
||||
2
|
||||
VIEW
|
||||
5
|
||||
63
|
||||
73
|
||||
330
|
||||
0
|
||||
100
|
||||
@@ -87,7 +87,7 @@ TABLE
|
||||
2
|
||||
UCS
|
||||
5
|
||||
64
|
||||
74
|
||||
330
|
||||
0
|
||||
100
|
||||
@@ -101,7 +101,7 @@ TABLE
|
||||
2
|
||||
APPID
|
||||
5
|
||||
65
|
||||
75
|
||||
330
|
||||
0
|
||||
100
|
||||
@@ -111,9 +111,9 @@ AcDbSymbolTable
|
||||
0
|
||||
APPID
|
||||
5
|
||||
66
|
||||
76
|
||||
330
|
||||
65
|
||||
75
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
@@ -125,9 +125,9 @@ ACAD
|
||||
0
|
||||
APPID
|
||||
5
|
||||
67
|
||||
77
|
||||
330
|
||||
65
|
||||
75
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
@@ -143,7 +143,7 @@ TABLE
|
||||
2
|
||||
DIMSTYLE
|
||||
5
|
||||
68
|
||||
78
|
||||
330
|
||||
0
|
||||
100
|
||||
@@ -153,9 +153,9 @@ AcDbSymbolTable
|
||||
0
|
||||
DIMSTYLE
|
||||
105
|
||||
69
|
||||
79
|
||||
330
|
||||
68
|
||||
78
|
||||
100
|
||||
AcDbSymbolTableRecord
|
||||
100
|
||||
@@ -253,7 +253,7 @@ STANDARD
|
||||
274
|
||||
3
|
||||
340
|
||||
61
|
||||
71
|
||||
275
|
||||
0
|
||||
280
|
||||
|
||||
@@ -38,9 +38,11 @@ class OpenSCADWorkbench ( Workbench ):
|
||||
def __init__(self):
|
||||
self.__class__.Icon = FreeCAD.getResourceDir() + "Mod/OpenSCAD/Resources/icons/OpenSCADWorkbench.svg"
|
||||
self.__class__.MenuText = "OpenSCAD"
|
||||
self.__class__.ToolTip = "OpenSCAD is an application for creating solid 3D CAD." + '\n' +
|
||||
"FreeCAD utizes OpenSCAD's capability as a script-only based modeller that uses its own description language" + '\n' +
|
||||
"Note: the Mesh workbench heavily uses the boolean operations of this workbench because they are quite robust"
|
||||
self.__class__.ToolTip = (
|
||||
"OpenSCAD is an application for creating solid 3D CAD.\n"
|
||||
"FreeCAD utizes OpenSCAD's capability as a script-only based modeller that uses its own description language\n"
|
||||
"Note: the Mesh workbench heavily uses the boolean operations of this workbench because they are quite robust"
|
||||
)
|
||||
|
||||
def Initialize(self):
|
||||
def QT_TRANSLATE_NOOP(scope, text):
|
||||
|
||||
@@ -538,21 +538,26 @@ void QGIViewDimension::updateDim()
|
||||
if ( vp == nullptr ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// QString labelText = QString::fromUtf8(dim->getFormatedValue().c_str());
|
||||
//want this split into value and unit
|
||||
QString labelText = QString::fromUtf8(dim->getFormatedValue(1).c_str()); //just the number
|
||||
QString unitText = QString::fromUtf8(dim->getFormatedValue(2).c_str()); //just the unit
|
||||
|
||||
QString arbText = QString::fromUtf8(dim->FormatSpec.getValue());
|
||||
|
||||
QFont font = datumLabel->getFont();
|
||||
font.setFamily(QString::fromUtf8(vp->Font.getValue()));
|
||||
font.setPixelSize(calculateFontPixelSize(vp->Fontsize.getValue()));
|
||||
datumLabel->setFont(font);
|
||||
|
||||
prepareGeometryChange();
|
||||
datumLabel->setDimString(labelText);
|
||||
datumLabel->setTolString();
|
||||
datumLabel->setUnitString(unitText);
|
||||
if (dim->Arbitrary.getValue()) {
|
||||
datumLabel->setDimString(arbText);
|
||||
} else {
|
||||
datumLabel->setDimString(labelText);
|
||||
datumLabel->setTolString();
|
||||
datumLabel->setUnitString(unitText);
|
||||
}
|
||||
datumLabel->setPosFromCenter(datumLabel->X(),datumLabel->Y());
|
||||
|
||||
datumLabel->setFramed(dim->TheoreticalExact.getValue());
|
||||
|
||||
@@ -113,8 +113,8 @@ class ParameterTestCase(unittest.TestCase):
|
||||
self.failUnless(self.TestPar.HasGroup("44"),"Test on created group failed")
|
||||
# check on Deletion
|
||||
self.TestPar.RemGroup("44")
|
||||
self.failUnless(not self.TestPar.HasGroup("44"),"Test on delete group failed")
|
||||
Temp =0
|
||||
self.failUnless(self.TestPar.HasGroup("44"),"A referenced group must not be deleted")
|
||||
Temp = 0
|
||||
|
||||
#check on special conditions
|
||||
def testInt(self):
|
||||
|
||||
Reference in New Issue
Block a user