Поддерживает ли нативный Delphi HTTPClient SNI? - PullRequest
1 голос
/ 03 апреля 2019

Мы должны включить 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;
...