1 /*
2 * Copyright 2009-2017 Alibaba Cloud All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "Utils.h"
18
19 #ifdef USE_CRYPTO_MBEDTLS
20 #include "mbedtls/md.h"
21 #include "mbedtls/compat-1.3.h"
22 #include "mbedtls/sha1.h"
23 #include "mbedtls/base64.h"
24 #include "mbedtls/md5.h"
25
26 #else
27
28 #include <openssl/evp.h>
29 #include <openssl/hmac.h>
30 #include <openssl/md5.h>
31
32 #ifdef OPENSSL_IS_BORINGSSL
33 #include <openssl/base64.h>
34 #endif
35
36 #endif
37
38 #include <algorithm>
39 #include <cstring>
40 #include <iostream>
41 #include <sstream>
42 #include <map>
43 #include <regex>
44 #include <iomanip>
45 #include <alibabacloud/oss/Const.h>
46 #include <alibabacloud/oss/http/HttpType.h>
47 #include <alibabacloud/oss/http/Url.h>
48 #include "../external/json/json.h"
49
50 using namespace AlibabaCloud::OSS;
51
52 #if defined(__GNUG__) && __GNUC__ < 5
53
54 #else
55 static const std::regex ipPattern("((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])");
56 static const std::regex bucketNamePattern("^[a-z0-9][a-z0-9\\-]{1,61}[a-z0-9]$");
57 static const std::regex loggingPrefixPattern("^[a-zA-Z][a-zA-Z0-9\\-]{0,31}$");
58 #endif
59
GenerateUuid()60 std::string AlibabaCloud::OSS::GenerateUuid()
61 {
62 return "";
63 }
64
UrlEncode(const std::string & src)65 std::string AlibabaCloud::OSS::UrlEncode(const std::string & src)
66 {
67 std::stringstream dest;
68 static const char *hex = "0123456789ABCDEF";
69 unsigned char c;
70
71 for (size_t i = 0; i < src.size(); i++) {
72 c = src[i];
73 if (isalnum(c) || (c == '-') || (c == '_') || (c == '.') || (c == '~')) {
74 dest << c;
75 } else if (c == ' ') {
76 dest << "%20";
77 } else {
78 dest << '%' << hex[c >> 4] << hex[c & 15];
79 }
80 }
81
82 return dest.str();
83 }
84
UrlDecode(const std::string & src)85 std::string AlibabaCloud::OSS::UrlDecode(const std::string & src)
86 {
87 std::stringstream unescaped;
88 unescaped.fill('0');
89 unescaped << std::hex;
90
91 size_t safeLength = src.size();
92 const char *safe = src.c_str();
93 for (auto i = safe, n = safe + safeLength; i != n; ++i)
94 {
95 char c = *i;
96 if(c == '%')
97 {
98 char hex[3];
99 hex[0] = *(i + 1);
100 hex[1] = *(i + 2);
101 hex[2] = 0;
102 i += 2;
103 auto hexAsInteger = strtol(hex, nullptr, 16);
104 unescaped << (char)hexAsInteger;
105 }
106 else
107 {
108 unescaped << *i;
109 }
110 }
111
112 return unescaped.str();
113 }
114
Base64Encode(const std::string & src)115 std::string AlibabaCloud::OSS::Base64Encode(const std::string &src)
116 {
117 return AlibabaCloud::OSS::Base64Encode(src.c_str(), static_cast<int>(src.size()));
118 }
119
Base64Encode(const ByteBuffer & buffer)120 std::string AlibabaCloud::OSS::Base64Encode(const ByteBuffer& buffer)
121 {
122 return AlibabaCloud::OSS::Base64Encode(reinterpret_cast<const char*>(buffer.data()), static_cast<int>(buffer.size()));
123 }
124
Base64Encode(const char * src,int len)125 std::string AlibabaCloud::OSS::Base64Encode(const char *src, int len)
126 {
127 if (!src || len == 0) {
128 return "";
129 }
130
131 static const char *ENC = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
132 auto in = reinterpret_cast<const unsigned char *>(src);
133 auto inLen = len;
134 std::stringstream ss;
135 while (inLen) {
136 // first 6 bits of char 1
137 ss << ENC[*in >> 2];
138 if (!--inLen) {
139 // last 2 bits of char 1, 4 bits of 0
140 ss << ENC[(*in & 0x3) << 4];
141 ss << '=';
142 ss << '=';
143 break;
144 }
145 // last 2 bits of char 1, first 4 bits of char 2
146 ss << ENC[((*in & 0x3) << 4) | (*(in + 1) >> 4)];
147 in++;
148 if (!--inLen) {
149 // last 4 bits of char 2, 2 bits of 0
150 ss << ENC[(*in & 0xF) << 2];
151 ss << '=';
152 break;
153 }
154 // last 4 bits of char 2, first 2 bits of char 3
155 ss << ENC[((*in & 0xF) << 2) | (*(in + 1) >> 6)];
156 in++;
157 // last 6 bits of char 3
158 ss << ENC[*in & 0x3F];
159 in++, inLen--;
160 }
161 return ss.str();
162 }
163
Base64EncodeUrlSafe(const std::string & src)164 std::string AlibabaCloud::OSS::Base64EncodeUrlSafe(const std::string &src)
165 {
166 return AlibabaCloud::OSS::Base64EncodeUrlSafe(src.c_str(), static_cast<int>(src.size()));
167 }
168
Base64EncodeUrlSafe(const char * src,int len)169 std::string AlibabaCloud::OSS::Base64EncodeUrlSafe(const char *src, int len)
170 {
171 std::string out = AlibabaCloud::OSS::Base64Encode(src, len);
172
173 while (out.size() > 0 && *out.rbegin() == '=')
174 out.pop_back();
175
176 std::transform(out.begin(), out.end(), out.begin(), [](unsigned char c) {
177 if (c == '+') return '-';
178 if (c == '/') return '_';
179 return (char)c;
180 });
181 return out;
182 }
183
XmlEscape(const std::string & value)184 std::string AlibabaCloud::OSS::XmlEscape(const std::string& value)
185 {
186 struct Entity {
187 const char* pattern;
188 char value;
189 };
190
191 static const Entity entities[] = {
192 { """, '\"' },
193 { "&", '&' },
194 { "'", '\'' },
195 { "<", '<' },
196 { ">", '>' },
197 { " ", '\r' }
198 };
199
200 if (value.empty()) {
201 return value;
202 }
203
204 std::stringstream ss;
205 for (size_t i = 0; i < value.size(); i++) {
206 bool flag = false;
207 for (size_t j = 0; j < (sizeof(entities)/sizeof(entities[0])); j++) {
208 if (value[i] == entities[j].value) {
209 flag = true;
210 ss << entities[j].pattern;
211 break;
212 }
213 }
214
215 if (!flag) {
216 ss << value[i];
217 }
218 }
219
220 return ss.str();
221 }
Base64Decode(const char * data,int len)222 ByteBuffer AlibabaCloud::OSS::Base64Decode(const char *data, int len)
223 {
224 int in_len = len;
225 int i = 0;
226 int in_ = 0;
227 unsigned char part4[4];
228
229 const int max_len = (len * 3 / 4);
230 ByteBuffer ret(max_len);
231 int idx = 0;
232
233 while (in_len-- && (data[in_] != '=')) {
234 unsigned char ch = data[in_++];
235 if ('A' <= ch && ch <= 'Z') ch = ch - 'A'; // A - Z
236 else if ('a' <= ch && ch <= 'z') ch = ch - 'a' + 26; // a - z
237 else if ('0' <= ch && ch <= '9') ch = ch - '0' + 52; // 0 - 9
238 else if ('+' == ch) ch = 62; // +
239 else if ('/' == ch) ch = 63; // /
240 else if ('=' == ch) ch = 64; // =
241 else ch = 0xff; // something wrong
242 part4[i++] = ch;
243 if (i == 4) {
244 ret[idx++] = (part4[0] << 2) + ((part4[1] & 0x30) >> 4);
245 ret[idx++] = ((part4[1] & 0xf) << 4) + ((part4[2] & 0x3c) >> 2);
246 ret[idx++] = ((part4[2] & 0x3) << 6) + part4[3];
247 i = 0;
248 }
249 }
250
251 if (i) {
252 for (int j = i; j < 4; j++)
253 part4[j] = 0xFF;
254 ret[idx++] = (part4[0] << 2) + ((part4[1] & 0x30) >> 4);
255 if (part4[2] != 0xFF) {
256 ret[idx++] = ((part4[1] & 0xf) << 4) + ((part4[2] & 0x3c) >> 2);
257 if (part4[3] != 0xFF) {
258 ret[idx++] = ((part4[2] & 0x3) << 6) + part4[3];
259 }
260 }
261 }
262
263 ret.resize(idx);
264 return ret;
265 }
266
Base64Decode(const std::string & src)267 ByteBuffer AlibabaCloud::OSS::Base64Decode(const std::string &src)
268 {
269 return Base64Decode(src.c_str(), src.size());
270 }
271
272
ComputeContentMD5(const std::string & data)273 std::string AlibabaCloud::OSS::ComputeContentMD5(const std::string& data)
274 {
275 return ComputeContentMD5(data.c_str(), data.size());
276 }
277
ComputeContentMD5(const char * data,size_t size)278 std::string AlibabaCloud::OSS::ComputeContentMD5(const char * data, size_t size)
279 {
280 #if defined(USE_CRYPTO_MBEDTLS)
281 unsigned char md_data[16];
282 unsigned int mdLen = 16;
283 mbedtls_md5_context ctx;
284 unsigned int olen = 0;
285 #if 0
286 mbedtls_md5_init(&ctx);
287 mbedtls_md5_starts(&ctx);
288 mbedtls_md5_update(&ctx, (const unsigned char *)data, size);
289 mbedtls_md5_finish(&ctx, md_data);
290 mbedtls_md5_free(&ctx);
291 #endif
292
293 mbedtls_md5_ret((const unsigned char*)data, size, md_data);
294
295 char encodedData[100];
296
297 mbedtls_base64_encode((unsigned char*)encodedData, sizeof(encodedData), &olen, md_data, mdLen);
298
299 return encodedData;
300 //TODO: ethan: not used for the moment
301 #elif 0//defined(USE_CRYPTO_MBEDTLS)
302 unsigned char md_data[16];
303 unsigned int mdLen = 16;
304 unsigned int olen = 0;
305
306 mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_MD5), data, size, md_data);
307
308 char encodedData[100];
309
310 mbedtls_base64_encode((unsigned char*)encodedData, sizeof(encodedData), &olen, md_data, mdLen);
311
312 return encodedData;
313 #else
314
315 unsigned char md[MD5_DIGEST_LENGTH];
316 MD5(reinterpret_cast<const unsigned char*>(data), size, (unsigned char*)&md);
317
318 char encodedData[100];
319
320 EVP_EncodeBlock(reinterpret_cast<unsigned char*>(encodedData), md, MD5_DIGEST_LENGTH);
321
322 return encodedData;
323 #endif
324 }
325
ComputeContentMD5(std::istream & stream)326 std::string AlibabaCloud::OSS::ComputeContentMD5(std::istream& stream)
327 {
328 #ifdef USE_CRYPTO_MBEDTLS
329 unsigned char md_value[16];
330 unsigned int md_len = 16;
331 unsigned int olen = 0;
332 mbedtls_md5_context ctx;
333
334 mbedtls_md5_init(&ctx);
335 mbedtls_md5_starts_ret(&ctx);
336
337 auto currentPos = stream.tellg();
338 if (currentPos == static_cast<std::streampos>(-1)) {
339 currentPos = 0;
340 stream.clear();
341 }
342 stream.seekg(0, stream.beg);
343
344 // TODO: ethan, need to shrink the buffer, or stack overflow may happen?
345
346 char streamBuffer[2048];
347 while (stream.good())
348 {
349 stream.read(streamBuffer, 2048);
350 auto bytesRead = stream.gcount();
351
352 if (bytesRead > 0)
353 {
354 mbedtls_md5_update_ret(&ctx, (const unsigned char*)streamBuffer, static_cast<size_t>(bytesRead));
355 }
356 }
357
358 mbedtls_md5_finish_ret(&ctx, md_value);
359 mbedtls_md5_free(&ctx);
360
361 stream.clear();
362 stream.seekg(currentPos, stream.beg);
363
364 //Based64
365 char encodedData[100];
366
367 mbedtls_base64_encode((unsigned char*)encodedData, sizeof(encodedData), &olen, md_value, md_len);
368
369 return encodedData;
370 #else
371 auto ctx = EVP_MD_CTX_create();
372
373 unsigned char md_value[EVP_MAX_MD_SIZE];
374 unsigned int md_len = 0;
375
376 EVP_MD_CTX_init(ctx);
377 #ifndef OPENSSL_IS_BORINGSSL
378 EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
379 #endif
380 EVP_DigestInit_ex(ctx, EVP_md5(), nullptr);
381
382 auto currentPos = stream.tellg();
383 if (currentPos == static_cast<std::streampos>(-1)) {
384 currentPos = 0;
385 stream.clear();
386 }
387 stream.seekg(0, stream.beg);
388
389 char streamBuffer[2048];
390 while (stream.good())
391 {
392 stream.read(streamBuffer, 2048);
393 auto bytesRead = stream.gcount();
394
395 if (bytesRead > 0)
396 {
397 EVP_DigestUpdate(ctx, streamBuffer, static_cast<size_t>(bytesRead));
398 }
399 }
400
401 EVP_DigestFinal_ex(ctx, md_value, &md_len);
402 EVP_MD_CTX_destroy(ctx);
403 stream.clear();
404 stream.seekg(currentPos, stream.beg);
405
406 //Based64
407 char encodedData[100];
408 EVP_EncodeBlock(reinterpret_cast<unsigned char*>(encodedData), md_value, md_len);
409 return encodedData;
410 #endif
411 }
HexToString(const unsigned char * data,size_t size)412 static std::string HexToString(const unsigned char *data, size_t size)
413 {
414 static char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
415 std::stringstream ss;
416 for (size_t i = 0; i < size; i++)
417 ss << hex[(data[i] >> 4)] << hex[(data[i] & 0x0F)];
418 return ss.str();
419 }
420
ComputeContentETag(const std::string & data)421 std::string AlibabaCloud::OSS::ComputeContentETag(const std::string& data)
422 {
423 return ComputeContentETag(data.c_str(), data.size());
424 }
425
ComputeContentETag(const char * data,size_t size)426 std::string AlibabaCloud::OSS::ComputeContentETag(const char * data, size_t size)
427 {
428 if (!data) {
429 return "";
430 }
431 #if defined(USE_CRYPTO_MBEDTLS)
432 unsigned char md_data[16];
433
434 #if 0
435 mbedtls_md5_context ctx;
436
437 mbedtls_md5_init(&ctx);
438 mbedtls_md5_starts_ret(&ctx);
439 mbedtls_md5_update_ret(&ctx, (const unsigned char*)data, size);
440 mbedtls_md5_finish_ret(&ctx, md_data);
441 mbedtls_md5_free(&ctx);
442 #endif
443
444 mbedtls_md5_ret((const unsigned char*)data, size, md_data);
445
446 return HexToString(md_data, 16);
447
448 #elif 0//defined(USE_CRYPTO_MBEDTLS)
449 unsigned char md_data[16];
450
451 mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_MD5), data, size, md_data);
452
453 return HexToString(md_data, 16);
454 #else
455 unsigned char md[MD5_DIGEST_LENGTH];
456 MD5(reinterpret_cast<const unsigned char*>(data), size, (unsigned char*)&md);
457 return HexToString(md, MD5_DIGEST_LENGTH);
458 #endif
459 }
460
ComputeContentETag(std::istream & stream)461 std::string AlibabaCloud::OSS::ComputeContentETag(std::istream& stream)
462 {
463 #ifdef USE_CRYPTO_MBEDTLS
464 unsigned char md_value[16];
465 unsigned int md_len = 16;
466
467 mbedtls_md5_context ctx;
468
469 mbedtls_md5_init( &ctx);
470 mbedtls_md5_starts_ret(&ctx);
471
472 auto currentPos = stream.tellg();
473 if (currentPos == static_cast<std::streampos>(-1)) {
474 currentPos = 0;
475 stream.clear();
476 }
477 stream.seekg(0, stream.beg);
478 // TODO: ethan, need to shrink the buffer, or stack overflow may happen?
479 char streamBuffer[2048];
480 while (stream.good())
481 {
482 stream.read(streamBuffer, 2048);
483 auto bytesRead = stream.gcount();
484
485 if (bytesRead > 0)
486 {
487 mbedtls_md5_update_ret(&ctx, (const unsigned char*)streamBuffer, static_cast<size_t>(bytesRead));
488 }
489 }
490
491 mbedtls_md5_finish_ret(&ctx, md_value);
492 mbedtls_md5_free(&ctx);
493
494 stream.clear();
495 stream.seekg(currentPos, stream.beg);
496 return HexToString(md_value, md_len);
497 #else
498 auto ctx = EVP_MD_CTX_create();
499
500 unsigned char md_value[EVP_MAX_MD_SIZE];
501 unsigned int md_len = 0;
502
503 EVP_MD_CTX_init(ctx);
504 #ifndef OPENSSL_IS_BORINGSSL
505 EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
506 #endif
507
508 EVP_DigestInit_ex(ctx, EVP_md5(), nullptr);
509
510 auto currentPos = stream.tellg();
511 if (currentPos == static_cast<std::streampos>(-1)) {
512 currentPos = 0;
513 stream.clear();
514 }
515 stream.seekg(0, stream.beg);
516
517 char streamBuffer[2048];
518 while (stream.good())
519 {
520 stream.read(streamBuffer, 2048);
521 auto bytesRead = stream.gcount();
522
523 if (bytesRead > 0)
524 {
525 EVP_DigestUpdate(ctx, streamBuffer, static_cast<size_t>(bytesRead));
526 }
527 }
528
529 EVP_DigestFinal_ex(ctx, md_value, &md_len);
530 EVP_MD_CTX_destroy(ctx);
531 stream.clear();
532 stream.seekg(currentPos, stream.beg);
533 return HexToString(md_value, md_len);
534 #endif
535 }
536
537
StringReplace(std::string & src,const std::string & s1,const std::string & s2)538 void AlibabaCloud::OSS::StringReplace(std::string & src, const std::string & s1, const std::string & s2)
539 {
540 std::string::size_type pos =0;
541 while ((pos = src.find(s1, pos)) != std::string::npos)
542 {
543 src.replace(pos, s1.length(), s2);
544 pos += s2.length();
545 }
546 }
547
LeftTrim(const char * source)548 std::string AlibabaCloud::OSS::LeftTrim(const char* source)
549 {
550 std::string copy(source);
551 copy.erase(copy.begin(), std::find_if(copy.begin(), copy.end(), [](unsigned char ch) { return !::isspace(ch); }));
552 return copy;
553 }
554
RightTrim(const char * source)555 std::string AlibabaCloud::OSS::RightTrim(const char* source)
556 {
557 std::string copy(source);
558 copy.erase(std::find_if(copy.rbegin(), copy.rend(), [](unsigned char ch) { return !::isspace(ch); }).base(), copy.end());
559 return copy;
560 }
561
Trim(const char * source)562 std::string AlibabaCloud::OSS::Trim(const char* source)
563 {
564 return LeftTrim(RightTrim(source).c_str());
565 }
566
LeftTrimQuotes(const char * source)567 std::string AlibabaCloud::OSS::LeftTrimQuotes(const char* source)
568 {
569 std::string copy(source);
570 copy.erase(copy.begin(), std::find_if(copy.begin(), copy.end(), [](int ch) { return !(ch == '"'); }));
571 return copy;
572 }
573
RightTrimQuotes(const char * source)574 std::string AlibabaCloud::OSS::RightTrimQuotes(const char* source)
575 {
576 std::string copy(source);
577 copy.erase(std::find_if(copy.rbegin(), copy.rend(), [](int ch) { return !(ch == '"'); }).base(), copy.end());
578 return copy;
579 }
580
TrimQuotes(const char * source)581 std::string AlibabaCloud::OSS::TrimQuotes(const char* source)
582 {
583 return LeftTrimQuotes(RightTrimQuotes(source).c_str());
584 }
585
ToLower(const char * source)586 std::string AlibabaCloud::OSS::ToLower(const char* source)
587 {
588 std::string copy;
589 if (source) {
590 size_t srcLength = strlen(source);
591 copy.resize(srcLength);
592 std::transform(source, source + srcLength, copy.begin(), [](unsigned char c) { return (char)::tolower(c); });
593 }
594 return copy;
595 }
596
ToUpper(const char * source)597 std::string AlibabaCloud::OSS::ToUpper(const char* source)
598 {
599 std::string copy;
600 if (source) {
601 size_t srcLength = strlen(source);
602 copy.resize(srcLength);
603 std::transform(source, source + srcLength, copy.begin(), [](unsigned char c) { return (char)::toupper(c); });
604 }
605 return copy;
606 }
607
IsIp(const std::string & host)608 bool AlibabaCloud::OSS::IsIp(const std::string &host)
609 {
610 #if defined(__GNUG__) && __GNUC__ < 5
611 int n[4];
612 char c[4];
613 const char *p = host.c_str();
614 if (sscanf(p, "%d%c%d%c%d%c%d%c", &n[0], &c[0], &n[1], &c[1], &n[2], &c[2], &n[3], &c[3]) == 7)
615 {
616 int i;
617 for (i = 0; i < 3; ++i)
618 if (c[i] != '.')
619 return false;
620 for (i = 0; i < 4; ++i)
621 if (n[i] > 255 || n[i] < 0)
622 return false;
623 return true;
624 }
625 return false;
626 #else
627 return std::regex_match(host, ipPattern);
628 #endif
629 }
630
ToGmtTime(std::time_t & t)631 std::string AlibabaCloud::OSS::ToGmtTime(std::time_t &t)
632 {
633 std::stringstream date;
634 std::tm tm;
635 #ifdef _WIN32
636 ::gmtime_s(&tm, &t);
637 #else
638 ::gmtime_r(&t, &tm);
639 #endif
640
641 #if defined(__GNUG__) && __GNUC__ < 5
642 static const char wday_name[][4] = {
643 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
644 };
645 static const char mon_name[][4] = {
646 "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
647 };
648 char tmbuff[26];
649 snprintf(tmbuff, sizeof(tmbuff), "%.3s, %.2d %.3s %d %.2d:%.2d:%.2d",
650 wday_name[tm.tm_wday], tm.tm_mday, mon_name[tm.tm_mon],
651 1900 + tm.tm_year,
652 tm.tm_hour, tm.tm_min, tm.tm_sec);
653 date << tmbuff << " GMT";
654 #else
655 date.imbue(std::locale::classic());
656 date << std::put_time(&tm, "%a, %d %b %Y %H:%M:%S GMT");
657 #endif
658 return date.str();
659 }
660
ToUtcTime(std::time_t & t)661 std::string AlibabaCloud::OSS::ToUtcTime(std::time_t &t)
662 {
663 std::stringstream date;
664 std::tm tm;
665 #ifdef _WIN32
666 ::gmtime_s(&tm, &t);
667 #else
668 ::gmtime_r(&t, &tm);
669 #endif
670 #if defined(__GNUG__) && __GNUC__ < 5
671 char tmbuff[26];
672 strftime(tmbuff, 26, "%Y-%m-%dT%H:%M:%S.000Z", &tm);
673 date << tmbuff;
674 #else
675 date.imbue(std::locale::classic());
676 date << std::put_time(&tm, "%Y-%m-%dT%X.000Z");
677 #endif
678 return date.str();
679 }
680
UtcToUnixTime(const std::string & t)681 std::time_t AlibabaCloud::OSS::UtcToUnixTime(const std::string &t)
682 {
683 const char* date = t.c_str();
684 std::tm tm;
685 std::time_t tt = -1;
686 int ms;
687 auto result = sscanf(date, "%4d-%2d-%2dT%2d:%2d:%2d.%dZ",
688 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &ms);
689
690 if (result == 7) {
691 tm.tm_year = tm.tm_year - 1900;
692 tm.tm_mon = tm.tm_mon - 1;
693 #ifdef _WIN32
694 tt = _mkgmtime64(&tm);
695 #else
696 #if 0
697 tt = timegm(&tm);
698 #endif
699 #endif // _WIN32
700 }
701 return tt < 0 ? -1 : tt;
702 }
703
IsValidBucketName(const std::string & bucketName)704 bool AlibabaCloud::OSS::IsValidBucketName(const std::string &bucketName)
705 {
706 #if defined(__GNUG__) && __GNUC__ < 5
707 if (bucketName.size() < 3 || bucketName.size() > 63)
708 return false;
709 for (auto it = bucketName.begin(); it != bucketName.end(); it++) {
710 if (!((*it >= 'a' && *it <= 'z') || (*it >= '0' && *it <= '9') || *it == '-'))
711 return false;
712 }
713 if (*bucketName.begin() == '-' || *bucketName.rbegin() == '-')
714 return false;
715 return true;
716 #else
717 if (bucketName.empty())
718 return false;
719 return std::regex_match(bucketName, bucketNamePattern);
720 #endif
721 }
722
IsValidObjectKey(const std::string & key)723 bool AlibabaCloud::OSS::IsValidObjectKey(const std::string & key)
724 {
725 if (key.empty() || !key.compare(0, 1, "\\", 1))
726 return false;
727
728 return key.size() <= ObjectNameLengthLimit;
729 }
730
IsValidLoggingPrefix(const std::string & prefix)731 bool AlibabaCloud::OSS::IsValidLoggingPrefix(const std::string &prefix)
732 {
733 if (prefix.empty())
734 return true;
735 #if defined(__GNUG__) && __GNUC__ < 5
736 if (prefix.size() > 32)
737 return false;
738
739 auto ch = static_cast<int>(*prefix.begin());
740 if (isalpha(ch) == 0)
741 return false;
742
743 for (auto it = prefix.begin(); it != prefix.end(); it++) {
744 ch = static_cast<int>(*it);
745 if (!(::isalpha(ch) || ::isdigit(ch) || *it == '-'))
746 return false;
747 }
748 return true;
749 #else
750 return std::regex_match(prefix, loggingPrefixPattern);
751 #endif
752 }
753
IsValidChannelName(const std::string & channelName)754 bool AlibabaCloud::OSS::IsValidChannelName(const std::string &channelName)
755 {
756 if(channelName.empty() ||
757 std::string::npos != channelName.find('/') ||
758 channelName.size() > MaxLiveChannelNameLength)
759 return false;
760
761 return true;
762 }
763
IsValidPlayListName(const std::string & playlistName)764 bool AlibabaCloud::OSS::IsValidPlayListName(const std::string &playlistName)
765 {
766 if(playlistName.empty())
767 {
768 return false;
769 }else{
770 if(!IsValidObjectKey(playlistName))
771 {
772 return false;
773 }
774 if(playlistName.size() < MinLiveChannelPlayListLength ||
775 playlistName.size() > MaxLiveChannelPlayListLength)
776 {
777 return false;
778 }
779 std::size_t lastPos = playlistName.find_last_of('.');
780 std::size_t slashPos = playlistName.find('/');
781 if(lastPos == std::string::npos ||
782 slashPos != std::string::npos ||
783 0 == lastPos || '.' == playlistName[lastPos-1])
784 {
785 return false;
786 }else{
787 std::string suffix = playlistName.substr(lastPos);
788 if(suffix.size() < 5)
789 {
790 return false;
791 }
792 if(ToLower(suffix.c_str()) != ".m3u8")
793 {
794 return false;
795 }
796 return true;
797 }
798 }
799 }
800
IsValidTagKey(const std::string & key)801 bool AlibabaCloud::OSS::IsValidTagKey(const std::string &key)
802 {
803 if (key.empty() || key.size() > TagKeyLengthLimit)
804 return false;
805
806 return true;
807 }
808
IsValidTagValue(const std::string & value)809 bool AlibabaCloud::OSS::IsValidTagValue(const std::string &value)
810 {
811 return value.size() <= TagValueLengthLimit;
812 }
813
LookupMimeType(const std::string & name)814 const std::string& AlibabaCloud::OSS::LookupMimeType(const std::string &name)
815 {
816 const static std::map<std::string, std::string> mimeType = {
817 {"html", "text/html"},
818 {"htm", "text/html"},
819 {"shtml", "text/html"},
820 {"css", "text/css"},
821 {"xml", "text/xml"},
822 {"gif", "image/gif"},
823 {"jpeg", "image/jpeg"},
824 {"jpg", "image/jpeg"},
825 {"js", "application/x-javascript"},
826 {"atom", "application/atom+xml"},
827 {"rss", "application/rss+xml"},
828 {"mml", "text/mathml"},
829 {"txt", "text/plain"},
830 {"jad", "text/vnd.sun.j2me.app-descriptor"},
831 {"wml", "text/vnd.wap.wml"},
832 {"htc", "text/x-component"},
833 {"png", "image/png"},
834 {"tif", "image/tiff"},
835 {"tiff", "image/tiff"},
836 {"wbmp", "image/vnd.wap.wbmp"},
837 {"ico", "image/x-icon"},
838 {"jng", "image/x-jng"},
839 {"bmp", "image/x-ms-bmp"},
840 {"svg", "image/svg+xml"},
841 {"svgz", "image/svg+xml"},
842 {"webp", "image/webp"},
843 {"jar", "application/java-archive"},
844 {"war", "application/java-archive"},
845 {"ear", "application/java-archive"},
846 {"hqx", "application/mac-binhex40"},
847 {"doc ", "application/msword"},
848 {"pdf", "application/pdf"},
849 {"ps", "application/postscript"},
850 {"eps", "application/postscript"},
851 {"ai", "application/postscript"},
852 {"rtf", "application/rtf"},
853 {"xls", "application/vnd.ms-excel"},
854 {"ppt", "application/vnd.ms-powerpoint"},
855 {"wmlc", "application/vnd.wap.wmlc"},
856 {"kml", "application/vnd.google-earth.kml+xml"},
857 {"kmz", "application/vnd.google-earth.kmz"},
858 {"7z", "application/x-7z-compressed"},
859 {"cco", "application/x-cocoa"},
860 {"jardiff", "application/x-java-archive-diff"},
861 {"jnlp", "application/x-java-jnlp-file"},
862 {"run", "application/x-makeself"},
863 {"pl", "application/x-perl"},
864 {"pm", "application/x-perl"},
865 {"prc", "application/x-pilot"},
866 {"pdb", "application/x-pilot"},
867 {"rar", "application/x-rar-compressed"},
868 {"rpm", "application/x-redhat-package-manager"},
869 {"sea", "application/x-sea"},
870 {"swf", "application/x-shockwave-flash"},
871 {"sit", "application/x-stuffit"},
872 {"tcl", "application/x-tcl"},
873 {"tk", "application/x-tcl"},
874 {"der", "application/x-x509-ca-cert"},
875 {"pem", "application/x-x509-ca-cert"},
876 {"crt", "application/x-x509-ca-cert"},
877 {"xpi", "application/x-xpinstall"},
878 {"xhtml", "application/xhtml+xml"},
879 {"zip", "application/zip"},
880 {"wgz", "application/x-nokia-widget"},
881 {"bin", "application/octet-stream"},
882 {"exe", "application/octet-stream"},
883 {"dll", "application/octet-stream"},
884 {"deb", "application/octet-stream"},
885 {"dmg", "application/octet-stream"},
886 {"eot", "application/octet-stream"},
887 {"iso", "application/octet-stream"},
888 {"img", "application/octet-stream"},
889 {"msi", "application/octet-stream"},
890 {"msp", "application/octet-stream"},
891 {"msm", "application/octet-stream"},
892 {"mid", "audio/midi"},
893 {"midi", "audio/midi"},
894 {"kar", "audio/midi"},
895 {"mp3", "audio/mpeg"},
896 {"ogg", "audio/ogg"},
897 {"m4a", "audio/x-m4a"},
898 {"ra", "audio/x-realaudio"},
899 {"3gpp", "video/3gpp"},
900 {"3gp", "video/3gpp"},
901 {"mp4", "video/mp4"},
902 {"mpeg", "video/mpeg"},
903 {"mpg", "video/mpeg"},
904 {"mov", "video/quicktime"},
905 {"webm", "video/webm"},
906 {"flv", "video/x-flv"},
907 {"m4v", "video/x-m4v"},
908 {"mng", "video/x-mng"},
909 {"asx", "video/x-ms-asf"},
910 {"asf", "video/x-ms-asf"},
911 {"wmv", "video/x-ms-wmv"},
912 {"avi", "video/x-msvideo"},
913 {"ts", "video/MP2T"},
914 {"m3u8", "application/x-mpegURL"},
915 {"apk", "application/vnd.android.package-archive"}
916 };
917
918 const static std::string defaultType("application/octet-stream");
919 std::string::size_type last_pos = name.find_last_of('.');
920 std::string::size_type first_pos = name.find_first_of('.');
921 std::string prefix, ext, ext2;
922
923 if (last_pos == std::string::npos) {
924 return defaultType;
925 }
926
927 // extract the last extension
928 if (last_pos != std::string::npos) {
929 ext = name.substr(1 + last_pos, std::string::npos);
930 }
931 if (last_pos != std::string::npos) {
932 if (first_pos != std::string::npos && first_pos < last_pos) {
933 prefix = name.substr(0, last_pos);
934 // Now get the second to last file extension
935 std::string::size_type next_pos = prefix.find_last_of('.');
936 if (next_pos != std::string::npos) {
937 ext2 = prefix.substr(1 + next_pos, std::string::npos);
938 }
939 }
940 }
941
942 ext = ToLower(ext.c_str());
943 auto iter = mimeType.find(ext);
944 if (iter != mimeType.end()) {
945 return (*iter).second;
946 }
947
948 if (first_pos == last_pos) {
949 return defaultType;
950 }
951
952 ext2 = ToLower(ext2.c_str());
953 iter = mimeType.find(ext2);
954 if (iter != mimeType.end()) {
955 return (*iter).second;
956 }
957
958 return defaultType;
959 }
960
CombineHostString(const std::string & endpoint,const std::string & bucket,bool isCname)961 std::string AlibabaCloud::OSS::CombineHostString(
962 const std::string &endpoint,
963 const std::string &bucket,
964 bool isCname)
965 {
966 Url url(endpoint);
967 if (url.scheme().empty()) {
968 url.setScheme(Http::SchemeToString(Http::HTTP));
969 }
970
971 if (!bucket.empty() && !isCname && !IsIp(url.host())) {
972 std::string host(bucket);
973 host.append(".").append(url.host());
974 url.setHost(host);
975 }
976
977 std::ostringstream out;
978 out << url.scheme() << "://" << url.authority();
979 return out.str();
980 }
981
CombinePathString(const std::string & endpoint,const std::string & bucket,const std::string & key)982 std::string AlibabaCloud::OSS::CombinePathString(
983 const std::string &endpoint,
984 const std::string &bucket,
985 const std::string &key)
986 {
987 Url url(endpoint);
988 std::string path;
989 path = "/";
990 if (IsIp(url.host())) {
991 path.append(bucket).append("/");
992 }
993 path.append(UrlEncode(key));
994 return path;
995 }
996
CombineRTMPString(const std::string & endpoint,const std::string & bucket,bool isCname)997 std::string AlibabaCloud::OSS::CombineRTMPString(
998 const std::string &endpoint,
999 const std::string &bucket,
1000 bool isCname)
1001 {
1002 Url url(endpoint);
1003 if (!bucket.empty() && !isCname && !IsIp(url.host())) {
1004 std::string host(bucket);
1005 host.append(".").append(url.host());
1006 url.setHost(host);
1007 }
1008
1009 std::ostringstream out;
1010 out << "rtmp://" << url.authority();
1011 return out.str();
1012 }
1013
CombineQueryString(const ParameterCollection & parameters)1014 std::string AlibabaCloud::OSS::CombineQueryString(const ParameterCollection ¶meters)
1015 {
1016 std::stringstream ss;
1017 if (!parameters.empty()) {
1018 for (const auto &p : parameters)
1019 {
1020 if (p.second.empty())
1021 ss << "&" << UrlEncode(p.first);
1022 else
1023 ss << "&" << UrlEncode(p.first) << "=" << UrlEncode(p.second);
1024 }
1025 }
1026 return ss.str().substr(1);
1027 }
1028
GetIOStreamLength(std::iostream & stream)1029 std::streampos AlibabaCloud::OSS::GetIOStreamLength(std::iostream &stream)
1030 {
1031 auto currentPos = stream.tellg();
1032 if (currentPos == static_cast<std::streampos>(-1)) {
1033 currentPos = 0;
1034 stream.clear();
1035 }
1036 stream.seekg(0, stream.end);
1037 auto streamSize = stream.tellg();
1038 stream.seekg(currentPos, stream.beg);
1039 return streamSize;
1040 }
1041
ToStorageClassName(StorageClass storageClass)1042 const char *AlibabaCloud::OSS::ToStorageClassName(StorageClass storageClass)
1043 {
1044 static const char *StorageClassName[] = { "Standard", "IA", "Archive", "ColdArchive" };
1045 return StorageClassName[storageClass - StorageClass::Standard];
1046 }
1047
ToStorageClassType(const char * name)1048 StorageClass AlibabaCloud::OSS::ToStorageClassType(const char *name)
1049 {
1050 std::string storageName = ToLower(name);
1051 if(!storageName.compare("ia")) return StorageClass::IA;
1052 else if (!storageName.compare("archive")) return StorageClass::Archive;
1053 else if (!storageName.compare("coldarchive")) return StorageClass::ColdArchive;
1054 else return StorageClass::Standard;
1055 }
1056
ToAclName(CannedAccessControlList acl)1057 const char *AlibabaCloud::OSS::ToAclName(CannedAccessControlList acl)
1058 {
1059 static const char *AclName[] = { "private", "public-read", "public-read-write", "default"};
1060 return AclName[acl - CannedAccessControlList::Private];
1061 }
1062
ToAclType(const char * name)1063 CannedAccessControlList AlibabaCloud::OSS::ToAclType(const char *name)
1064 {
1065 std::string aclName = ToLower(name);
1066 if (!aclName.compare("private")) return CannedAccessControlList::Private;
1067 else if (!aclName.compare("public-read")) return CannedAccessControlList::PublicRead;
1068 else if (!aclName.compare("public-read-write")) return CannedAccessControlList::PublicReadWrite;
1069 else return CannedAccessControlList::Default;
1070 }
1071
ToCopyActionName(CopyActionList action)1072 const char *AlibabaCloud::OSS::ToCopyActionName(CopyActionList action)
1073 {
1074 static const char *ActionName[] = { "COPY", "REPLACE"};
1075 return ActionName[action - CopyActionList::Copy];
1076 }
1077
ToRuleStatusName(RuleStatus status)1078 const char *AlibabaCloud::OSS::ToRuleStatusName(RuleStatus status)
1079 {
1080 static const char *StatusName[] = { "Enabled", "Disabled" };
1081 return StatusName[status - RuleStatus::Enabled];
1082 }
1083
ToRuleStatusType(const char * name)1084 RuleStatus AlibabaCloud::OSS::ToRuleStatusType(const char *name)
1085 {
1086 std::string statusName = ToLower(name);
1087 if (!statusName.compare("enabled")) return RuleStatus::Enabled;
1088 else return RuleStatus::Disabled;
1089 }
1090
ToLiveChannelStatusName(LiveChannelStatus status)1091 const char *AlibabaCloud::OSS::ToLiveChannelStatusName(LiveChannelStatus status)
1092 {
1093 if(status > LiveChannelStatus::LiveStatus)
1094 return "";
1095
1096 static const char *StatusName[] = { "enabled", "disabled", "idle", "live" };
1097 return StatusName[status - LiveChannelStatus::EnabledStatus];
1098 }
1099
ToLiveChannelStatusType(const char * name)1100 LiveChannelStatus AlibabaCloud::OSS::ToLiveChannelStatusType(const char *name)
1101 {
1102 std::string statusName = ToLower(name);
1103 if (!statusName.compare("enabled")) return LiveChannelStatus::EnabledStatus;
1104 else if (!statusName.compare("disabled")) return LiveChannelStatus::DisabledStatus;
1105 else if (!statusName.compare("idle")) return LiveChannelStatus::IdleStatus;
1106 else if (!statusName.compare("live")) return LiveChannelStatus::LiveStatus;
1107 else return LiveChannelStatus::UnknownStatus;
1108 }
1109
ToRequestPayerName(RequestPayer payer)1110 const char* AlibabaCloud::OSS::ToRequestPayerName(RequestPayer payer)
1111 {
1112 static const char* PayerName[] = { "NotSet", "BucketOwner", "Requester"};
1113 return PayerName[static_cast<int>(payer) - static_cast<int>(RequestPayer::NotSet)];
1114 }
1115
ToRequestPayer(const char * name)1116 RequestPayer AlibabaCloud::OSS::ToRequestPayer(const char* name)
1117 {
1118 std::string statusName = ToLower(name);
1119 if (!statusName.compare("bucketowner")) return RequestPayer::BucketOwner;
1120 else if (!statusName.compare("requester")) return RequestPayer::Requester;
1121 else return RequestPayer::NotSet;
1122 }
1123
ToSSEAlgorithmName(SSEAlgorithm sse)1124 const char* AlibabaCloud::OSS::ToSSEAlgorithmName(SSEAlgorithm sse)
1125 {
1126 static const char* StatusName[] = { "NotSet", "KMS", "AES256" };
1127 return StatusName[static_cast<int>(sse) - static_cast<int>(SSEAlgorithm::NotSet)];
1128 }
1129
ToSSEAlgorithm(const char * name)1130 SSEAlgorithm AlibabaCloud::OSS::ToSSEAlgorithm(const char* name)
1131 {
1132 std::string statusName = ToLower(name);
1133 if (!statusName.compare("kms")) return SSEAlgorithm::KMS;
1134 else if (!statusName.compare("aes256")) return SSEAlgorithm::AES256;
1135 else return SSEAlgorithm::NotSet;
1136 }
1137
ToDataRedundancyType(const char * name)1138 DataRedundancyType AlibabaCloud::OSS::ToDataRedundancyType(const char* name)
1139 {
1140 std::string storageName = ToLower(name);
1141 if (!storageName.compare("lrs")) return DataRedundancyType::LRS;
1142 else if (!storageName.compare("zrs")) return DataRedundancyType::ZRS;
1143 else return DataRedundancyType::NotSet;
1144 }
1145
ToDataRedundancyTypeName(DataRedundancyType type)1146 const char* AlibabaCloud::OSS::ToDataRedundancyTypeName(DataRedundancyType type)
1147 {
1148 static const char* typeName[] = { "NotSet", "LRS", "ZRS" };
1149 return typeName[static_cast<int>(type) - static_cast<int>(DataRedundancyType::NotSet)];
1150 }
1151
ToVersioningStatusName(VersioningStatus status)1152 const char * AlibabaCloud::OSS::ToVersioningStatusName(VersioningStatus status)
1153 {
1154 static const char *StatusName[] = { "NotSet", "Enabled", "Suspended" };
1155 return StatusName[static_cast<int>(status) - static_cast<int>(VersioningStatus::NotSet)];
1156 }
1157
ToVersioningStatusType(const char * name)1158 VersioningStatus AlibabaCloud::OSS::ToVersioningStatusType(const char *name)
1159 {
1160 std::string statusName = ToLower(name);
1161 if (!statusName.compare("enabled")) return VersioningStatus::Enabled;
1162 else if (!statusName.compare("suspended")) return VersioningStatus::Suspended;
1163 else return VersioningStatus::NotSet;
1164 }
1165
ToInventoryFormatName(InventoryFormat status)1166 const char* AlibabaCloud::OSS::ToInventoryFormatName(InventoryFormat status)
1167 {
1168 static const char* StatusName[] = { "NotSet", "CSV"};
1169 return StatusName[static_cast<int>(status) - static_cast<int>(InventoryFormat::NotSet)];
1170 }
1171
ToInventoryFormatType(const char * name)1172 InventoryFormat AlibabaCloud::OSS::ToInventoryFormatType(const char* name)
1173 {
1174 std::string statusName = ToLower(name);
1175 if (!statusName.compare("csv")) return InventoryFormat::CSV;
1176 else return InventoryFormat::NotSet;
1177 }
1178
ToInventoryFrequencyName(InventoryFrequency status)1179 const char* AlibabaCloud::OSS::ToInventoryFrequencyName(InventoryFrequency status)
1180 {
1181 static const char* StatusName[] = { "NotSet", "Daily", "Weekly" };
1182 return StatusName[static_cast<int>(status) - static_cast<int>(InventoryFrequency::NotSet)];
1183 }
1184
ToInventoryFrequencyType(const char * name)1185 InventoryFrequency AlibabaCloud::OSS::ToInventoryFrequencyType(const char* name)
1186 {
1187 std::string statusName = ToLower(name);
1188 if (!statusName.compare("daily")) return InventoryFrequency::Daily;
1189 else if (!statusName.compare("weekly")) return InventoryFrequency::Weekly;
1190 else return InventoryFrequency::NotSet;
1191 }
1192
ToInventoryOptionalFieldName(InventoryOptionalField status)1193 const char* AlibabaCloud::OSS::ToInventoryOptionalFieldName(InventoryOptionalField status)
1194 {
1195 static const char* StatusName[] = { "NotSet", "Size", "LastModifiedDate", "ETag", "StorageClass", "IsMultipartUploaded", "EncryptionStatus" };
1196 return StatusName[static_cast<int>(status) - static_cast<int>(InventoryOptionalField::NotSet)];
1197 }
1198
ToInventoryOptionalFieldType(const char * name)1199 InventoryOptionalField AlibabaCloud::OSS::ToInventoryOptionalFieldType(const char* name)
1200 {
1201 std::string statusName = ToLower(name);
1202 if (!statusName.compare("size")) return InventoryOptionalField::Size;
1203 else if (!statusName.compare("lastmodifieddate")) return InventoryOptionalField::LastModifiedDate;
1204 else if (!statusName.compare("etag")) return InventoryOptionalField::ETag;
1205 else if (!statusName.compare("storageclass")) return InventoryOptionalField::StorageClass;
1206 else if (!statusName.compare("ismultipartuploaded")) return InventoryOptionalField::IsMultipartUploaded;
1207 else if (!statusName.compare("encryptionstatus")) return InventoryOptionalField::EncryptionStatus;
1208 else return InventoryOptionalField::NotSet;
1209 }
1210
ToInventoryIncludedObjectVersionsName(InventoryIncludedObjectVersions status)1211 const char* AlibabaCloud::OSS::ToInventoryIncludedObjectVersionsName(InventoryIncludedObjectVersions status)
1212 {
1213 static const char* StatusName[] = { "NotSet", "All", "Current" };
1214 return StatusName[static_cast<int>(status) - static_cast<int>(InventoryIncludedObjectVersions::NotSet)];
1215 }
1216
ToInventoryIncludedObjectVersionsType(const char * name)1217 InventoryIncludedObjectVersions AlibabaCloud::OSS::ToInventoryIncludedObjectVersionsType(const char* name)
1218 {
1219 std::string statusName = ToLower(name);
1220 if (!statusName.compare("all")) return InventoryIncludedObjectVersions::All;
1221 else if (!statusName.compare("current")) return InventoryIncludedObjectVersions::Current;
1222 else return InventoryIncludedObjectVersions::NotSet;
1223 }
1224
ToInventoryBucketFullName(const std::string & name)1225 std::string AlibabaCloud::OSS::ToInventoryBucketFullName(const std::string& name)
1226 {
1227 std::string fullName = "acs:oss:::";
1228 return fullName.append(name);
1229 }
1230
ToInventoryBucketShortName(const char * name)1231 std::string AlibabaCloud::OSS::ToInventoryBucketShortName(const char* name)
1232 {
1233 std::string name_ = ToLower(name);
1234 std::string shortName;
1235
1236 if (!name_.compare(0, 10, "acs:oss:::")) {
1237 shortName.append(name + 10);
1238 }
1239 return shortName;
1240 }
1241
ToTierTypeName(TierType status)1242 const char * AlibabaCloud::OSS::ToTierTypeName(TierType status)
1243 {
1244 static const char *StatusName[] = { "Expedited", "Standard", "Bulk" };
1245 return StatusName[static_cast<int>(status) - static_cast<int>(TierType::Expedited)];
1246 }
1247
ToTierType(const char * name)1248 TierType AlibabaCloud::OSS::ToTierType(const char *name)
1249 {
1250 std::string statusName = ToLower(name);
1251 if (!statusName.compare("expedited")) return TierType::Expedited;
1252 else if (!statusName.compare("bulk")) return TierType::Bulk;
1253 else return TierType::Standard;
1254 }
1255
1256 #if !defined(OSS_DISABLE_RESUAMABLE) || !defined(OSS_DISABLE_ENCRYPTION)
JsonStringToMap(const std::string & jsonStr)1257 std::map<std::string, std::string> AlibabaCloud::OSS::JsonStringToMap(const std::string& jsonStr)
1258 {
1259 std::map<std::string, std::string> valueMap;
1260 Json::Value root;
1261 Json::CharReaderBuilder rbuilder;
1262 std::stringstream input(jsonStr);
1263 std::string errMsg;
1264
1265 if (Json::parseFromStream(rbuilder, input, &root, &errMsg)) {
1266
1267 for (auto it = root.begin(); it != root.end(); ++it)
1268 {
1269 valueMap[it.key().asString()] = (*it).asString();
1270 }
1271 }
1272
1273 return valueMap;
1274 }
1275
MapToJsonString(const std::map<std::string,std::string> & map)1276 std::string AlibabaCloud::OSS::MapToJsonString(const std::map<std::string, std::string>& map)
1277 {
1278 if (map.empty()) {
1279 return "";
1280 }
1281 Json::Value root;
1282 for (const auto& it : map) {
1283 root[it.first] = it.second;
1284 }
1285
1286 Json::StreamWriterBuilder builder;
1287 builder["indentation"] = "";
1288 return Json::writeString(builder, root);
1289 }
1290 #endif
1291