delphi调用阿里云的函数计算服务FC

阿里云函数计算:https://www.aliyun.com/product/fc?spm=5176.7933691.765261.210.ijPFRC

delphi版本:Embarcadero® Delphi 10.2 Version 25.0.26309.314 

阿里云最开始有PaaS层的“云引擎ACE”,像百度的“应用引擎BAE”一样,但是在2016时,阿里把它关闭了。

目前,阿里的“函数计算FC”有点类似这个,但感觉比之前ACE限制太多,要访问数据啥的第三方模组,需要使用docker等。

FC的调用SDK没有Delphi的版本,参照javascript的版本,修改了一个,可以运作:

unit wxhAliYun_FC;

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

  function invokeAliFC(req:TRESTRequest;funName:string;body:string):TJSONValue;

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:T256BitDigest;
begin
  d:=CalcHMAC_SHA256(secret,source);
  Result:=EncodeBase64(@d.Bytes,length(d.Bytes));
end;

function composeStringToSign(method, contentMD5,contentType,date,signHeaders,path:string):string;
begin
  Result:= method+#10+contentMD5+#10+contentType+#10+date+#10+signHeaders+#10+path;
end;

function invokeAliFC(req:TRESTRequest;funName:string;body:string):TJSONValue;
var
  vItem:TRESTRequestParameter;
  stringToSign,signature,sDate:string;
  accountID,path,host,sContentType,contentMD5:string;
  contentType:TRESTContentType;
  d:T128BitDigest;
  s:ansistring;
  b0,b:TBytes;
begin
  accountID:='你的账号ID';
  path:='/2016-08-15/services/flowers/functions/'+funName+'/invocations';
  host:=accountID+'.fc.cn-shanghai.aliyuncs.com';
  contentType:=TRESTContentType.ctAPPLICATION_OCTET_STREAM;
  sContentType:='application/octet-stream';//'application/json';
  //sDate:='Sat, 02 Sep 2017 03:08:12 GMT';
  sDate:=DateTimeToGMT(TTimeZone.Local.ToUniversalTime(now()));

  req.ClearBody();
  req.Params.Clear();

  req.Client.BaseURL:='http://localhost:8080'+path;
  //req.Client.BaseURL:='http://'+host+path;

  d:=CalcMD5(body);
  SetLength(s, Length(d.Bytes)*2);
  {$IFDEF NEXTGEN}
  SetLength(b,Length(d.Bytes)*2);
  b0:=BytesOf(@d.Bytes,length(d.Bytes));
  BinToHex(b0,0, b, 0,Length(b));
  s:=StringOf(b);
  {$ELSE}
  BinToHex(@d.Bytes[0], PAnsiChar(s), Length(d.Bytes));
  {$ENDIF}

  s:=LowerCase(s);
  contentMD5:=EncodeBase64(PAnsiChar(s),Length(s));
  stringToSign := composeStringToSign(
    'POST',
    contentMD5,
    sContentType,
    sDate,
    'x-fc-account-id:'+accountID,
    path);
  signature := signString(stringToSign,'你的密钥');

  vItem:=req.Params.AddItem;
  vItem.Kind:=TRESTRequestParameterKind.pkHTTPHEADER;
  vItem.ContentType:=contentType;
  vItem.Options:=[TRESTRequestParameterOption.poDoNotEncode];
  vItem.Name:='authorization';
  vItem.Value:='FC 你的访问ID:'+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:='x-fc-account-id';
  vItem.Value:=accountID;

  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);
  req.Method:=TRESTRequestMethod.rmPOST;

  req.Execute;
  Result:=req.Response.JSONValue;
end;

end.
注意:

  1. MD5,HMAC-SHA256加密算法来自http://fundementals.sourceforge.net,delphi自带的IdHMACSHA256执行有错。
  2. 其中的fc.cn-shanghai.aliyuncs.com,根据你实际注册FC的服务区域修改。

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

猜你喜欢

转载自blog.csdn.net/acrodelphi/article/details/77816433
今日推荐