Quick.Azure.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. { ***************************************************************************
  2. Copyright (c) 2015-2017 Kike Pérez
  3. Unit : Quick.Azure
  4. Description : Azure blobs operations
  5. Author : Kike Pérez
  6. Version : 1.2
  7. Created : 27/08/2015
  8. Modified : 13/09/2017
  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.Azure;
  22. interface
  23. uses
  24. Classes,
  25. System.SysUtils,
  26. System.Generics.Collections,
  27. IPPeerClient,
  28. IdURI,
  29. Data.Cloud.CloudAPI,
  30. Data.Cloud.AzureAPI;
  31. type
  32. TAzureProtocol = (azHTTP,azHTTPS);
  33. //TAzureBlob = Data.Cloud.AzureAPI.TAzureBlob;
  34. TBlobPublicAccess = Data.Cloud.AzureAPI.TBlobPublicAccess;
  35. TAzureResponseInfo = record
  36. StatusCode : Integer;
  37. StatusMsg : string;
  38. end;
  39. TAzureBlobObject = class
  40. Name : string;
  41. Size : Int64;
  42. LastModified : TDateTime;
  43. end;
  44. TBlobList = class (TObjectList<TAzureBlobObject>);
  45. TQuickAzure = class
  46. private
  47. fconAzure : TAzureConnectionInfo;
  48. fAccountName : string;
  49. fAccountKey : string;
  50. fAzureProtocol : TAzureProtocol;
  51. fTimeOut : Integer;
  52. procedure SetAccountName(azAccountName : string);
  53. procedure SetAccountKey(azAccountKey : string);
  54. procedure SetAzureProtocol(azProtocol : TAzureProtocol);
  55. function FileToArray(cFilename : string) : TArray<Byte>;
  56. function StreamToArray(cStream : TStream) : TArray<Byte>;
  57. function GMT2DateTime(const gmtdate : string):TDateTime;
  58. function CheckContainer(const aContainer : string) : string;
  59. function RemoveFirstSlash(const aValue : string) : string;
  60. public
  61. constructor Create; overload;
  62. constructor Create(azAccountName, azAccountKey : string); overload;
  63. destructor Destroy; override;
  64. property AccountName : string read fAccountName write SetAccountName;
  65. property AccountKey : string read fAccountKey write SetAccountKey;
  66. property AzureProtocol : TAzureProtocol read fAzureProtocol write SetAzureProtocol;
  67. property TimeOut : Integer read fTimeOut write fTimeOut;
  68. function PutBlob(const azContainer, cFilename, azBlobName : string; out azResponseInfo : TAzureResponseInfo) : Boolean; overload;
  69. function PutBlob(const azContainer : string; cStream : TStream; const azBlobName : string; out azResponseInfo : TAzureResponseInfo) : Boolean; overload;
  70. function GetBlob(const azContainer, azBlobName, cFilenameTo : string; out azResponseInfo : TAzureResponseInfo) : Boolean; overload;
  71. function GetBlob(const azContainer, azBlobName : string; out azResponseInfo : TAzureResponseInfo; out Stream : TMemoryStream) : Boolean; overload;
  72. function GetBlob(const azContainer, azBlobName : string; out azResponseInfo : TAzureResponseInfo) : TMemoryStream; overload;
  73. function CopyBlob(const azSourceContainer, azSourceBlobName : string; azTargetContainer, azTargetBlobName : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  74. function RenameBlob(const azContainer, azSourceBlobName, azTargetBlobName : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  75. function ExistsObject(const azContainer, azBlobName : string) : Boolean;
  76. function ExistsFolder(const azContainer, azFolderName : string) : Boolean;
  77. function DeleteBlob(const azContainer,azBlobName : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  78. function ListBlobs(const azContainer, azBlobsStartWith : string; Recursive : Boolean; out azResponseInfo : TAzureResponseInfo) : TBlobList;
  79. function ListBlobsNames(const azContainer, azBlobsStartWith : string; Recursive : Boolean; out azResponseInfo : TAzureResponseInfo) : TStrings;
  80. function ExistsContainer(const azContainer : string) : Boolean;
  81. function ListContainers(const azContainersStartWith : string; azResponseInfo : TAzureResponseInfo) : TStrings;
  82. function CreateContainer(const azContainer : string; azPublicAccess : TBlobPublicAccess; out azResponseInfo : TAzureResponseInfo) : Boolean;
  83. function DeleteContainer(const azContainer : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  84. end;
  85. implementation
  86. constructor TQuickAzure.Create;
  87. begin
  88. inherited;
  89. fconAzure := TAzureConnectionInfo.Create(nil);
  90. fAzureProtocol := azHTTP;
  91. fTimeOut := 30;
  92. end;
  93. constructor TQuickAzure.Create(azAccountName, azAccountKey : string);
  94. begin
  95. Create;
  96. SetAccountName(azAccountName);
  97. SetAccountKey(azAccountKey);
  98. end;
  99. destructor TQuickAzure.Destroy;
  100. begin
  101. if Assigned(fconAzure) then fconAzure.Free;
  102. inherited;
  103. end;
  104. procedure TQuickAzure.SetAccountName(azAccountName : string);
  105. begin
  106. if fAccountName <> azAccountName then
  107. begin
  108. fAccountName := azAccountName;
  109. fconAzure.AccountName := azAccountName;
  110. end;
  111. end;
  112. procedure TQuickAzure.SetAccountKey(azAccountKey : string);
  113. begin
  114. if fAccountKey <> azAccountKey then
  115. begin
  116. fAccountKey := azAccountKey ;
  117. fconAzure.AccountKey := azAccountKey;
  118. end;
  119. end;
  120. procedure TQuickAzure.SetAzureProtocol(azProtocol: TAzureProtocol);
  121. begin
  122. if fAzureProtocol <> azProtocol then
  123. begin
  124. fAzureProtocol := azProtocol;
  125. if azProtocol = azHTTP then fconAzure.Protocol := 'HTTP'
  126. else fconAzure.Protocol := 'HTTPS';
  127. end;
  128. end;
  129. function TQuickAzure.FileToArray(cFilename : string) : TArray<Byte>;
  130. var
  131. fs : TFileStream;
  132. bs : TBytesStream;
  133. begin
  134. fs := TFileStream.Create(cFilename, fmOpenRead);
  135. try
  136. bs := TBytesStream.Create(Result);
  137. try
  138. bs.LoadFromStream(fs);
  139. Result := bs.Bytes;
  140. finally
  141. bs.Free
  142. end;
  143. finally
  144. fs.Free;
  145. end;
  146. end;
  147. function TQuickAzure.StreamToArray(cStream : TStream) : TArray<Byte>;
  148. var
  149. bs : TBytesStream;
  150. begin
  151. bs := TBytesStream.Create(Result);
  152. try
  153. bs.LoadFromStream(cStream);
  154. Result := bs.Bytes;
  155. finally
  156. bs.Free
  157. end;
  158. end;
  159. function TQuickAzure.GMT2DateTime(const gmtdate : string):TDateTime;
  160. function GetMonthDig(Value : string):Integer;
  161. const
  162. aMonth : array[1..12] of string = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
  163. var
  164. idx : Integer;
  165. begin
  166. Result := 0;
  167. for idx := 1 to 12 do
  168. begin
  169. if CompareText(Value,aMonth[idx]) = 0 then
  170. begin
  171. Result := idx;
  172. Break;
  173. end;
  174. end;
  175. end;
  176. var
  177. i : Integer;
  178. Len : Integer;
  179. wDay, wMonth, wYear,
  180. wHour, wMinute, wSec : Word;
  181. begin
  182. //GMT Format: 'Mon, 12 Jan 2014 16:20:35 GMT'
  183. Result := 0;
  184. Len := 0;
  185. if gmtdate = '' then Exit;
  186. try
  187. for i := 0 to Length(gmtdate) do
  188. begin
  189. if gmtdate[i] in ['0'..'9'] then
  190. begin
  191. Len := i;
  192. Break;
  193. end;
  194. end;
  195. //Day
  196. wDay := StrToIntDef(Copy(gmtdate,Len,2),0);
  197. if wDay = 0 then Exit;
  198. Inc(Len,3);
  199. //Month
  200. wMonth := GetMonthDig(Copy(gmtdate,Len,3));
  201. if wMonth = 0 then Exit;
  202. Inc(Len,4);
  203. //Year
  204. wYear := StrToIntDef(Copy(gmtdate,Len,4),0);
  205. if wYear = 0 then Exit;
  206. Inc(Len,5);
  207. //Hour
  208. wHour := StrToIntDef(Copy(gmtdate,Len,2),99);
  209. if wHour = 99 then Exit;
  210. Inc(Len,3);
  211. //Min
  212. wMinute := StrToIntDef(Copy(gmtdate,Len,2),99);
  213. if wMinute = 99 then Exit;
  214. Inc(Len,3);
  215. //Sec
  216. wSec := StrToIntDef(Copy(gmtdate,Len,2),99);
  217. if wSec = 99 then Exit;
  218. Result := EncodeDate(wYear,wMonth,wDay) + EncodeTime(wHour,wMinute,wSec,0);
  219. except
  220. Result := 0;
  221. end;
  222. end;
  223. function GetResponseInfo(ResponseInfo : TCloudResponseInfo) : TAzureResponseInfo;
  224. begin
  225. Result.StatusCode := ResponseInfo.StatusCode;
  226. Result.StatusMsg := ResponseInfo.StatusMessage;
  227. end;
  228. function TQuickAzure.PutBlob(const azContainer, cFilename, azBlobName : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  229. var
  230. BlobService : TAzureBlobService;
  231. Content : TArray<Byte>;
  232. CloudResponseInfo : TCloudResponseInfo;
  233. container : string;
  234. blobname : string;
  235. begin
  236. Result := False;
  237. BlobService := TAzureBlobService.Create(fconAzure);
  238. try
  239. container := CheckContainer(azContainer);
  240. CloudResponseInfo := TCloudResponseInfo.Create;
  241. try
  242. BlobService.Timeout := fTimeout;
  243. Content := FileToArray(cFilename);
  244. if azBlobName = '' then blobname := cFilename;
  245. if blobname.StartsWith('/') then blobname := Copy(blobname,2,Length(blobname));
  246. Result := BlobService.PutBlockBlob(container,blobname,Content,EmptyStr,nil,nil,CloudResponseInfo);
  247. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  248. finally
  249. CloudResponseInfo.Free;
  250. end;
  251. finally
  252. BlobService.Free;
  253. end;
  254. end;
  255. function TQuickAzure.PutBlob(const azContainer : string; cStream : TStream; const azBlobName : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  256. var
  257. BlobService : TAzureBlobService;
  258. Content : TArray<Byte>;
  259. CloudResponseInfo : TCloudResponseInfo;
  260. container : string;
  261. blobname : string;
  262. begin
  263. azResponseInfo.StatusCode := 500;
  264. if cStream.Size = 0 then
  265. begin
  266. azResponseInfo.StatusMsg := 'Stream is empty';
  267. Exit;
  268. end;
  269. container := CheckContainer(azContainer);
  270. blobname := RemoveFirstSlash(azBlobName);
  271. try
  272. BlobService := TAzureBlobService.Create(fconAzure);
  273. try
  274. BlobService.Timeout := fTimeout;
  275. CloudResponseInfo := TCloudResponseInfo.Create;
  276. try
  277. Content := StreamToArray(cStream);
  278. Result := BlobService.PutBlockBlob(container,blobname,Content,EmptyStr,nil,nil,CloudResponseInfo);
  279. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  280. finally
  281. CloudResponseInfo.Free;
  282. end;
  283. finally
  284. BlobService.Free;
  285. end;
  286. except
  287. on E : Exception do
  288. begin
  289. azResponseInfo.StatusCode := 500;
  290. azResponseInfo.StatusMsg := e.message;
  291. Result := False;
  292. end;
  293. end;
  294. end;
  295. function TQuickAzure.GetBlob(const azContainer, azBlobName, cFilenameTo : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  296. var
  297. BlobService : TAzureBlobService;
  298. fs : TFileStream;
  299. CloudResponseInfo : TCloudResponseInfo;
  300. container : string;
  301. blobname : string;
  302. begin
  303. Result := False;
  304. container := CheckContainer(azContainer);
  305. blobname := RemoveFirstSlash(azBlobName);
  306. BlobService := TAzureBlobService.Create(fconAzure);
  307. try
  308. BlobService.Timeout := fTimeout;
  309. fs := TFileStream.Create(cFilenameTo,fmCreate);
  310. try
  311. try
  312. CloudResponseInfo := TCloudResponseInfo.Create;
  313. try
  314. Result := BlobService.GetBlob(container,blobname,fs,EmptyStr,CloudResponseInfo);
  315. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  316. finally
  317. CloudResponseInfo.Free;
  318. end;
  319. except
  320. Result := False;
  321. end;
  322. finally
  323. fs.Free;
  324. end;
  325. finally
  326. BlobService.Free;
  327. end;
  328. end;
  329. function TQuickAzure.GetBlob(const azContainer, azBlobName : string; out azResponseInfo : TAzureResponseInfo; out Stream : TMemoryStream) : Boolean;
  330. var
  331. BlobService : TAzureBlobService;
  332. CloudResponseInfo : TCloudResponseInfo;
  333. container : string;
  334. blobname : string;
  335. begin
  336. Result := False;
  337. Stream := TMemoryStream.Create;
  338. container := CheckContainer(azContainer);
  339. blobname := RemoveFirstSlash(azBlobName);
  340. BlobService := TAzureBlobService.Create(fconAzure);
  341. try
  342. BlobService.Timeout := fTimeout;
  343. try
  344. CloudResponseInfo := TCloudResponseInfo.Create;
  345. try
  346. Result := BlobService.GetBlob(container,blobname,Stream,EmptyStr,CloudResponseInfo);
  347. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  348. finally
  349. CloudResponseInfo.Free;
  350. end;
  351. except
  352. Stream := nil;
  353. end;
  354. finally
  355. BlobService.Free;
  356. end;
  357. end;
  358. function TQuickAzure.GetBlob(const azContainer, azBlobName : string; out azResponseInfo : TAzureResponseInfo) : TMemoryStream;
  359. begin
  360. GetBlob(azContainer,azBlobName,azResponseInfo,Result);
  361. end;
  362. function TQuickAzure.CheckContainer(const aContainer: string): string;
  363. begin
  364. if aContainer = '' then Result := '$root'
  365. else Result := aContainer;
  366. end;
  367. function TQuickAzure.CopyBlob(const azSourceContainer, azSourceBlobName : string; azTargetContainer, azTargetBlobName : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  368. var
  369. BlobService : TAzureBlobService;
  370. CloudResponseInfo : TCloudResponseInfo;
  371. sourcecontainer : string;
  372. targetcontainer : string;
  373. sourceblobname : string;
  374. targetblobname : string;
  375. begin
  376. Result := False;
  377. sourcecontainer := CheckContainer(azSourceContainer);
  378. targetcontainer := CheckContainer(azTargetContainer);
  379. sourceblobname := RemoveFirstSlash(azSourceBlobName);
  380. targetblobname := RemoveFirstSlash(azTargetBlobName);
  381. BlobService := TAzureBlobService.Create(fconAzure);
  382. try
  383. BlobService.Timeout := fTimeout;
  384. try
  385. CloudResponseInfo := TCloudResponseInfo.Create;
  386. try
  387. Result := BlobService.CopyBlob(targetcontainer,targetblobname,sourcecontainer,sourceblobname,'',nil,CloudResponseInfo);
  388. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  389. finally
  390. CloudResponseInfo.Free;
  391. end;
  392. except
  393. on E : Exception do
  394. begin
  395. Result := False;
  396. azResponseInfo.StatusCode := 500;
  397. azResponseInfo.StatusMsg := e.message;
  398. end;
  399. end;
  400. finally
  401. BlobService.Free;
  402. end;
  403. end;
  404. function TQuickAzure.RemoveFirstSlash(const aValue: string): string;
  405. begin
  406. if aValue.StartsWith('/') then Result := Copy(aValue,2,Length(aValue))
  407. else Result := aValue;
  408. end;
  409. function TQuickAzure.RenameBlob(const azContainer, azSourceBlobName, azTargetBlobName : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  410. var
  411. sourceblobname : string;
  412. begin
  413. Result := False;
  414. if sourceblobname.Contains('%') then sourceblobname := azSourceBlobName
  415. else sourceblobname := TIdURI.PathEncode(azSourceBlobName);
  416. if CopyBlob(azContainer,sourceblobname,azContainer,azTargetBlobName,azResponseInfo) then
  417. begin
  418. Result := DeleteBlob(azContainer,azSourceBlobName,azResponseInfo);
  419. end;
  420. end;
  421. function TQuickAzure.ExistsObject(const azContainer, azBlobName : string) : Boolean;
  422. var
  423. azBlob : string;
  424. azBlobs : TStrings;
  425. ResponseInfo : TAzureResponseInfo;
  426. begin
  427. Result := False;
  428. azBlobs := ListBlobsNames(azContainer,azBlobName,False,ResponseInfo);
  429. try
  430. if (ResponseInfo.StatusCode = 200) and (Assigned(azBlobs)) then
  431. begin
  432. for azBlob in azBlobs do
  433. begin
  434. if azBlob = azBlobName then
  435. begin
  436. Result := True;
  437. Break;
  438. end;
  439. end;
  440. end;
  441. finally
  442. azBlobs.Free;
  443. end;
  444. end;
  445. function TQuickAzure.ExistsFolder(const azContainer, azFolderName : string) : Boolean;
  446. var
  447. BlobService : TAzureBlobService;
  448. azBlob : TAzureBlob;
  449. azBlobList : TList<TAzureBlob>;
  450. CloudResponseInfo : TCloudResponseInfo;
  451. AzParams : TStrings;
  452. cNextMarker : string;
  453. container : string;
  454. foldername : string;
  455. begin
  456. Result := False;
  457. container := CheckContainer(azContainer);
  458. BlobService := TAzureBlobService.Create(fconAzure);
  459. try
  460. BlobService.Timeout := fTimeout;
  461. AzParams := TStringList.Create;
  462. try
  463. if not azFolderName.EndsWith('/') then foldername := azFolderName + '/'
  464. else foldername := azFolderName;
  465. AzParams.Values['prefix'] := foldername;
  466. AzParams.Values['delimiter'] := '/';
  467. AzParams.Values['maxresults'] := '1';
  468. cNextMarker := '';
  469. CloudResponseInfo := TCloudResponseInfo.Create;
  470. try
  471. azBlobList := BlobService.ListBlobs(container,cNextMarker,AzParams,CloudResponseInfo);
  472. try
  473. if (Assigned(azBlobList)) and (azBlobList.Count > 0) and (CloudResponseInfo.StatusCode = 200) then Result := True;
  474. finally
  475. //frees azbloblist objects
  476. for azBlob in azBlobList do azBlob.Free;
  477. azBlobList.Free;
  478. end;
  479. finally
  480. CloudResponseInfo.Free;
  481. end;
  482. finally
  483. AzParams.Free;
  484. end;
  485. finally
  486. BlobService.Free;
  487. end;
  488. end;
  489. function TQuickAzure.DeleteBlob(const azContainer,azBlobName : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  490. var
  491. BlobService : TAzureBlobService;
  492. CloudResponseInfo : TCloudResponseInfo;
  493. container : string;
  494. blobname : string;
  495. begin
  496. Result := False;
  497. container := CheckContainer(azContainer);
  498. blobname := RemoveFirstSlash(azBlobName);
  499. BlobService := TAzureBlobService.Create(fconAzure);
  500. try
  501. BlobService.Timeout := fTimeout;
  502. CloudResponseInfo := TCloudResponseInfo.Create;
  503. try
  504. Result := BlobService.DeleteBlob(container,blobname,False,EmptyStr,CloudResponseInfo);
  505. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  506. finally
  507. CloudResponseInfo.Free;
  508. end;
  509. finally
  510. BlobService.Free;
  511. end;
  512. end;
  513. function TQuickAzure.ListBlobs(const azContainer, azBlobsStartWith : string; Recursive : Boolean; out azResponseInfo : TAzureResponseInfo) : TBlobList;
  514. var
  515. BlobService : TAzureBlobService;
  516. azBlob : TAzureBlob;
  517. azBlobList : TList<TAzureBlob>;
  518. Blob : TAzureBlobObject;
  519. CloudResponseInfo : TCloudResponseInfo;
  520. cNextMarker : string;
  521. AzParams : TStrings;
  522. container : string;
  523. begin
  524. Result := TBlobList.Create(True);
  525. cNextMarker := '';
  526. container := CheckContainer(azContainer);
  527. BlobService := TAzureBlobService.Create(fconAzure);
  528. try
  529. BlobService.Timeout := fTimeout;
  530. repeat
  531. AzParams := TStringList.Create;
  532. try
  533. AzParams.Values['prefix'] := azBlobsStartWith;
  534. if not Recursive then AzParams.Values['delimiter'] := '/';
  535. if cNextMarker <> '' then AzParams.Values['marker'] := cNextMarker;
  536. CloudResponseInfo := TCloudResponseInfo.Create;
  537. try
  538. azBlobList := BlobService.ListBlobs(container,cNextMarker,AzParams,CloudResponseInfo);
  539. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  540. if Assigned(azBlobList) then
  541. begin
  542. try
  543. for azBlob in azBlobList do
  544. begin
  545. Blob := TAzureBlobObject.Create;
  546. Blob.Name := azBlob.Name;
  547. Blob.Size := StrToInt64Def(azBlob.Properties.Values['Content-Length'],0);
  548. Blob.LastModified := GMT2DateTime(azBlob.Properties.Values['Last-Modified']);
  549. Result.Add(Blob);
  550. end;
  551. finally
  552. //frees azbloblist objects
  553. for azBlob in azBlobList do azBlob.Free;
  554. azBlobList.Free;
  555. end;
  556. end;
  557. finally
  558. CloudResponseInfo.Free;
  559. end;
  560. finally
  561. FreeAndNil(AzParams);
  562. end;
  563. until (cNextMarker = '') or (azResponseInfo.StatusCode <> 200);
  564. finally
  565. BlobService.Free;
  566. end;
  567. end;
  568. function TQuickAzure.ListBlobsNames(const azContainer, azBlobsStartWith : string; Recursive : Boolean; out azResponseInfo : TAzureResponseInfo) : TStrings;
  569. var
  570. BlobService : TAzureBlobService;
  571. azBlob : TAzureBlob;
  572. azBlobList : TList<TAzureBlob>;
  573. CloudResponseInfo : TCloudResponseInfo;
  574. cNextMarker : string;
  575. AzParams : TStrings;
  576. container : string;
  577. begin
  578. Result := TStringList.Create;
  579. cNextMarker := '';
  580. container := CheckContainer(azContainer);
  581. BlobService := TAzureBlobService.Create(fconAzure);
  582. CloudResponseInfo := TCloudResponseInfo.Create;
  583. try
  584. BlobService.Timeout := fTimeout;
  585. repeat
  586. AzParams := TStringList.Create;
  587. try
  588. AzParams.Values['prefix'] := azBlobsStartWith;
  589. if not Recursive then AzParams.Values['delimiter'] := '/';
  590. if cNextMarker <> '' then AzParams.Values['marker'] := cNextMarker;
  591. azBlobList := BlobService.ListBlobs(container,cNextMarker,AzParams,CloudResponseInfo);
  592. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  593. if Assigned(azBlobList) then
  594. begin
  595. Result.BeginUpdate;
  596. try
  597. for azBlob in azBlobList do Result.Add(azBlob.Name);
  598. finally
  599. Result.EndUpdate;
  600. //frees bloblist objects
  601. for azBlob in azBlobList do azBlob.Free;
  602. azBlobList.Free;
  603. end;
  604. end;
  605. finally
  606. AzParams.Free;
  607. end;
  608. until (cNextMarker = '') or (azResponseInfo.StatusCode <> 200);
  609. finally
  610. BlobService.Free;
  611. CloudResponseInfo.Free;
  612. end;
  613. end;
  614. function TQuickAzure.ExistsContainer(const azContainer : string) : Boolean;
  615. var
  616. Container : string;
  617. Containers : TStrings;
  618. ResponseInfo : TAzureResponseInfo;
  619. begin
  620. Result := False;
  621. Containers := ListContainers(azContainer,ResponseInfo);
  622. try
  623. if (ResponseInfo.StatusCode = 200) and (Assigned(Containers)) then
  624. begin
  625. for Container in Containers do
  626. begin
  627. if Container = azContainer then
  628. begin
  629. Result := True;
  630. Break;
  631. end;
  632. end;
  633. end;
  634. finally
  635. Containers.Free;
  636. end;
  637. end;
  638. function TQuickAzure.ListContainers(const azContainersStartWith : string; azResponseInfo : TAzureResponseInfo) : TStrings;
  639. var
  640. BlobService : TAzureBlobService;
  641. CloudResponseInfo : TCloudResponseInfo;
  642. cNextMarker : string;
  643. AzParams : TStrings;
  644. AzContainer : TAzureContainer;
  645. AzContainers : TList<TAzureContainer>;
  646. begin
  647. Result := TStringList.Create;
  648. cNextMarker := '';
  649. BlobService := TAzureBlobService.Create(fconAzure);
  650. CloudResponseInfo := TCloudResponseInfo.Create;
  651. try
  652. BlobService.Timeout := fTimeout;
  653. repeat
  654. AzParams := TStringList.Create;
  655. try
  656. if azContainersStartWith <> '' then AzParams.Values['prefix'] := azContainersStartWith;
  657. if cNextMarker <> '' then AzParams.Values['marker'] := cNextMarker;
  658. AzContainers := BlobService.ListContainers(cNextMarker,AzParams,CloudResponseInfo);
  659. try
  660. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  661. if (azResponseInfo.StatusCode = 200) and (Assigned(AzContainers)) then
  662. begin
  663. for AzContainer in AzContainers do
  664. begin
  665. Result.Add(AzContainer.Name);
  666. end;
  667. end;
  668. finally
  669. if Assigned(AzContainer) then
  670. begin
  671. //frees ContainerList objects
  672. for AzContainer in AzContainers do AzContainer.Free;
  673. AzContainers.Free;
  674. end;
  675. end;
  676. finally
  677. AzParams.Free;
  678. end;
  679. until (cNextMarker = '') or (azResponseInfo.StatusCode <> 200);
  680. finally
  681. BlobService.Free;
  682. CloudResponseInfo.Free;
  683. end;
  684. end;
  685. function TQuickAzure.CreateContainer(const azContainer : string; azPublicAccess : TBlobPublicAccess; out azResponseInfo : TAzureResponseInfo) : Boolean;
  686. var
  687. BlobService : TAzureBlobService;
  688. CloudResponseInfo : TCloudResponseInfo;
  689. begin
  690. Result := False;
  691. if azContainer = '' then Exit;
  692. BlobService := TAzureBlobService.Create(fconAzure);
  693. try
  694. BlobService.Timeout := fTimeout;
  695. CloudResponseInfo := TCloudResponseInfo.Create;
  696. Result := BlobService.CreateContainer(azContainer,nil,azPublicAccess,CloudResponseInfo);
  697. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  698. finally
  699. BlobService.Free;
  700. CloudResponseInfo.Free;
  701. end;
  702. end;
  703. function TQuickAzure.DeleteContainer(const azContainer : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  704. var
  705. BlobService : TAzureBlobService;
  706. CloudResponseInfo : TCloudResponseInfo;
  707. begin
  708. Result := False;
  709. if azContainer = '' then Exit;
  710. BlobService := TAzureBlobService.Create(fconAzure);
  711. try
  712. BlobService.Timeout := fTimeout;
  713. CloudResponseInfo := TCloudResponseInfo.Create;
  714. Result := BlobService.DeleteContainer(azContainer,CloudResponseInfo);
  715. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  716. finally
  717. BlobService.Free;
  718. CloudResponseInfo.Free;
  719. end;
  720. end;
  721. end.