Quick.Azure.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. { ***************************************************************************
  2. Copyright (c) 2015-2019 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 : 11/03/2019
  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. else blobname := azBlobName;
  246. if blobname.StartsWith('/') then blobname := Copy(blobname,2,Length(blobname));
  247. Result := BlobService.PutBlockBlob(container,blobname,Content,EmptyStr,nil,nil,CloudResponseInfo);
  248. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  249. finally
  250. CloudResponseInfo.Free;
  251. end;
  252. finally
  253. BlobService.Free;
  254. end;
  255. end;
  256. function TQuickAzure.PutBlob(const azContainer : string; cStream : TStream; const azBlobName : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  257. var
  258. BlobService : TAzureBlobService;
  259. Content : TArray<Byte>;
  260. CloudResponseInfo : TCloudResponseInfo;
  261. container : string;
  262. blobname : string;
  263. begin
  264. azResponseInfo.StatusCode := 500;
  265. if cStream.Size = 0 then
  266. begin
  267. azResponseInfo.StatusMsg := 'Stream is empty';
  268. Exit;
  269. end;
  270. container := CheckContainer(azContainer);
  271. blobname := RemoveFirstSlash(azBlobName);
  272. try
  273. BlobService := TAzureBlobService.Create(fconAzure);
  274. try
  275. BlobService.Timeout := fTimeout;
  276. CloudResponseInfo := TCloudResponseInfo.Create;
  277. try
  278. Content := StreamToArray(cStream);
  279. Result := BlobService.PutBlockBlob(container,blobname,Content,EmptyStr,nil,nil,CloudResponseInfo);
  280. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  281. finally
  282. CloudResponseInfo.Free;
  283. end;
  284. finally
  285. BlobService.Free;
  286. end;
  287. except
  288. on E : Exception do
  289. begin
  290. azResponseInfo.StatusCode := 500;
  291. azResponseInfo.StatusMsg := e.message;
  292. Result := False;
  293. end;
  294. end;
  295. end;
  296. function TQuickAzure.GetBlob(const azContainer, azBlobName, cFilenameTo : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  297. var
  298. BlobService : TAzureBlobService;
  299. fs : TFileStream;
  300. CloudResponseInfo : TCloudResponseInfo;
  301. container : string;
  302. blobname : string;
  303. begin
  304. Result := False;
  305. container := CheckContainer(azContainer);
  306. blobname := RemoveFirstSlash(azBlobName);
  307. BlobService := TAzureBlobService.Create(fconAzure);
  308. try
  309. BlobService.Timeout := fTimeout;
  310. fs := TFileStream.Create(cFilenameTo,fmCreate);
  311. try
  312. try
  313. CloudResponseInfo := TCloudResponseInfo.Create;
  314. try
  315. Result := BlobService.GetBlob(container,blobname,fs,EmptyStr,CloudResponseInfo);
  316. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  317. finally
  318. CloudResponseInfo.Free;
  319. end;
  320. except
  321. Result := False;
  322. end;
  323. finally
  324. fs.Free;
  325. end;
  326. finally
  327. BlobService.Free;
  328. end;
  329. end;
  330. function TQuickAzure.GetBlob(const azContainer, azBlobName : string; out azResponseInfo : TAzureResponseInfo; out Stream : TMemoryStream) : Boolean;
  331. var
  332. BlobService : TAzureBlobService;
  333. CloudResponseInfo : TCloudResponseInfo;
  334. container : string;
  335. blobname : string;
  336. begin
  337. Result := False;
  338. Stream := TMemoryStream.Create;
  339. container := CheckContainer(azContainer);
  340. blobname := RemoveFirstSlash(azBlobName);
  341. BlobService := TAzureBlobService.Create(fconAzure);
  342. try
  343. BlobService.Timeout := fTimeout;
  344. try
  345. CloudResponseInfo := TCloudResponseInfo.Create;
  346. try
  347. Result := BlobService.GetBlob(container,blobname,Stream,EmptyStr,CloudResponseInfo);
  348. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  349. finally
  350. CloudResponseInfo.Free;
  351. end;
  352. except
  353. Stream := nil;
  354. end;
  355. finally
  356. BlobService.Free;
  357. end;
  358. end;
  359. function TQuickAzure.GetBlob(const azContainer, azBlobName : string; out azResponseInfo : TAzureResponseInfo) : TMemoryStream;
  360. begin
  361. GetBlob(azContainer,azBlobName,azResponseInfo,Result);
  362. end;
  363. function TQuickAzure.CheckContainer(const aContainer: string): string;
  364. begin
  365. if aContainer = '' then Result := '$root'
  366. else Result := aContainer;
  367. end;
  368. function TQuickAzure.CopyBlob(const azSourceContainer, azSourceBlobName : string; azTargetContainer, azTargetBlobName : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  369. var
  370. BlobService : TAzureBlobService;
  371. CloudResponseInfo : TCloudResponseInfo;
  372. sourcecontainer : string;
  373. targetcontainer : string;
  374. sourceblobname : string;
  375. targetblobname : string;
  376. begin
  377. Result := False;
  378. sourcecontainer := CheckContainer(azSourceContainer);
  379. targetcontainer := CheckContainer(azTargetContainer);
  380. sourceblobname := RemoveFirstSlash(azSourceBlobName);
  381. targetblobname := RemoveFirstSlash(azTargetBlobName);
  382. BlobService := TAzureBlobService.Create(fconAzure);
  383. try
  384. BlobService.Timeout := fTimeout;
  385. try
  386. CloudResponseInfo := TCloudResponseInfo.Create;
  387. try
  388. Result := BlobService.CopyBlob(targetcontainer,targetblobname,sourcecontainer,sourceblobname,'',nil,CloudResponseInfo);
  389. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  390. finally
  391. CloudResponseInfo.Free;
  392. end;
  393. except
  394. on E : Exception do
  395. begin
  396. Result := False;
  397. azResponseInfo.StatusCode := 500;
  398. azResponseInfo.StatusMsg := e.message;
  399. end;
  400. end;
  401. finally
  402. BlobService.Free;
  403. end;
  404. end;
  405. function TQuickAzure.RemoveFirstSlash(const aValue: string): string;
  406. begin
  407. if aValue.StartsWith('/') then Result := Copy(aValue,2,Length(aValue))
  408. else Result := aValue;
  409. end;
  410. function TQuickAzure.RenameBlob(const azContainer, azSourceBlobName, azTargetBlobName : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  411. var
  412. sourceblobname : string;
  413. begin
  414. Result := False;
  415. if sourceblobname.Contains('%') then sourceblobname := azSourceBlobName
  416. else sourceblobname := TIdURI.PathEncode(azSourceBlobName);
  417. if CopyBlob(azContainer,sourceblobname,azContainer,azTargetBlobName,azResponseInfo) then
  418. begin
  419. Result := DeleteBlob(azContainer,azSourceBlobName,azResponseInfo);
  420. end;
  421. end;
  422. function TQuickAzure.ExistsObject(const azContainer, azBlobName : string) : Boolean;
  423. var
  424. azBlob : string;
  425. azBlobs : TStrings;
  426. ResponseInfo : TAzureResponseInfo;
  427. begin
  428. Result := False;
  429. azBlobs := ListBlobsNames(azContainer,azBlobName,False,ResponseInfo);
  430. try
  431. if (ResponseInfo.StatusCode = 200) and (Assigned(azBlobs)) then
  432. begin
  433. for azBlob in azBlobs do
  434. begin
  435. if azBlob = azBlobName then
  436. begin
  437. Result := True;
  438. Break;
  439. end;
  440. end;
  441. end;
  442. finally
  443. azBlobs.Free;
  444. end;
  445. end;
  446. function TQuickAzure.ExistsFolder(const azContainer, azFolderName : string) : Boolean;
  447. var
  448. BlobService : TAzureBlobService;
  449. azBlob : TAzureBlob;
  450. azBlobList : TList<TAzureBlob>;
  451. CloudResponseInfo : TCloudResponseInfo;
  452. AzParams : TStrings;
  453. cNextMarker : string;
  454. container : string;
  455. foldername : string;
  456. begin
  457. Result := False;
  458. container := CheckContainer(azContainer);
  459. BlobService := TAzureBlobService.Create(fconAzure);
  460. try
  461. BlobService.Timeout := fTimeout;
  462. AzParams := TStringList.Create;
  463. try
  464. if not azFolderName.EndsWith('/') then foldername := azFolderName + '/'
  465. else foldername := azFolderName;
  466. AzParams.Values['prefix'] := foldername;
  467. AzParams.Values['delimiter'] := '/';
  468. AzParams.Values['maxresults'] := '1';
  469. cNextMarker := '';
  470. CloudResponseInfo := TCloudResponseInfo.Create;
  471. try
  472. azBlobList := BlobService.ListBlobs(container,cNextMarker,AzParams,CloudResponseInfo);
  473. try
  474. if (Assigned(azBlobList)) and (azBlobList.Count > 0) and (CloudResponseInfo.StatusCode = 200) then Result := True;
  475. finally
  476. //frees azbloblist objects
  477. for azBlob in azBlobList do azBlob.Free;
  478. azBlobList.Free;
  479. end;
  480. finally
  481. CloudResponseInfo.Free;
  482. end;
  483. finally
  484. AzParams.Free;
  485. end;
  486. finally
  487. BlobService.Free;
  488. end;
  489. end;
  490. function TQuickAzure.DeleteBlob(const azContainer,azBlobName : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  491. var
  492. BlobService : TAzureBlobService;
  493. CloudResponseInfo : TCloudResponseInfo;
  494. container : string;
  495. blobname : string;
  496. begin
  497. Result := False;
  498. container := CheckContainer(azContainer);
  499. blobname := RemoveFirstSlash(azBlobName);
  500. BlobService := TAzureBlobService.Create(fconAzure);
  501. try
  502. BlobService.Timeout := fTimeout;
  503. CloudResponseInfo := TCloudResponseInfo.Create;
  504. try
  505. Result := BlobService.DeleteBlob(container,blobname,False,EmptyStr,CloudResponseInfo);
  506. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  507. finally
  508. CloudResponseInfo.Free;
  509. end;
  510. finally
  511. BlobService.Free;
  512. end;
  513. end;
  514. function TQuickAzure.ListBlobs(const azContainer, azBlobsStartWith : string; Recursive : Boolean; out azResponseInfo : TAzureResponseInfo) : TBlobList;
  515. var
  516. BlobService : TAzureBlobService;
  517. azBlob : TAzureBlob;
  518. azBlobList : TList<TAzureBlob>;
  519. Blob : TAzureBlobObject;
  520. CloudResponseInfo : TCloudResponseInfo;
  521. cNextMarker : string;
  522. AzParams : TStrings;
  523. container : string;
  524. begin
  525. Result := TBlobList.Create(True);
  526. cNextMarker := '';
  527. container := CheckContainer(azContainer);
  528. BlobService := TAzureBlobService.Create(fconAzure);
  529. try
  530. BlobService.Timeout := fTimeout;
  531. repeat
  532. AzParams := TStringList.Create;
  533. try
  534. AzParams.Values['prefix'] := azBlobsStartWith;
  535. if not Recursive then AzParams.Values['delimiter'] := '/';
  536. if cNextMarker <> '' then AzParams.Values['marker'] := cNextMarker;
  537. CloudResponseInfo := TCloudResponseInfo.Create;
  538. try
  539. azBlobList := BlobService.ListBlobs(container,cNextMarker,AzParams,CloudResponseInfo);
  540. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  541. if Assigned(azBlobList) then
  542. begin
  543. try
  544. for azBlob in azBlobList do
  545. begin
  546. Blob := TAzureBlobObject.Create;
  547. Blob.Name := azBlob.Name;
  548. Blob.Size := StrToInt64Def(azBlob.Properties.Values['Content-Length'],0);
  549. Blob.LastModified := GMT2DateTime(azBlob.Properties.Values['Last-Modified']);
  550. Result.Add(Blob);
  551. end;
  552. finally
  553. //frees azbloblist objects
  554. for azBlob in azBlobList do azBlob.Free;
  555. azBlobList.Free;
  556. end;
  557. end;
  558. finally
  559. CloudResponseInfo.Free;
  560. end;
  561. finally
  562. FreeAndNil(AzParams);
  563. end;
  564. until (cNextMarker = '') or (azResponseInfo.StatusCode <> 200);
  565. finally
  566. BlobService.Free;
  567. end;
  568. end;
  569. function TQuickAzure.ListBlobsNames(const azContainer, azBlobsStartWith : string; Recursive : Boolean; out azResponseInfo : TAzureResponseInfo) : TStrings;
  570. var
  571. BlobService : TAzureBlobService;
  572. azBlob : TAzureBlob;
  573. azBlobList : TList<TAzureBlob>;
  574. CloudResponseInfo : TCloudResponseInfo;
  575. cNextMarker : string;
  576. AzParams : TStrings;
  577. container : string;
  578. begin
  579. Result := TStringList.Create;
  580. cNextMarker := '';
  581. container := CheckContainer(azContainer);
  582. BlobService := TAzureBlobService.Create(fconAzure);
  583. CloudResponseInfo := TCloudResponseInfo.Create;
  584. try
  585. BlobService.Timeout := fTimeout;
  586. repeat
  587. AzParams := TStringList.Create;
  588. try
  589. AzParams.Values['prefix'] := azBlobsStartWith;
  590. if not Recursive then AzParams.Values['delimiter'] := '/';
  591. if cNextMarker <> '' then AzParams.Values['marker'] := cNextMarker;
  592. azBlobList := BlobService.ListBlobs(container,cNextMarker,AzParams,CloudResponseInfo);
  593. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  594. if Assigned(azBlobList) then
  595. begin
  596. Result.BeginUpdate;
  597. try
  598. for azBlob in azBlobList do Result.Add(azBlob.Name);
  599. finally
  600. Result.EndUpdate;
  601. //frees bloblist objects
  602. for azBlob in azBlobList do azBlob.Free;
  603. azBlobList.Free;
  604. end;
  605. end;
  606. finally
  607. AzParams.Free;
  608. end;
  609. until (cNextMarker = '') or (azResponseInfo.StatusCode <> 200);
  610. finally
  611. BlobService.Free;
  612. CloudResponseInfo.Free;
  613. end;
  614. end;
  615. function TQuickAzure.ExistsContainer(const azContainer : string) : Boolean;
  616. var
  617. Container : string;
  618. Containers : TStrings;
  619. ResponseInfo : TAzureResponseInfo;
  620. begin
  621. Result := False;
  622. Containers := ListContainers(azContainer,ResponseInfo);
  623. try
  624. if (ResponseInfo.StatusCode = 200) and (Assigned(Containers)) then
  625. begin
  626. for Container in Containers do
  627. begin
  628. if Container = azContainer then
  629. begin
  630. Result := True;
  631. Break;
  632. end;
  633. end;
  634. end;
  635. finally
  636. Containers.Free;
  637. end;
  638. end;
  639. function TQuickAzure.ListContainers(const azContainersStartWith : string; azResponseInfo : TAzureResponseInfo) : TStrings;
  640. var
  641. BlobService : TAzureBlobService;
  642. CloudResponseInfo : TCloudResponseInfo;
  643. cNextMarker : string;
  644. AzParams : TStrings;
  645. AzContainer : TAzureContainer;
  646. AzContainers : TList<TAzureContainer>;
  647. begin
  648. Result := TStringList.Create;
  649. cNextMarker := '';
  650. BlobService := TAzureBlobService.Create(fconAzure);
  651. CloudResponseInfo := TCloudResponseInfo.Create;
  652. try
  653. BlobService.Timeout := fTimeout;
  654. repeat
  655. AzParams := TStringList.Create;
  656. try
  657. if azContainersStartWith <> '' then AzParams.Values['prefix'] := azContainersStartWith;
  658. if cNextMarker <> '' then AzParams.Values['marker'] := cNextMarker;
  659. AzContainers := BlobService.ListContainers(cNextMarker,AzParams,CloudResponseInfo);
  660. try
  661. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  662. if (azResponseInfo.StatusCode = 200) and (Assigned(AzContainers)) then
  663. begin
  664. for AzContainer in AzContainers do
  665. begin
  666. Result.Add(AzContainer.Name);
  667. end;
  668. end;
  669. finally
  670. if Assigned(AzContainer) then
  671. begin
  672. //frees ContainerList objects
  673. for AzContainer in AzContainers do AzContainer.Free;
  674. AzContainers.Free;
  675. end;
  676. end;
  677. finally
  678. AzParams.Free;
  679. end;
  680. until (cNextMarker = '') or (azResponseInfo.StatusCode <> 200);
  681. finally
  682. BlobService.Free;
  683. CloudResponseInfo.Free;
  684. end;
  685. end;
  686. function TQuickAzure.CreateContainer(const azContainer : string; azPublicAccess : TBlobPublicAccess; out azResponseInfo : TAzureResponseInfo) : Boolean;
  687. var
  688. BlobService : TAzureBlobService;
  689. CloudResponseInfo : TCloudResponseInfo;
  690. begin
  691. Result := False;
  692. if azContainer = '' then Exit;
  693. BlobService := TAzureBlobService.Create(fconAzure);
  694. try
  695. BlobService.Timeout := fTimeout;
  696. CloudResponseInfo := TCloudResponseInfo.Create;
  697. Result := BlobService.CreateContainer(azContainer,nil,azPublicAccess,CloudResponseInfo);
  698. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  699. finally
  700. BlobService.Free;
  701. CloudResponseInfo.Free;
  702. end;
  703. end;
  704. function TQuickAzure.DeleteContainer(const azContainer : string; out azResponseInfo : TAzureResponseInfo) : Boolean;
  705. var
  706. BlobService : TAzureBlobService;
  707. CloudResponseInfo : TCloudResponseInfo;
  708. begin
  709. Result := False;
  710. if azContainer = '' then Exit;
  711. BlobService := TAzureBlobService.Create(fconAzure);
  712. try
  713. BlobService.Timeout := fTimeout;
  714. CloudResponseInfo := TCloudResponseInfo.Create;
  715. Result := BlobService.DeleteContainer(azContainer,CloudResponseInfo);
  716. azResponseInfo := GetResponseInfo(CloudResponseInfo);
  717. finally
  718. BlobService.Free;
  719. CloudResponseInfo.Free;
  720. end;
  721. end;
  722. end.