2019/10/02

TIdHTTPWebBrokerBridge效能和驗證(Authorization)

圖/取自網路


TIdHTTPWebBrokerBridge 目前會用到的地方大概只有 Stand-Alone 場合,更偏向於 Debug 應用。

看到 Marco 寫的 Thread Pooling 文章,不太能夠理解只是Debug為什麼還需要這麼大的效能。

Thread Pooling

Marco原文是這樣說的:
Regarding threading, creating one for each incoming request is Indy’s IdHTTPServer default configuration, but you can tune it adding code to the server main form, which creates and manages the Web server component.
 大意上是說每個Client都會建立一條Thread,所以用了Thread Pooling後可以預先把Thread開好,就不用花時間在每次連接的Thread建立時間。

另一個好處是:限制Client數上限(MaxConnections),總比Server崩潰要好一點。

使用它不吃虧,就記錄一下要怎麼用吧!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
procedure TForm2.FormCreate(Sender: TObject);
var
  SchedulerOfThreadPool: TIdSchedulerOfThreadPool;
begin
  FServer := TIdHTTPWebBrokerBridge.Create(Self);

  // Thread Pooling uses IdSchedulerOfThreadPool
  SchedulerOfThreadPool := TIdSchedulerOfThreadPool.Create(FServer);
  SchedulerOfThreadPool.PoolSize := 50;
  FServer.Scheduler := SchedulerOfThreadPool;

  FServer.MaxConnections := 150;
end


Authorization

隨著前端科技日新月異,Authorization現在多了像:OAuth, OAuth2等方法。

這個 Header 也太複雜……(汗)

已知DataSnap / WebBroker所使用的驗證方式為Basic:
Authorization:Basic BASE64_ENCODE(USER+':'+PASSWORD)

現在多了Bearer:
Authorization:Bearer TOKEN_ENCODE(AWS4-HMAC-SHA256)

使用上我得到下面的內容:



在 IdCustomHTTPServer 單元中,可以看到 INDY 只針對【Basic】處理,其它一律不認識。


沒救,結案。































 
等等,有沒有看到上面的【if Assigned(FOnPaseAuthentication then begin】?

原來 Indy 保留了讓我們自訂 Authorization 的方法,程式碼如下:

procedure T大匠之風.OnDoParseAuthentication(AContext: TIdContext; const AAuthType,
  AAuthData: String; var VUsername, VPassword: String; var VHandled: Boolean);
  function DoParseAuthentication(ASender: TIdContext; const AAuthType,
    AAuthData: String; var VUsername, VPassword: String): Boolean;
  var
    s: String;
  begin
    Result := False;
    if TextIsSame(AAuthType, 'Basic') then begin    {Do not Localize}
      with TIdDecoderMIME.Create do try
        s := DecodeString(AAuthData);
      finally Free; end;
      VUsername := Fetch(s, ':');    {Do not Localize}
      VPassword := s;
      Result := True;
    end
    else if TextIsSame(AAuthType, 'Bearer') then
    begin
      // TODO:
    end;
  end;
begin
  VHandled := DoParseAuthentication(AContext, AAuthType, AAuthData, VUsername, VPassword);
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  FServer := TIdHTTPWebBrokerBridge.Create(Self);
  FServer.OnParseAuthentication := T大匠之風.OnDoParseAuthentication;
end;


利用自訂 Authorization 事件就可以擴充自己設計的 Authorization 內容。

TODO的地方就留給各位自行發揮,有任何建議請留言讓我知道。



後記:Indy 的水也太深,每次要用都得踩上不少雷,想解鎖成就者必玩! (大笑)

更新

ISAPI DLL

另外,ISAPI DLL 開發時,DoParseAuthentication 也無法應用在 ISAPI Application 上,這部份目前只能使用 TWebModule.onBeforeDispatch 事件對 TWebRequest 進行 OAuth (bearer token) 二次處理驗證工作,開發時必須要留意這點。

DataSnap Service

改採 DataSnap Service 時,可對 TDSHttpService 進行如下的程式碼設計:

TIdHTTPServer(DSHTTPService1.HttpServer).OnParseAuthentication := Self.OnDoParseAuthentication;

DSHTTPService.Server 拿去裝 TDSServer,所以用 HttpServer 進行改裝。


See also:

2 則留言: