delphi调用阿里云的对象存储服务OSS

阿里云的对象存储:https://www.aliyun.com/product/oss?spm=5176.8142029.388261.220.tpdG6e

Delphi版本:Embarcadero® Delphi 10.2 Version 25.0.26309.314 

其开发文档中没有提供Delphi的SDK,参考javascript的SDK,大致修改后可以运作:

unit wxhAliYun_OSS;

interface
uses
  REST.Client,system.JSON,system.SysUtils;

  function invokeAliOSS(req:TRESTRequest;objName,method,body:string):string;

implementation
uses
  REST.Types,DateUtils,EncdDecd,cHash,System.Classes;

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:=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+#10+resource;
end;

function invokeAliOSS(req:TRESTRequest;objName:string;method,body:string):string;
var
  vItem:TRESTRequestParameter;
  stringToSign,signature,sDate,resource,accessKeyId,accessKeySecret:string;
  bucketID,path,host,sContentType,contentMD5:string;
  contentType:TRESTContentType;
  d:T128BitDigest;
begin
  bucketID:='你的桶';
  path:='/'+objName;
  host:=bucketID+'.oss-cn-shanghai.aliyuncs.com';
  contentType:=TRESTContentType.ctAPPLICATION_OCTET_STREAM;
  sContentType:='application/octet-stream';//'application/json';
  accessKeyId:='你的key';
  accessKeySecret:='你的密钥';

  //sDate:='Sat, 02 Sep 2017 03:08:12 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:='http://'+host+path;

  d:=CalcMD5(body);
  contentMD5:=EncodeBase64(@d.Bytes,Length(d.Bytes));

  stringToSign := composeStringToSign(
    method,
    contentMD5,
    sContentType,
    sDate,
    '',
    resource);
  signature := signString(stringToSign,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;

  req.AddBody(body);
  if (method='PUT') then
    req.Method:=TRESTRequestMethod.rmPUT
  else if (method='GET') then
    req.Method:=TRESTRequestMethod.rmGET;

  req.Execute();
  Result:=req.Response.Content;
end;

end.
其中,注意:

  1. MD5和HMAC-SHA1的算法是来自http://fundementals.sourceforge.net,Delphi自带的IdHMACSHA1运行不起来。
  2. 其中的oss-cn-shanghai.aliyuncs.com,与你申请的OSS所在物理区域有关,需要根据实际情况调整。

客户端调用方法:

procedure TFormRanks.FormShow(Sender: TObject);
var
  data:string;
  i: Integer;
  users:TJSONArray;
begin
  //从阿里云的对象存储服务获取数据
  data:=wxhAliYun_OSS.invokeAliOSS(RESTRequest1,'scores','GET','');
  users:=TJSONArray(TJSONObject.ParseJSONValue(data));

  //使用阿里云引擎,2016年时该服务关闭了。
  {RESTClient1.BaseURL:='http://flowers2016.aliapp.com/getRanks';
  RESTRequest1.Execute;
  users:=TJSONArray(RESTResponse1.JSONValue);}

  Grid1.RowCount:=users.Size;
  for i := 0 to users.Size-1 do
  begin
    self.Grid1.Cells[0,i]:=InttoStr(i+1);
    self.Grid1.Cells[1,i]:=users.Items[i].GetValue<string>('userID');
    self.Grid1.Cells[2,i]:=users.Items[i].GetValue<string>('score');
    self.Grid1.Cells[3,i]:=users.Items[i].GetValue<string>('score')+'/'+users.Items[i].GetValue<string>('cellCount');
  end;
end;


原创文章 159 获赞 11 访问量 36万+

猜你喜欢

转载自blog.csdn.net/acrodelphi/article/details/77816242