Quick.Amazon.pas 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. { ***************************************************************************
  2. Copyright (c) 2015-2018 Kike Pérez
  3. Unit : Quick.Amazon
  4. Description : Amazon object operations
  5. Author : Kike Pérez
  6. Version : 1.4
  7. Created : 18/11/2016
  8. Modified : 21/02/2018
  9. This file is part of QuickLib: https://github.com/exilon/QuickLib
  10. ***************************************************************************
  11. Licensed under the Apache License, Version 2.0 (the "License");
  12. you may not use this file except in compliance with the License.
  13. You may obtain a copy of the License at
  14. http://www.apache.org/licenses/LICENSE-2.0
  15. Unless required by applicable law or agreed to in writing, software
  16. distributed under the License is distributed on an "AS IS" BASIS,
  17. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. See the License for the specific language governing permissions and
  19. limitations under the License.
  20. *************************************************************************** }
  21. unit Quick.Amazon;
  22. interface
  23. uses
  24. Classes,
  25. System.SysUtils,
  26. System.Generics.Collections,
  27. IPPeerClient,
  28. Data.Cloud.CloudAPI,
  29. Data.Cloud.AmazonAPI;
  30. const
  31. AWSRegionSet : array of string = [
  32. 'eu-west-1',
  33. 'eu-west-1',
  34. 'eu-central-1',
  35. 'us-east-1',
  36. 'us-west-1',
  37. 'us-west-2',
  38. 'ap-southeast-1',
  39. 'ap-southeast-2',
  40. 'ap-northeast-1',
  41. 'ap-northeast-2',
  42. 'sa-east-1',
  43. 'us-east-1', // deprecate
  44. 'us-east-1','us-east-1'];
  45. type
  46. TAmazonProtocol = (amHTTP,amHTTPS);
  47. TAmazonStorage = TAmazonStorageService;
  48. TAmazonACLAccess = TAmazonACLType;
  49. TAmazonRegion = Data.Cloud.AmazonAPI.TAmazonRegion;
  50. TAmazonObject = class
  51. Name : string;
  52. Modified : TDateTime;
  53. Size : Int64;
  54. IsDeleted : Boolean;
  55. end;
  56. TAmazonObjects = class(TObjectList<TAmazonObject>);
  57. TAmazonResponseInfo = record
  58. StatusCode : Integer;
  59. StatusMsg : string;
  60. end;
  61. TQuickAmazon = class
  62. private
  63. fconAmazon : TAmazonConnectionInfo;
  64. fAccountName : string;
  65. fAccountKey : string;
  66. fAWSRegion : TAmazonRegion;
  67. fAmazonProtocol : TAmazonProtocol;
  68. procedure SetAccountName(amAccountName : string);
  69. procedure SetAccountKey(amAccountKey : string);
  70. procedure SetAmazonProtocol(amProtocol : TAmazonProtocol);
  71. procedure SetAWSRegion(Value : TAmazonRegion);
  72. function FileToArray(cFilename : string) : TArray<Byte>;
  73. function StreamToArray(cStream : TStream) : TArray<Byte>;
  74. public
  75. constructor Create; overload;
  76. constructor Create(amAccountName, amAccountKey : string); overload;
  77. destructor Destroy; override;
  78. property AccountName : string read fAccountName write SetAccountName;
  79. property AccountKey : string read fAccountKey write SetAccountKey;
  80. property AmazonProtocol : TAmazonProtocol read fAmazonProtocol write SetAmazonProtocol;
  81. property AWSRegion : TAmazonRegion read fAWSRegion write SetAWSRegion;
  82. function StorageURL(amBucket : string) : string;
  83. function PutObject(amBucket, cFilename, amObjectName : string; amACLType : TAmazonACLType; var amResponseInfo : TAmazonResponseInfo) : Boolean; overload;
  84. function PutObject(amBucket : string; cStream : TStream; amObjectName : string; amACLType : TAmazonACLType; var amResponseInfo : TAmazonResponseInfo) : Boolean; overload;
  85. function GetObject(amBucket, amObjectName, cFilenameTo : string; var amResponseInfo : TAmazonResponseInfo) : Boolean; overload;
  86. function GetObject(amBucket, amObjectName : string; var amResponseInfo : TAmazonResponseInfo) : TMemoryStream; overload;
  87. function ExistsObject(amBucket, amObjectName : string; amRegion : TAmazonRegion) : Boolean;
  88. function DeleteObject(amBucket,amObjectName : string; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  89. function ListObjects(amBucket : string; amObjectsStartWith : string; amRegion : TAmazonRegion; var amResponseInfo : TAmazonResponseInfo) : TAmazonObjects;
  90. function ListObjectsNames(amBucket : string; amObjectsStartWith : string; amRegion : TAmazonRegion; var amResponseInfo : TAmazonResponseInfo) : TStrings;
  91. function ExistsBucket(amBucketName : string) : Boolean;
  92. function ListBuckets(var amResponseInfo : TAmazonResponseInfo) : TStrings;
  93. function CreateBucket(amBucket : string; amBucketRegion : TAmazonRegion; amACLType : TAmazonACLAccess; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  94. function DeleteBucket(amBucket : string; amBucketRegion : TAmazonRegion; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  95. class function GetAWSRegion(Region: TAmazonRegion): string; overload;
  96. class function GetAWSRegion(const Region : string) : TAmazonRegion; overload;
  97. end;
  98. implementation
  99. constructor TQuickAmazon.Create;
  100. begin
  101. inherited;
  102. fconAmazon := TAmazonConnectionInfo.Create(nil);
  103. fAmazonProtocol := amHTTP;
  104. fconAmazon.UseDefaultEndpoints := False;
  105. end;
  106. constructor TQuickAmazon.Create(amAccountName, amAccountKey : string);
  107. begin
  108. Create;
  109. SetAccountName(amAccountName);
  110. SetAccountKey(amAccountKey);
  111. end;
  112. destructor TQuickAmazon.Destroy;
  113. begin
  114. if Assigned(fconAmazon) then fconAmazon.Free;
  115. inherited;
  116. end;
  117. procedure TQuickAmazon.SetAWSRegion(Value : TAmazonRegion);
  118. begin
  119. fAWSRegion := Value;
  120. fconAmazon.StorageEndpoint := Format('s3-%s.amazonaws.com',[GetAWSRegion(Value)]);
  121. end;
  122. procedure TQuickAmazon.SetAccountName(amAccountName : string);
  123. begin
  124. if fAccountName <> amAccountName then
  125. begin
  126. fAccountName := amAccountName;
  127. fconAmazon.AccountName := amAccountName;
  128. end;
  129. end;
  130. procedure TQuickAmazon.SetAccountKey(amAccountKey : string);
  131. begin
  132. if fAccountKey <> amAccountKey then
  133. begin
  134. fAccountKey := amAccountKey ;
  135. fconAmazon.AccountKey := amAccountKey;
  136. end;
  137. end;
  138. procedure TQuickAmazon.SetAmazonProtocol(amProtocol: TAmazonProtocol);
  139. begin
  140. if fAmazonProtocol <> amProtocol then
  141. begin
  142. fAmazonProtocol := amProtocol;
  143. if amProtocol = amHTTP then fconAmazon.Protocol := 'http'
  144. else fconAmazon.Protocol := 'https';
  145. end;
  146. end;
  147. function TQuickAmazon.FileToArray(cFilename : string) : TArray<Byte>;
  148. var
  149. fs : TFileStream;
  150. bs : TBytesStream;
  151. begin
  152. fs := TFileStream.Create(cFilename, fmOpenRead);
  153. try
  154. bs := TBytesStream.Create(Result);
  155. try
  156. bs.LoadFromStream(fs);
  157. Result := bs.Bytes;
  158. finally
  159. bs.Free
  160. end;
  161. finally
  162. fs.Free;
  163. end;
  164. end;
  165. function TQuickAmazon.StreamToArray(cStream : TStream) : TArray<Byte>;
  166. var
  167. bs : TBytesStream;
  168. begin
  169. bs := TBytesStream.Create(Result);
  170. try
  171. bs.LoadFromStream(cStream);
  172. Result := bs.Bytes;
  173. finally
  174. bs.Free
  175. end;
  176. end;
  177. {function TQuickAmazon.StreamToArray(cStream : TStream) : TArray<Byte>;
  178. begin
  179. SetLength(Result,cStream.Size);
  180. cStream.WriteData(Result,Length(Result));
  181. end;}
  182. function GetResponseInfo(amResponseInfo : TCloudResponseInfo) : TAmazonResponseInfo;
  183. begin
  184. Result.StatusCode := amResponseInfo.StatusCode;
  185. Result.StatusMsg := amResponseInfo.StatusMessage;
  186. end;
  187. function TQuickAmazon.StorageURL(amBucket : string) : string;
  188. begin
  189. Result := fconAmazon.StorageURL(amBucket)
  190. end;
  191. function TQuickAmazon.PutObject(amBucket, cFilename, amObjectName : string; amACLType : TAmazonACLType; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  192. var
  193. AmazonS3 : TAmazonStorage;
  194. Content : TArray<Byte>;
  195. CloudResponseInfo : TCloudResponseInfo;
  196. begin
  197. Result := False;
  198. AmazonS3 := TAmazonStorage.Create(fconAmazon);
  199. if amBucket = '' then amBucket := '$root';
  200. CloudResponseInfo := TCloudResponseInfo.Create;
  201. try
  202. Content := FileToArray(cFilename);
  203. if amObjectName = '' then amObjectName := cFilename;
  204. if amObjectName.StartsWith('/') then amObjectName := Copy(amObjectName,2,Length(amObjectName));
  205. Result := AmazonS3.UploadObject(amBucket,amObjectName,Content,False,nil,nil,amACLType,CloudResponseInfo);
  206. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  207. finally
  208. AmazonS3.Free;
  209. CloudResponseInfo.Free;
  210. end;
  211. end;
  212. function TQuickAmazon.PutObject(amBucket : string; cStream : TStream; amObjectName : string; amACLType : TAmazonACLType; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  213. var
  214. AmazonS3 : TAmazonStorage;
  215. Content : TArray<Byte>;
  216. CloudResponseInfo : TCloudResponseInfo;
  217. begin
  218. amResponseInfo.StatusCode := 500;
  219. if amBucket = '' then amBucket := '$root';
  220. if amObjectName.StartsWith('/') then amObjectName := Copy(amObjectName,2,Length(amObjectName));
  221. try
  222. AmazonS3 := TAmazonStorage.Create(fconAmazon);
  223. try
  224. //AmazonS3.Timeout := fTimeout;
  225. CloudResponseInfo := TCloudResponseInfo.Create;
  226. //CloudResponseInfo.Headers.AddPair();
  227. Content := StreamToArray(cStream);
  228. Result := AmazonS3.UploadObject(amBucket,amObjectName,Content,False,nil,nil,amACLType,CloudResponseInfo);
  229. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  230. finally
  231. AmazonS3.Free;
  232. CloudResponseInfo.Free;
  233. SetLength(Content,0);
  234. Content := nil;
  235. end;
  236. except
  237. Result := False;
  238. end;
  239. end;
  240. function TQuickAmazon.GetObject(amBucket, amObjectName, cFilenameTo : string; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  241. var
  242. AmazonS3 : TAmazonStorage;
  243. fs : TFileStream;
  244. CloudResponseInfo : TCloudResponseInfo;
  245. amParams : TAmazonGetObjectOptionals;
  246. begin
  247. Result := False;
  248. if amBucket = '' then amBucket := '$root';
  249. if amObjectName.StartsWith('/') then amObjectName := Copy(amObjectName,2,Length(amObjectName));
  250. AmazonS3 := TAmazonStorage.Create(fconAmazon);
  251. try
  252. //AmazonS3.Timeout := fTimeout;
  253. CloudResponseInfo := TCloudResponseInfo.Create;
  254. if FileExists(cFilenameTo) then fs := TFileStream.Create(cFilenameTo,fmOpenWrite)
  255. else fs := TFileStream.Create(cFilenameTo,fmCreate);
  256. try
  257. try
  258. AmazonS3.GetObject(amBucket,amObjectName,fs,CloudResponseInfo);
  259. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  260. if amResponseInfo.StatusCode = 200 then Result := True;
  261. except
  262. Result := False;
  263. end;
  264. finally
  265. fs.Free;
  266. CloudResponseInfo.Free;
  267. end;
  268. finally
  269. AmazonS3.Free;
  270. end;
  271. end;
  272. function TQuickAmazon.GetObject(amBucket, amObjectName : string; var amResponseInfo : TAmazonResponseInfo) : TMemoryStream;
  273. var
  274. AmazonS3 : TAmazonStorage;
  275. fs : TFileStream;
  276. CloudResponseInfo : TCloudResponseInfo;
  277. begin
  278. Result := TMemoryStream.Create;
  279. if amBucket = '' then amBucket := '$root';
  280. if amObjectName.StartsWith('/') then amObjectName := Copy(amObjectName,2,Length(amObjectName));
  281. AmazonS3 := TAmazonStorage.Create(fconAmazon);
  282. try
  283. //AmazonS3.Timeout := fTimeout;
  284. CloudResponseInfo := TCloudResponseInfo.Create;
  285. try
  286. AmazonS3.GetObject(amBucket,amObjectName,Result,CloudResponseInfo);
  287. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  288. except
  289. Result := nil;
  290. end;
  291. finally
  292. AmazonS3.Free;
  293. CloudResponseInfo.Free;
  294. end;
  295. end;
  296. function TQuickAmazon.ExistsObject(amBucket, amObjectName : string; amRegion : TAmazonRegion) : Boolean;
  297. var
  298. amObject : string;
  299. amObjects : TStrings;
  300. ResponseInfo : TAmazonResponseInfo;
  301. begin
  302. Result := False;
  303. amObjects := ListObjectsNames(amBucket,amObjectName,amRegion,ResponseInfo);
  304. try
  305. if (ResponseInfo.StatusCode = 200) and (Assigned(amObjects)) then
  306. begin
  307. for amObject in amObjects do
  308. begin
  309. if amObject = amObjectName then
  310. begin
  311. Result := True;
  312. Break;
  313. end;
  314. end;
  315. end;
  316. finally
  317. amObjects.Free;
  318. end;
  319. end;
  320. function TQuickAmazon.DeleteObject(amBucket,amObjectName : string; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  321. var
  322. AmazonS3 : TAmazonStorage;
  323. CloudResponseInfo : TCloudResponseInfo;
  324. begin
  325. Result := False;
  326. if amBucket = '' then amBucket := '$root';
  327. if amObjectName.StartsWith('/') then amObjectName := Copy(amObjectName,2,Length(amObjectName));
  328. AmazonS3 := TAmazonStorage.Create(fconAmazon);
  329. try
  330. //AmazonS3.Timeout := fTimeout;
  331. CloudResponseInfo := TCloudResponseInfo.Create;
  332. Result := AmazonS3.DeleteObject(amBucket,amObjectName,CloudResponseInfo);
  333. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  334. finally
  335. AmazonS3.Free;
  336. CloudResponseInfo.Free;
  337. end;
  338. end;
  339. function TQuickAmazon.ListObjects(amBucket : string; amObjectsStartWith : string; amRegion : TAmazonRegion; var amResponseInfo : TAmazonResponseInfo) : TAmazonObjects;
  340. var
  341. AmazonS3 : TAmazonStorage;
  342. amObject : TAmazonObject;
  343. i : Integer;
  344. amBucketResult : TAmazonBucketResult;
  345. CloudResponseInfo : TCloudResponseInfo;
  346. cNextMarker : string;
  347. amParams : TStrings;
  348. a : TAmazonBucketResult;
  349. begin
  350. Result := TAmazonObjects.Create(True);
  351. cNextMarker := '';
  352. if amBucket = '' then amBucket := '$root';
  353. AmazonS3 := TAmazonStorage.Create(fconAmazon);
  354. CloudResponseInfo := TCloudResponseInfo.Create;
  355. try
  356. //AmazonS3.Timeout := fTimeout;
  357. repeat
  358. amParams := TStringList.Create;
  359. try
  360. amParams.Values['prefix'] := amObjectsStartWith;
  361. if cNextMarker <> '' then amParams.Values['marker'] := cNextMarker;
  362. amBucketResult := AmazonS3.GetBucket(amBucket,amParams,CloudResponseInfo,amRegion);
  363. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  364. if Assigned(amBucketResult) then
  365. begin
  366. try
  367. Result.Capacity := amBucketResult.Objects.Count;
  368. for i := 0 to amBucketResult.Objects.Count-1 do
  369. begin
  370. amObject := TAmazonObject.Create;
  371. amObject.Name := amBucketResult.Objects[i].Name;
  372. amObject.Modified := StrToDateTime(amBucketResult.Objects[i].LastModified);
  373. amObject.Size := amBucketResult.Objects[i].Size;
  374. amObject.IsDeleted := amBucketResult.Objects[i].IsDeleted;
  375. Result.Add(amObject);
  376. end;
  377. finally
  378. amBucketResult.Free;
  379. end;
  380. cNextMarker := amBucketResult.Marker;
  381. end;
  382. finally
  383. amParams.Free;
  384. end;
  385. until (cNextMarker = '') or (amResponseInfo.StatusCode <> 200);
  386. finally
  387. AmazonS3.Free;
  388. CloudResponseInfo.Free;
  389. end;
  390. end;
  391. function TQuickAmazon.ListObjectsNames(amBucket : string; amObjectsStartWith : string; amRegion : TAmazonRegion; var amResponseInfo : TAmazonResponseInfo) : TStrings;
  392. var
  393. AmazonS3 : TAmazonStorage;
  394. i : Integer;
  395. amBucketResult : TAmazonBucketResult;
  396. CloudResponseInfo : TCloudResponseInfo;
  397. cNextMarker : string;
  398. amParams : TStrings;
  399. a : TAmazonBucketResult;
  400. begin
  401. Result := TStringList.Create;
  402. cNextMarker := '';
  403. if amBucket = '' then amBucket := '$root';
  404. AmazonS3 := TAmazonStorage.Create(fconAmazon);
  405. CloudResponseInfo := TCloudResponseInfo.Create;
  406. try
  407. //AmazonS3.Timeout := fTimeout;
  408. repeat
  409. amParams := TStringList.Create;
  410. try
  411. if amObjectsStartWith <> '' then amParams.Values['prefix'] := amObjectsStartWith;
  412. if cNextMarker <> '' then amParams.Values['marker'] := cNextMarker;
  413. amBucketResult := AmazonS3.GetBucket(amBucket,amParams,CloudResponseInfo,amRegion);
  414. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  415. if Assigned(amBucketResult) then
  416. begin
  417. try
  418. Result.Capacity := amBucketResult.Objects.Count;
  419. for i := 0 to amBucketResult.Objects.Count-1 do Result.Add(amBucketResult.Objects[i].Name);
  420. finally
  421. amBucketResult.Free;
  422. end;
  423. cNextMarker := amBucketResult.Marker;
  424. end;
  425. finally
  426. amParams.Free;
  427. end;
  428. until (cNextMarker = '') or (amResponseInfo.StatusCode <> 200);
  429. finally
  430. AmazonS3.Free;
  431. CloudResponseInfo.Free;
  432. end;
  433. end;
  434. function TQuickAmazon.ExistsBucket(amBucketName : string) : Boolean;
  435. var
  436. amBucket : string;
  437. amBuckets : TStrings;
  438. ResponseInfo : TAmazonResponseInfo;
  439. begin
  440. Result := False;
  441. amBuckets := ListBuckets(ResponseInfo);
  442. try
  443. if (ResponseInfo.StatusCode = 200) and (Assigned(amBuckets)) then
  444. begin
  445. for amBucket in amBuckets do
  446. begin
  447. if amBucket = amBucketName then
  448. begin
  449. Result := True;
  450. Break;
  451. end;
  452. end;
  453. end;
  454. finally
  455. amBuckets.Free;
  456. end;
  457. end;
  458. function TQuickAmazon.ListBuckets(var amResponseInfo : TAmazonResponseInfo) : TStrings;
  459. var
  460. AmazonS3 : TAmazonStorageService;
  461. CloudResponseInfo : TCloudResponseInfo;
  462. Buckets : TStrings;
  463. i : Integer;
  464. begin
  465. AmazonS3 := TAmazonStorageService.Create(fconAmazon);
  466. Result := TStringList.Create;
  467. try
  468. //AmazonS3.Timeout := fTimeout;
  469. CloudResponseInfo := TCloudResponseInfo.Create;
  470. Buckets := AmazonS3.ListBuckets(CloudResponseInfo);
  471. try
  472. Result.Capacity := Buckets.Count;
  473. for i := 0 to Buckets.Count -1 do
  474. begin
  475. Result.Add(Buckets.Names[i]);
  476. end;
  477. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  478. finally
  479. Buckets.Free;
  480. end;
  481. finally
  482. AmazonS3.Free;
  483. CloudResponseInfo.Free;
  484. end;
  485. end;
  486. function TQuickAmazon.CreateBucket(amBucket : string; amBucketRegion : TAmazonRegion; amACLType : TAmazonACLAccess; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  487. var
  488. AmazonS3 : TAmazonStorageService;
  489. CloudResponseInfo : TCloudResponseInfo;
  490. begin
  491. Result := False;
  492. if amBucket = '' then Exit;
  493. AmazonS3 := TAmazonStorageService.Create(fconAmazon);
  494. try
  495. CloudResponseInfo := TCloudResponseInfo.Create;
  496. Result := AmazonS3.CreateBucket(amBucket,amACLType,amBucketRegion,CloudResponseInfo);
  497. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  498. finally
  499. AmazonS3.Free;
  500. CloudResponseInfo.Free;
  501. end;
  502. end;
  503. function TQuickAmazon.DeleteBucket(amBucket : string; amBucketRegion : TAmazonRegion; var amResponseInfo : TAmazonResponseInfo) : Boolean;
  504. var
  505. AmazonS3 : TAmazonStorageService;
  506. CloudResponseInfo : TCloudResponseInfo;
  507. begin
  508. Result := False;
  509. if amBucket = '' then Exit;
  510. AmazonS3 := TAmazonStorageService.Create(fconAmazon);
  511. try
  512. CloudResponseInfo := TCloudResponseInfo.Create;
  513. Result := AmazonS3.DeleteBucket(amBucket,CloudResponseInfo,amBucketRegion);
  514. amResponseInfo := GetResponseInfo(CloudResponseInfo);
  515. finally
  516. AmazonS3.Free;
  517. CloudResponseInfo.Free;
  518. end;
  519. end;
  520. class function TQuickAmazon.GetAWSRegion(const Region : string) : TAmazonRegion;
  521. begin
  522. Result := TAmazonStorageService.GetRegionFromString(Region);
  523. end;
  524. class function TQuickAmazon.GetAWSRegion(Region: TAmazonRegion): string;
  525. begin
  526. Result := TAmazonStorageService.GetRegionString(Region);
  527. end;
  528. end.