本机Delphi HTTPClient是否支持SNI?

时间:2019-04-03 18:11:00

标签: http delphi sni

我们必须在其余请求中包括SNI(Server_Name_Indication),因为服务器将在不久的将来托管多个虚拟域。我们使用的是在运行时创建的标准THTTPClient组件。 一旦我们添加了具有新证书的新域,我们就会收到一个例外 “服务器证书无效或不存在” (从德语错误文本翻译而来)

是否有一个特殊的标头值来像基本身份验证那样存档SNI?

下面是我们代码的简化版本(没有日志记录,没有代理,伪造的URL)。抱歉,我无法提供我们正在使用的真实URL。

我们希望我们必须增加GetRequest方法,但是没有找到任何示例或提示。

unit Unit1;

interface

uses
  Winapi.Windows, WinApi.WinHTTP, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
  System.Net.HTTPClient;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    function PostRequest(const cRequest, cBody: string): string;
  public
    { Public declarations }
  end;

type
  TMyRestClient = class(TObject)
  private
    fHTTPClient: THTTPClient;
    fSysUrl: string;
    fUserID: string;
    fPassWD: string;
    //...
    function GetRequest(const cMethod, cUrl: string): IHTTPRequest;
  public
    constructor Create(const cUrl: string);
    destructor Destroy; override;
    function Post(const cRequest, cBody: string): string;

    //...
    property SystemUrl: string read fSysUrl write fSysUrl;
    property Username: string read fUserID write fUserID;
    property Password: string read fPassWD write fPassWD ;
  end;

var
  Form1: TForm1;

implementation

uses
  System.SysUtils, System.Variants, System.NetEncoding;

{$R *.dfm}

constructor TMyRestClient.Create(const cUrl: string);
begin
  fHTTPClient := THTTPClient.Create;
  SystemUrl := cUrl;
end;

destructor TMyRestClient.Destroy;
begin
  FreeAndNil(fHTTPClient);
  inherited Destroy;
end;

function TMyRestClient.GetRequest(const cMethod, cUrl: string): IHTTPRequest;
begin
  Result := fHTTPClient.GetRequest(cMethod, cUrl);
  Result.AddHeader('content-type', 'appplication/json');
  if (Password <> '') then
    Result.AddHeader('Authorization', 'Basic ' + TNetEncoding.Base64.Encode(Username + ':' + Password));
end;

function TMyRestClient.Post(const cRequest, cBody: string): string;
var
  iRequest: IHTTPRequest;
  iResponse: IHTTPResponse;
  aBody: TStringStream;
begin
  iRequest := GetRequest('POST', Format('%s/%s', [SystemUrl, cRequest]));
  aBody := TStringStream.Create(UTF8String(cBody));
  try
    iRequest.SourceStream := aBody;
    iResponse := fHTTPClient.Execute(iRequest);
  finally
    aBody.DisposeOf;
  end;
  if (iResponse.StatusCode <> HTTP_STATUS_OK) then
    raise Exception.CreateFmt('Post: %s failed (Code %d) %', [cRequest, iResponse.StatusCode, iResponse.StatusText]);
  Result := iResponse.ContentAsString;
end;

function TForm1.PostRequest(const cRequest, cBody: string): string;
var
  xClient: TMyRestClient;
begin
  xClient := TMyRestClient.Create('www.myserver.com/demo');
  try
    // Basic authentification (not used)
    xClient.Username := '';
    xClient.Password := '';
    Result := xClient.Post(cRequest, cBody);
  finally
    xClient.DisposeOf
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit1.Text := PostRequest('retrieve/paramvalue', '{''PARAM'':''VERSION''}' );
end;

0 个答案:

没有答案