📄 idhttpwebbrokerbridge.pas
字号:
unit IdHTTPWebBrokerBridge;
{$I IdCompilerDefines.inc}
(*
Original Author: Dave Nottage.
Modified by: Grahame Grieve
Modified by: Chad Z. Hower (Kudzu)
*)
interface
uses
Classes,
HTTPApp,
IdCustomHTTPServer, IdTCPServer, IdIOHandlerSocket,
WebBroker;
type
TIdHTTPAppRequest = class(TWebRequest)
protected
FRequestInfo : TIdHTTPRequestInfo;
FResponseInfo : TIdHTTPResponseInfo;
FThread : TIdPeerThread;
FClientCursor : Integer;
//
function GetDateVariable(Index: Integer): TDateTime; override;
function GetIntegerVariable(Index: Integer): Integer; override;
function GetStringVariable(Index: Integer): string; override;
public
constructor Create(AThread: TIdPeerThread; ARequestInfo: TIdHTTPRequestInfo;
AResponseInfo: TIdHTTPResponseInfo);
function GetFieldByName(const Name: string): string; override;
function ReadClient(var Buffer; Count: Integer): Integer; override;
function ReadString(Count: Integer): string; override;
function TranslateURI(const URI: string): string; override;
function WriteClient(var ABuffer; ACount: Integer): Integer; override;
{$IFDEF VCL6ORABOVE}
function WriteHeaders(StatusCode: Integer; const ReasonString, Headers: string): Boolean; override;
{$ENDIF}
function WriteString(const AString: string): Boolean; override;
end;
TIdHTTPAppResponse = class(TWebResponse)
protected
FContent: string;
FRequestInfo: TIdHTTPRequestInfo;
FResponseInfo: TIdHTTPResponseInfo;
FSent: Boolean;
FThread: TIdPeerThread;
//
function GetContent: string; override;
function GetDateVariable(Index: Integer): TDateTime; override;
function GetStatusCode: Integer; override;
function GetIntegerVariable(Index: Integer): Integer; override;
function GetLogMessage: string; override;
function GetStringVariable(Index: Integer): string; override;
procedure SetContent(const AValue: string); override;
procedure SetContentStream(AValue: TStream); override;
procedure SetStatusCode(AValue: Integer); override;
procedure SetStringVariable(Index: Integer; const Value: string); override;
procedure SetDateVariable(Index: Integer; const Value: TDateTime); override;
procedure SetIntegerVariable(Index: Integer; Value: Integer); override;
procedure SetLogMessage(const Value: string); override;
procedure MoveCookiesAndCustomHeaders;
public
constructor Create(AHTTPRequest: TWebRequest; AThread: TIdPeerThread;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
procedure SendRedirect(const URI: string); override;
procedure SendResponse; override;
procedure SendStream(AStream: TStream); override;
function Sent: Boolean; override;
end;
TIdHTTPWebBrokerBridge = class(TIdCustomHTTPServer)
protected
FWebModuleClass: TComponentClass;
//
procedure DoCommandGet(AThread: TIdPeerThread; ARequestInfo: TIdHTTPRequestInfo;
AResponseInfo: TIdHTTPResponseInfo); override;
public
constructor Create(AOwner: TComponent); override;
procedure RegisterWebModuleClass(AClass: TComponentClass);
end;
implementation
uses
IdException, IdHTTPHeaderInfo, IdGlobal, IdCookie,
SysUtils, Math;
type
// Make HandleRequest accessible
TWebDispatcherAccess = class(TCustomWebDispatcher);
const
INDEX_RESP_Version = 0;
INDEX_RESP_ReasonString = 1;
INDEX_RESP_Server = 2;
INDEX_RESP_WWWAuthenticate = 3;
INDEX_RESP_Realm = 4;
INDEX_RESP_Allow = 5;
INDEX_RESP_Location = 6;
INDEX_RESP_ContentEncoding = 7;
INDEX_RESP_ContentType = 8;
INDEX_RESP_ContentVersion = 9;
INDEX_RESP_DerivedFrom = 10;
INDEX_RESP_Title = 11;
//
INDEX_RESP_ContentLength = 0;
//
INDEX_RESP_Date = 0;
INDEX_RESP_Expires = 1;
INDEX_RESP_LastModified = 2;
//
//Borland coder didn't define constants in HTTPApp
INDEX_Method = 0;
INDEX_ProtocolVersion = 1;
INDEX_URL = 2;
INDEX_Query = 3;
INDEX_PathInfo = 4;
INDEX_PathTranslated = 5;
INDEX_CacheControl = 6;
INDEX_Date = 7;
INDEX_Accept = 8;
INDEX_From = 9;
INDEX_Host = 10;
INDEX_IfModifiedSince = 11;
INDEX_Referer = 12;
INDEX_UserAgent = 13;
INDEX_ContentEncoding = 14;
INDEX_ContentType = 15;
INDEX_ContentLength = 16;
INDEX_ContentVersion = 17;
INDEX_DerivedFrom = 18;
INDEX_Expires = 19;
INDEX_Title = 20;
INDEX_RemoteAddr = 21;
INDEX_RemoteHost = 22;
INDEX_ScriptName = 23;
INDEX_ServerPort = 24;
INDEX_Content = 25;
INDEX_Connection = 26;
INDEX_Cookie = 27;
INDEX_Authorization = 28;
{ TIdHTTPAppRequest }
constructor TIdHTTPAppRequest.Create(AThread: TIdPeerThread; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
Var
i: Integer;
begin
FThread := AThread;
FRequestInfo := ARequestInfo;
FResponseInfo := AResponseInfo;
inherited Create;
FClientCursor := 0;
for i := 0 to ARequestInfo.Cookies.Count - 1 do begin
CookieFields.Add(ARequestInfo.Cookies[i].ClientCookie);
end;
end;
function TIdHTTPAppRequest.GetDateVariable(Index: Integer): TDateTime;
var
LValue: string;
begin
LValue := GetStringVariable(Index);
if Length(LValue) > 0 then begin
Result := ParseDate(LValue)
end else begin
Result := -1;
end;
end;
function TIdHTTPAppRequest.GetIntegerVariable(Index: Integer): Integer;
begin
Result := StrToIntDef(GetStringVariable(Index), -1)
end;
function TIdHTTPAppRequest.GetStringVariable(Index: Integer): string;
var
s: string;
begin
case Index of
INDEX_Method : Result := FRequestInfo.Command;
INDEX_ProtocolVersion : Result := FRequestInfo.Version;
INDEX_URL : Result := FRequestInfo.Document;
INDEX_Query : Result := FRequestInfo.UnparsedParams;
INDEX_PathInfo : Result := FRequestInfo.Document;
INDEX_PathTranslated : Result := FRequestInfo.Document; // it's not clear quite what should be done here - we can't translate to a path
INDEX_CacheControl : Result := GetFieldByName('CACHE_CONTROL'); {do not localize}
INDEX_Date : Result := GetFieldByName('DATE'); {do not localize}
INDEX_Accept : Result := FRequestInfo.Accept;
INDEX_From : Result := FRequestInfo.From;
INDEX_Host: begin
s := FRequestInfo.Host;
Result := Fetch(s, ':');
end;
INDEX_IfModifiedSince : Result := GetFieldByName('IF_MODIFIED_SINCE'); {do not localize}
INDEX_Referer : Result := FRequestInfo.Referer;
INDEX_UserAgent : Result := FRequestInfo.UserAgent;
INDEX_ContentEncoding : Result := FRequestInfo.ContentEncoding;
INDEX_ContentType : Result := FRequestInfo.ContentType;
INDEX_ContentLength : Result := IntToStr(Length(FRequestInfo.UnparsedParams));
INDEX_ContentVersion : Result := GetFieldByName('CONTENT_VERSION'); {do not localize}
INDEX_DerivedFrom : Result := GetFieldByName('DERIVED_FROM'); {do not localize}
INDEX_Expires : Result := GetFieldByName('EXPIRES'); {do not localize}
INDEX_Title : Result := GetFieldByName('TITLE'); {do not localize}
INDEX_RemoteAddr : Result := FRequestInfo.RemoteIP;
INDEX_RemoteHost : Result := GetFieldByName('REMOTE_HOST'); {do not localize}
INDEX_ScriptName : Result := '';
INDEX_ServerPort: begin
Result := FRequestInfo.Host;
Fetch(Result, ':');
if Length(Result) = 0 then begin
Result := IntToStr(TIdIOHandlerSocket(FThread.Connection.IOHandler).Binding.Port);
// Result := '80';
end;
end;
INDEX_Content : Result := FRequestInfo.UnparsedParams;
INDEX_Connection : Result := GetFieldByName('CONNECTION'); {do not localize}
INDEX_Cookie : Result := ''; // not available at present. FRequestInfo.Cookies....;
INDEX_Authorization : Result := GetFieldByName('AUTHORIZATION'); {do not localize}
else
Result := '';
end;
end;
function TIdHTTPAppRequest.GetFieldByName(const Name: string): string;
begin
Result := FRequestInfo.RawHeaders.Values[Name];
end;
function TIdHTTPAppRequest.ReadClient(var Buffer; Count: Integer): Integer;
begin
Result := Min(Count, length(FRequestInfo.UnparsedParams)) - FClientCursor;
if Result > 0 then begin
Move(FRequestInfo.UnparsedParams[FClientCursor + 1], Buffer, Result);
Inc(FClientCursor, Result);
end else begin
// well, it shouldn't be less than 0. but let's not take chances
Result := 0;
end;
end;
function TIdHTTPAppRequest.ReadString(Count: Integer): string;
var
LLength: Integer;
begin
LLength := Min(Count, length(FRequestInfo.UnparsedParams)) - FClientCursor;
if LLength > 0 then
begin
Result := copy(FRequestInfo.UnparsedParams, FClientCursor, LLength);
inc(FClientCursor, LLength);
end
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -