ADD: MacCloud/S3: step-122: support multi-bucket in Amazones3/AliyunOSS/TencentCOS/HuaweiBOS

This commit is contained in:
rich2014 2025-05-11 14:16:34 +08:00
commit 13aec9f5b0
6 changed files with 87 additions and 33 deletions

View file

@ -7,7 +7,7 @@ interface
uses
Classes, SysUtils,
CocoaAll,
uCloudDriver, uS3Client,
uCloudDriver, uAWSCore, uS3Client,
uMiniUtil;
type
@ -17,6 +17,7 @@ type
TAliyunOSSGetAllBucketsSession = class( TS3GetAllBucketsSession )
protected
procedure constructBucket( const bucket: TS3Bucket; const xmlBucket: NSXMLElement ); override;
function getConnectionDataOfService: TAWSConnectionData; override;
function getEndPointOfRegion(const region: String): String; override;
end;
@ -40,12 +41,16 @@ begin
bucket.connectionData.endPoint:= TXmlUtil.getString( xmlBucket, 'ExtranetEndpoint' );
end;
function TAliyunOSSGetAllBucketsSession.getConnectionDataOfService: TAWSConnectionData;
begin
Result.region:= '';
Result.endPoint:= 'oss.aliyuncs.com';
Result.bucketName:= '';
end;
function TAliyunOSSGetAllBucketsSession.getEndPointOfRegion( const region: String ): String;
begin
if region = EmptyStr then
Result:= 'oss.aliyuncs.com'
else
Result:= 'oss-' + region + '.aliyuncs.com';
Result:= 'oss-' + region + '.aliyuncs.com';
end;
{ TAliyunOSSClient }

View file

@ -18,6 +18,7 @@ type
TAmazonS3GetAllBucketsSession = class( TS3GetAllBucketsSession )
protected
procedure constructBucket( const bucket: TS3Bucket; const xmlBucket: NSXMLElement ); override;
function getConnectionDataOfService: TAWSConnectionData; override;
function getEndPointOfRegion(const region: String): String; override;
function getRegionOfBucket(const name: String): String;
end;
@ -43,23 +44,31 @@ begin
bucket.connectionData.endPoint:= self.getEndPointOfRegion( bucket.connectionData.region );
end;
function TAmazonS3GetAllBucketsSession.getConnectionDataOfService: TAWSConnectionData;
begin
Result.region:= 'us-east-1';
Result.endPoint:= 's3.amazonaws.com';
Result.bucketName:= '';
end;
function TAmazonS3GetAllBucketsSession.getEndPointOfRegion( const region: String ): String;
begin
if region = EmptyStr then
Result:= 's3.us-east-1.amazonaws.com'
else
Result:= 's3.' + region + '.amazonaws.com';
Result:= 's3.' + region + '.amazonaws.com';
end;
function TAmazonS3GetAllBucketsSession.getRegionOfBucket( const name: String ): String;
var
connectionData: TAWSConnectionData;
endPoint: String;
http: TMiniHttpClient = nil;
httpResult: TMiniHttpResult = nil;
cloudDriverResult: TCloudDriverResult = nil;
urlString: String;
begin
try
urlString:= 'https://' + name + '.' + self.getEndPointOfRegion('') + '/';
connectionData:= self.getConnectionDataOfService;
endPoint:= self.getEndPointOfRegion( connectionData.region );
urlString:= 'https://' + name + '.' + endPoint + '/';
http:= TMiniHttpClient.Create( urlString, HttpConst.Method.HEAD );
http.addHeader( AWSConst.HEADER.CONTENT_SHA256, AWSConst.HEADER.CONTENT_SHA256_DEFAULT_VALUE );
_authSession.setAuthHeader( http );

View file

@ -7,7 +7,7 @@ interface
uses
Classes, SysUtils,
CocoaAll,
uCloudDriver, uS3Client,
uCloudDriver, uAWSCore, uS3Client,
uMiniUtil;
type
@ -17,6 +17,7 @@ type
THuaweiOBSGetAllBucketsSession = class( TS3GetAllBucketsSession )
protected
procedure constructBucket( const bucket: TS3Bucket; const xmlBucket: NSXMLElement ); override;
function getConnectionDataOfService: TAWSConnectionData; override;
function getEndPointOfRegion(const region: String): String; override;
end;
@ -40,12 +41,16 @@ begin
bucket.connectionData.endPoint:= self.getEndPointOfRegion( bucket.connectionData.region );
end;
function THuaweiOBSGetAllBucketsSession.getConnectionDataOfService: TAWSConnectionData;
begin
Result.region:= '';
Result.endPoint:= 'obs.myhuaweicloud.com';
Result.bucketName:= '';
end;
function THuaweiOBSGetAllBucketsSession.getEndPointOfRegion( const region: String ): String;
begin
if region = EmptyStr then
Result:= 'obs.myhuaweicloud.com'
else
Result:= 'obs.' + region + '.myhuaweicloud.com';
Result:= 'obs.' + region + '.myhuaweicloud.com';
end;
{ THuaweiOBSClient }

View file

@ -16,7 +16,9 @@ type
public
class function driverName: String; override;
class function createInstance: TCloudDriver; override;
protected
function getConcreteClass: TCloudDriverClass; override;
function getAllBuckets: TS3Buckets; override;
end;
implementation
@ -38,5 +40,15 @@ begin
Result:= TS3CompatibleClient;
end;
function TS3CompatibleClient.getAllBuckets: TS3Buckets;
var
bucket: TS3Bucket;
begin
bucket:= TS3Bucket.Create;
bucket.connectionData:= self.getDefaultConnectionData;
Result:= TS3Buckets.Create;
Result.add( bucket );
end;
end.

View file

@ -7,7 +7,7 @@ interface
uses
Classes, SysUtils,
CocoaAll,
uCloudDriver, uS3Client,
uCloudDriver, uAWSCore, uS3Client,
uMiniUtil;
type
@ -17,6 +17,7 @@ type
TTencentCOSGetAllBucketsSession = class( TS3GetAllBucketsSession )
protected
procedure constructBucket( const bucket: TS3Bucket; const xmlBucket: NSXMLElement ); override;
function getConnectionDataOfService: TAWSConnectionData; override;
function getEndPointOfRegion(const region: String): String; override;
end;
@ -40,12 +41,16 @@ begin
bucket.connectionData.endPoint:= self.getEndPointOfRegion( bucket.connectionData.region );
end;
function TTencentCOSGetAllBucketsSession.getConnectionDataOfService: TAWSConnectionData;
begin
Result.region:= '*';
Result.endPoint:= 'service.cos.myqcloud.com';
Result.bucketName:= '';
end;
function TTencentCOSGetAllBucketsSession.getEndPointOfRegion( const region: String ): String;
begin
if region = EmptyStr then
Result:= 'service.cos.myqcloud.com'
else
Result:= 'cos.' + region + '.myqcloud.com';
Result:= 'cos.' + region + '.myqcloud.com';
end;
{ TTencentCOSClient }

View file

@ -59,6 +59,7 @@ type
function analyseListResult( const listString: String ): TS3Buckets;
protected
procedure constructBucket( const bucket: TS3Bucket; const xmlBucket: NSXMLElement ); virtual; abstract;
function getConnectionDataOfService: TAWSConnectionData; virtual; abstract;
function getEndPointOfRegion( const region: String ): String; virtual; abstract;
public
constructor Create( const authSession: TCloudDriverAuthSession );
@ -356,7 +357,7 @@ begin
http:= TMiniHttpClient.Create( urlString, HttpConst.Method.GET );
http.setQueryParams( queryItems );
http.addHeader( AWSConst.HEADER.CONTENT_SHA256, AWSConst.HEADER.CONTENT_SHA256_DEFAULT_VALUE );
_authSession.setAuthHeader( http );
TAWSAuthSession(_authSession).setAuthHeader( http, _connectionData );
cloudDriverResult:= TCloudDriverResult.Create;
httpResult:= http.connect;
@ -634,7 +635,6 @@ begin
bucket.creationTime:= ISO8601ToDate( TXmlUtil.getString( xmlBucket, 'CreationDate' ) );
self.constructBucket( bucket, xmlBucket );
buckets.Add( bucket );
Writeln( '>> ', bucket.connectionData.bucketName, ',', bucket.connectionData.region, ',', bucket.connectionData.endPoint, ',', bucket.creationTime );
end;
Result:= buckets;
end;
@ -646,23 +646,19 @@ end;
function TS3GetAllBucketsSession.listBuckets: TS3Buckets;
var
connectionData: TAWSConnectionData;
http: TMiniHttpClient = nil;
httpResult: TMiniHttpResult = nil;
cloudDriverResult: TCloudDriverResult = nil;
connectionData: TAWSConnectionData;
urlString: String;
queryItems: TQueryItemsDictonary;
begin
Result:= nil;
try
connectionData:= TAWSAuthSession(_authSession).defaultConnectionData;
connectionData:= self.getConnectionDataOfService;
urlString:= 'https://' + connectionData.endPoint + '/';
queryItems:= TQueryItemsDictonary.Create;
queryItems.Add( 'max-keys', '1000' );
http:= TMiniHttpClient.Create( urlString, HttpConst.Method.GET );
http.setQueryParams( queryItems );
http.addHeader( AWSConst.HEADER.CONTENT_SHA256, AWSConst.HEADER.CONTENT_SHA256_DEFAULT_VALUE );
_authSession.setAuthHeader( http );
TAWSAuthSession(_authSession).setAuthHeader( http, connectionData );
cloudDriverResult:= TCloudDriverResult.Create;
httpResult:= http.connect;
@ -752,13 +748,35 @@ var
parser: TS3PathParser;
connectionData: TAWSConnectionData;
listFolderSession: TCloudDriverListFolderSession;
procedure createBucketList;
var
bucket: TS3Bucket;
begin
// todo: multi thread
if _buckets <> nil then
Exit;
_buckets:= self.getAllBuckets;
if _buckets.Count > 0 then
Exit;
bucket:= TS3Bucket.Create;
bucket.connectionData:= self.getDefaultConnectionData;
if (bucket.connectionData.bucketName=EmptyStr) or
(bucket.connectionData.region=EmptyStr) or
(bucket.connectionData.endPoint=EmptyStr)
then begin
bucket.Free;
Exit;
end;
_buckets.add( bucket );
end;
begin
parser:= TS3PathParser.Create( path );
try
// todo: multi thread
if _buckets = nil then
_buckets:= self.getAllBuckets;
createBucketList;
if Path = EmptyStr then begin
Result:= TS3BucketsLister.Create( _buckets );
end else begin