我正在尝试使用XE7连接到内部REDCap服务器。REDCap详细描述了https://education.arcus.chop.edu/redcap-api/上的API和https://bbmc.ouhsc.edu/redcap/api上的带有测试令牌密钥的测试服务器。R中的https://mran.microsoft.com/snapshot/2015-08-18/web/packages/REDCapR/vignettes/TroubleshootingApiCalls.html有帮助。
我可以用Curl和PostMan连接到测试现场。我的问题是如何在 Delphi 中使用SSL实现这一点。
PostMan的Curl脚本:
curl --location 'https://bbmc.ouhsc.edu/redcap/api/' \
--data-urlencode 'token=9A81268476645C4E5F03428B8AC3AA7B' \
--data-urlencode 'content=record' \
--data-urlencode 'action=export' \
--data-urlencode 'format=csv' \
--data-urlencode 'rawOrLabel=label'
经过大量搜索,这是我的 Delphi 代码。我错过了什么?IdLogFile1
是表单上的一个组件。
function TForm1.IdSSLIOHandlerSocketOpenSSL1VerifyPeer(Certificate: TIdX509; AOk: Boolean; ADepth, AError: Integer): Boolean;
begin
showmessage('at IOhandler');
Result := true; // always returns true
end;
procedure TForm1.idHTTP2BtnClick(Sender: TObject);
var post : string;
Params : TStringList;
idHTTP : TIdHTTP;
SSL1 : TIdSSLIOHandlerSocketOpenSSL;
status : integer;
response : TstringStream;
begin
params := TStringList.Create;
idHTTP := TIdHTTP.Create(nil);
SSL1 := TIdSSLIOHandlerSocketOpenSSL.Create(idHTTP);
response := TstringStream.create;
SSL1.SSLOptions.Mode := sslmClient ;
SSL1.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2 ];// [ sslvSSLv3, sslvSSLv23,sslvSSLv2, sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
SSL1.SSLOptions.VerifyDepth := 0;
SSL1.OnVerifyPeer := IdSSLIOHandlerSocketOpenSSL1VerifyPeer;
SSL1.SSLOptions.VerifyMode := [ ];
idHTTP.IOHandler := SSL1;
memo1.Lines.clear;
idHTTP.ReadTimeout := 3000;
idHTTP.ConnectTimeout := 3000;
idHttp.Request.BasicAuthentication := false;
try
idHTTP.HandleRedirects := true;
idHTTP.Intercept := IdLogFile1;
IdLogFile1.Active := true;
IdHttp.Request.CustomHeaders.Clear;
IdHttp.Request.CustomHeaders.Values['token'] := '9A81268476645C4E5F03428B8AC3AA7B';
IdHttp.Request.CustomHeaders.Values['content'] := 'record';
IdHttp.Request.CustomHeaders.Values['action'] := 'export';
IdHttp.Request.CustomHeaders.Values['format'] := 'csv';
IdHttp.Request.CustomHeaders.Values['rawOrLabel'] := 'label';
IdHttp.Request.CustomHeaders.Values['verify_ssl'] := 'false';
IdHttp.Request.CustomHeaders.Values['ssl_verify'] := 'false'; //various verify options ?
IdHttp.Request.CustomHeaders.Values['ssl_verifypeer'] := 'false';
idHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
IdHTTP.Request.Charset := 'utf-8';
idHTTP.HTTPOptions := [hoKeepOrigProtocol, hoForceEncodeParams];
idHTTP.Post('https://bbmc.ouhsc.edu/redcap/api/', params, response );
finally
memo1.Lines.add(' ');
memo1.lines.add(idHTTP.ResponseText);
memo1.Lines.add(' ');
status := idHTTP.ResponseCode;
memo1.Lines.Add('code: ' + inttostr(status));
idhttp.Disconnect;
end;
Params.Free;
SSL1.Free;
idHTTP.Free;
response.Free;
end;
2条答案
按热度按时间eoxn13cs1#
您正在正确设置TLS连接(前提是Indy可以找到 * 适当的 * OpenSSL DLL)。
您没有正确设置的是数据参数。Curl的
--data-urlencode
命令将数据放在HTTP请求正文中,而不是HTTP头中。因此,您需要将数据放入正在发布的TStringList
中(TIdHTTP
将为您处理URL编码)。试试这个:
j2datikz2#
两个更简单的替代方案是System.Net.HttpClient和mORMot。两者都按预期工作,结果相同。用 Delphi 11测试。