2,496
社区成员
发帖
与我相关
我的任务
分享
unit duAliYun_OSS;
interface
uses
REST.Client, system.JSON, system.SysUtils, Vcl.Dialogs;
function invokeAliOSS(objName, fileName, method: PChar; AHost, Bucket, AccessKey, AccessSecret: PChar): Boolean; stdcall;
implementation
uses
REST.Types, DateUtils, Soap.EncdDecd, cHash, system.Classes, system.NetEncoding,
dulogclass, IPPeerCommon, idhttp, fmclient;
function DateTimeToGMT(const ADate: TDateTime): string;
const
WEEK: array[1..7] of PChar = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
MonthDig: array[1..12] of PChar = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
var
wWeek, wYear, wMonth, wDay, wHour, wMin, wSec, wMilliSec: Word;
sWeek, sMonth: string;
begin
DecodeDateTime(ADate, wYear, wMonth, wDay, wHour, wMin, wSec, wMilliSec);
wWeek := DayOfWeek(ADate);
sWeek := WEEK[wWeek];
sMonth := MonthDig[wMonth];
Result := Format('%s, %.2d %s %d %.2d:%.2d:%.2d GMT', [sWeek, wDay, sMonth, wYear, wHour, wMin, wSec]);
end;
// 加密算法来自http://fundementals.sourceforge.net
function signString(source, secret: AnsiString): string;
var
d: T160BitDigest;
begin
d := CalcHMAC_SHA1(secret, source);
Result := string(EncodeBase64(@d.Bytes, Length(d.Bytes)));
end;
function composeStringToSign(method, contentMD5, contentType, date, signHeaders, resource: string): string;
begin
Result := method + #10 + contentMD5 + #10 + contentType + #10 + date + #10 + signHeaders + resource;
end;
function invokeAliOSS(objName, fileName, method: PChar; AHost, Bucket, AccessKey, AccessSecret: PChar): Boolean; stdcall;
var
vItem: TRESTRequestParameter;
stringToSign, signature, sDate, resource, accessKeyId, accessKeySecret: string;
bucketID, path, host, sContentType, contentMD5: string;
contentType: TRESTContentType;
d: T128BitDigest;
AStream: TMemoryStream;
LBytes: TBytes;
req: TRESTRequest;
begin
Result := False;
if not FileExists(fileName) then
Exit;
try
if not Assigned(Form1) then
Form1 := TForm1.Create(nil);
req := Form1.RESTRequest1;
bucketID := Bucket; //
path := '/' + objName;
host := AHost;
host := LowerCase(host);
host := StringReplace(host, 'http://', '', [rfReplaceAll, rfIgnoreCase]);
if Length(host) > 0 then
if host[Length(host)] = '/' then
Delete(host, Length(host), 1);
host := bucketID + '.' + host;
contentType := TRESTContentType.ctIMAGE_JPEG; //TRESTContentType.ctAPPLICATION_OCTET_STREAM; //TRESTContentType.ctIMAGE_JPEG;//
sContentType := ContentTypeToString(TRESTContentType.ctIMAGE_JPEG); // 'application/octet-stream'; // 'application/json';
accessKeyId := AccessKey;
accessKeySecret := AccessSecret;
AStream := TMemoryStream.Create;
try
// sDate:='Tue, 13 Mar 2018 03:11:33 GMT';
sDate := DateTimeToGMT(TTimeZone.local.ToUniversalTime(Now()));
resource := '/' + bucketID + '/' + objName;
req.ClearBody();
req.Params.Clear();
// req.Client.BaseURL:='http://localhost:8080'+path;
req.Client.BaseURL := 'https://' + host + path;
AStream.LoadFromFile(fileName);
SetLength(LBytes, AStream.Size);
AStream.Seek(0, TSeekOrigin.soBeginning);
AStream.Read(LBytes, 0, AStream.Size);
req.AddBody(AStream);
d := CalcMD5(LBytes[0], AStream.Size);
contentMD5 := string(EncodeBase64(@d.Bytes, Length(d.Bytes)));
finally
AStream.Free;
end;
stringToSign := composeStringToSign(method, contentMD5, sContentType, sDate, '', resource);
signature := signString(AnsiString(stringToSign), AnsiString(accessKeySecret));
vItem := req.Params.AddItem;
vItem.Kind := TRESTRequestParameterKind.pkHTTPHEADER;
vItem.contentType := contentType;
vItem.Options := [TRESTRequestParameterOption.poDoNotEncode];
vItem.Name := 'authorization';
vItem.Value := 'OSS ' + accessKeyId + ':' + signature;
vItem := req.Params.AddItem;
vItem.Kind := TRESTRequestParameterKind.pkHTTPHEADER;
vItem.contentType := contentType;
vItem.Options := [TRESTRequestParameterOption.poDoNotEncode];
vItem.Name := 'host';
vItem.Value := host;
vItem := req.Params.AddItem;
vItem.Kind := TRESTRequestParameterKind.pkHTTPHEADER;
vItem.contentType := contentType;
vItem.Options := [TRESTRequestParameterOption.poDoNotEncode];
vItem.Name := 'date';
vItem.Value := sDate;
vItem := req.Params.AddItem;
vItem.Kind := TRESTRequestParameterKind.pkHTTPHEADER;
vItem.contentType := contentType;
vItem.Options := [TRESTRequestParameterOption.poDoNotEncode];
vItem.Name := 'content-md5';
vItem.Value := contentMD5;
req.Accept := sContentType;
req.Client.contentType := sContentType;
//G_Log.WriteLogFile(req.Client.BaseURL);
if (method = 'PUT') then
req.method := TRESTRequestMethod.rmPUT
else if (method = 'GET') then
req.method := TRESTRequestMethod.rmGET;
req.Execute();
Result := req.Response.StatusCode = 200;
if Result = False then
G_Log.WriteLogFile(AnsiString(req.Response.Content));
except
on e: Exception do
begin
G_Log.WriteLogFile(AnsiString(e.Message));
G_Log.WriteLogFile(AnsiString(req.Response.Content));
end;
end;
end;
end.