288 lines
8.7 KiB
ObjectPascal
288 lines
8.7 KiB
ObjectPascal
unit uROIndySuperHttpChannel;
|
|
|
|
{----------------------------------------------------------------------------}
|
|
{ RemObjects SDK Library - Indy Components }
|
|
{ }
|
|
{ compiler: Delphi 5 and up, Kylix 2 and up }
|
|
{ platform: Win32, Linux }
|
|
{ }
|
|
{ (c)opyright RemObjects Software. all rights reserved. }
|
|
{ }
|
|
{ Using this code requires a valid license of the RemObjects SDK }
|
|
{ which can be obtained at http://www.remobjects.com. }
|
|
{----------------------------------------------------------------------------}
|
|
|
|
{$I RemObjects.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, uROClient, uROClientIntf,
|
|
{$IFDEF RemObjects_UseEncryption} uRoEncryption, {$ENDIF}
|
|
uROIndyTCPChannel, IdHTTP, uROBaseSuperHttpChannel, idstackconsts;
|
|
|
|
type
|
|
TROIndySuperHttpChannel = class(TROBaseSuperHttpChannel)
|
|
private
|
|
fClientWait,
|
|
fClientRequest: TIdHTTP;
|
|
fTargetUrl: String;
|
|
fDisableNagle: Boolean;
|
|
protected
|
|
{ IROHTTPTransport }
|
|
procedure SocketConnectedRequest(Sender: TObject);
|
|
procedure SocketConnectedWait(Sender: TObject);
|
|
function GetClientAddress : string; override;
|
|
procedure SetHeaders(const aName, aValue : string); override;
|
|
function GetHeaders(const aName : string) : string; override;
|
|
function GetContentType : string; override;
|
|
procedure SetContentType(const aValue : string); override;
|
|
function GetUserAgent : string; override;
|
|
procedure SetUserAgent(const aValue : string); override;
|
|
function GetTargetURL : string; override;
|
|
procedure SetTargetURL(const aValue : string); override;
|
|
procedure SetPathInfo (const aValue : string); override;
|
|
function GetPathInfo : string; override;
|
|
function GetQueryString : string; override;
|
|
function GetLocation : string; override;
|
|
function GetQueryParameter(const aName: string): string; override;
|
|
protected
|
|
procedure CancelRequest(aWaitingThread: Boolean); override;
|
|
procedure DispatchHttpRequest(aWaitingThread: Boolean;
|
|
aRequest: TDynByteArray; out aResponse: TDynByteArray); override;
|
|
public
|
|
constructor Create(aOwner: TCOmponent); override;
|
|
destructor Destroy; override;
|
|
{$IFDEF FPC}
|
|
property SessionId;
|
|
{$ENDIF}
|
|
published
|
|
{$IFNDEF FPC}
|
|
property SessionId;
|
|
{$ENDIF}
|
|
property Active;
|
|
property MaxPackageSize;
|
|
property TargetUrl: String read fTargetUrl write fTargetUrl;
|
|
property ClientWait: TIdHTTP read fClientWait;
|
|
property ClientRequest: TIdHTTP read fClientRequest;
|
|
property RequestTimeout;
|
|
property ConnectTimeout;
|
|
property HttpRequestTimeout;
|
|
property DisableNagle: Boolean read fDisableNagle write fDisableNagle default true;
|
|
|
|
property DispatchOptions;
|
|
property ServerLocators;
|
|
property OnServerLocatorAssignment;
|
|
end;
|
|
|
|
implementation
|
|
uses
|
|
uRORes,uROHTTPTools;
|
|
|
|
{ TROIndySuperHttpChannel }
|
|
|
|
procedure TROIndySuperHttpChannel.SocketConnectedRequest(Sender: TObject);
|
|
begin
|
|
|
|
if DisableNagle then begin
|
|
{$IFDEF RemObjects_INDY8}
|
|
fClientRequest.Binding.SetSockOpt(Id_IPPROTO_TCP, Id_TCP_NODELAY, PChar(@Id_SO_True), SizeOf(Id_SO_True));
|
|
{$ELSE}
|
|
{$IFDEF RemObjects_INDY9}
|
|
fClientRequest.Socket.Binding.SetSockOpt(Id_IPPROTO_TCP, Id_TCP_NODELAY, PChar(@Id_SO_True), SizeOf(Id_SO_True));
|
|
{$ELSE}
|
|
fClientRequest.Socket.Binding.SetSockOpt(Id_IPPROTO_TCP, Id_TCP_NODELAY, Id_SO_True);
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
end;
|
|
end;
|
|
procedure TROIndySuperHttpChannel.SocketConnectedWait(Sender: TObject);
|
|
begin
|
|
|
|
if DisableNagle then begin
|
|
{$IFDEF RemObjects_INDY8}
|
|
fClientWait.Binding.SetSockOpt(Id_IPPROTO_TCP, Id_TCP_NODELAY, PChar(@Id_SO_True), SizeOf(Id_SO_True));
|
|
{$ELSE}
|
|
{$IFDEF RemObjects_INDY9}
|
|
fClientWait.Socket.Binding.SetSockOpt(Id_IPPROTO_TCP, Id_TCP_NODELAY, PChar(@Id_SO_True), SizeOf(Id_SO_True));
|
|
{$ELSE}
|
|
fClientWait.Socket.Binding.SetSockOpt(Id_IPPROTO_TCP, Id_TCP_NODELAY, Id_SO_True);
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
end;
|
|
end;
|
|
|
|
procedure TROIndySuperHttpChannel.CancelRequest(aWaitingThread: Boolean);
|
|
var
|
|
lSock: TIdHTTP;
|
|
begin
|
|
try
|
|
if aWaitingThread then lSock := fClientWait else lSock := fClientRequest;
|
|
{$IFDEF RemOBjects_INDY8}
|
|
lSock.Binding.CloseSocket();
|
|
{$ELSE}
|
|
{$IFDEF RemObjects_INDY10}
|
|
if assigned(lSock.Socket) and (lSock.Socket.Connected) then
|
|
lSock.Socket.Close;
|
|
{$ELSE}
|
|
lSock.DisconnectSocket;
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
except
|
|
// indy will release an exception when closing
|
|
end;
|
|
end;
|
|
|
|
{$IFDEF RemObjects_INDY10}
|
|
type
|
|
TIdIndy10HackClient = class(TIdHTTP)
|
|
public
|
|
property OnConnected;
|
|
end;
|
|
{$ELSE}
|
|
type
|
|
TIdIndy10HackClient = TIdHTTP;
|
|
{$ENDIF}
|
|
|
|
constructor TROIndySuperHttpChannel.Create(aOwner: TCOmponent);
|
|
begin
|
|
inherited Create(aOwner);
|
|
fDisableNagle := true;
|
|
fClientWait := TIdHTTP.Create(nil);
|
|
TIdIndy10HackClient(fClientWait).OnConnected := SocketConnectedWait;
|
|
fClientWait.Request.UserAgent := str_ProductName;
|
|
|
|
fClientRequest := TIdHTTP.Create(nil);
|
|
TIdIndy10HackClient(fClientRequest).OnConnected := SocketConnectedRequest;
|
|
fClientRequest.Request.UserAgent := str_ProductName;
|
|
|
|
{$IFDEF DELPHI6UP}
|
|
fClientWait.SetSubComponent(TRUE);
|
|
{$ENDIF}
|
|
{$IFDEF DELPHI6UP}
|
|
fClientRequest.SetSubComponent(TRUE);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
destructor TROIndySuperHttpChannel.Destroy;
|
|
begin
|
|
Active := false;
|
|
fClientWait.Free;
|
|
fClientRequest.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TROIndySuperHttpChannel.DispatchHttpRequest(
|
|
aWaitingThread: Boolean; aRequest: TDynByteArray;
|
|
out aResponse: TDynByteArray);
|
|
var
|
|
lClient: TIdHTTP;
|
|
lRequest, lResponse: TMemoryStream;
|
|
begin
|
|
if aWaitingThread then lClient := fClientWait else lClient := fClientRequest;
|
|
lRequest:= TMemoryStream.Create;
|
|
lResponse := TMemoryStream.Create;
|
|
try
|
|
lRequest.Write(aRequest[0], Length(aRequest));
|
|
lRequest.Position := 0;
|
|
{$IFNDEF REMOBJECTS_INDY8}
|
|
lClient.ReadTimeout := HttpRequestTimeout;
|
|
{$ENDIF}
|
|
{$IFDEF RemObjects_INDY10}
|
|
lClient.ConnectTimeout := ConnectTimeout;
|
|
{$ENDIF}
|
|
lClient.Post(fTargetUrl, lRequest, lResponse);
|
|
SetLength(aResponse, lResponse.Size);
|
|
lResponse.Position := 0;
|
|
lResponse.Read(aResponse[0], Length(aResponse));
|
|
finally
|
|
lRequest.Free;
|
|
lResponse.Free;
|
|
end;
|
|
end;
|
|
|
|
function TROIndySuperHttpChannel.GetClientAddress: string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TROIndySuperHttpChannel.GetContentType: string;
|
|
begin
|
|
result := ClientRequest.Request.ContentType;
|
|
end;
|
|
|
|
function TROIndySuperHttpChannel.GetHeaders(const aName: string): string;
|
|
begin
|
|
{$IFDEF RemObjects_INDY8}
|
|
result := GetHeaderValue(ClientRequest.Request.ExtraHeaders, aName);
|
|
{$ELSE}
|
|
result := GetHeaderValue(ClientRequest.Request.RawHeaders, aName);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
function TROIndySuperHttpChannel.GetLocation: string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TROIndySuperHttpChannel.GetPathInfo: string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TROIndySuperHttpChannel.GetQueryParameter(
|
|
const aName: string): string;
|
|
begin
|
|
result := '';
|
|
end;
|
|
|
|
function TROIndySuperHttpChannel.GetQueryString: string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TROIndySuperHttpChannel.GetTargetURL: string;
|
|
begin
|
|
result := fTargetURL;
|
|
end;
|
|
|
|
function TROIndySuperHttpChannel.GetUserAgent: string;
|
|
begin
|
|
result := ClientRequest.Request.UserAgent;
|
|
end;
|
|
|
|
procedure TROIndySuperHttpChannel.SetContentType(const aValue: string);
|
|
begin
|
|
ClientWait.Request.ContentType := aValue;
|
|
ClientRequest.Request.ContentType := aValue;
|
|
end;
|
|
|
|
procedure TROIndySuperHttpChannel.SetHeaders(const aName, aValue: string);
|
|
begin
|
|
{$IFDEF RemObjects_INDY8}
|
|
SetHeaderValue(ClientWait.Request.ExtraHeaders, aName, aValue);
|
|
SetHeaderValue(ClientRequest.Request.ExtraHeaders, aName, aValue);
|
|
{$ELSE}
|
|
SetHeaderValue(ClientWait.Request.CustomHeaders, aName, aValue);
|
|
SetHeaderValue(ClientRequest.Request.CustomHeaders, aName, aValue);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TROIndySuperHttpChannel.SetPathInfo(const aValue: string);
|
|
begin
|
|
// do nothing; server side only
|
|
end;
|
|
|
|
procedure TROIndySuperHttpChannel.SetTargetURL(const aValue: string);
|
|
begin
|
|
fTargetURL := Trim(aValue)
|
|
end;
|
|
|
|
procedure TROIndySuperHttpChannel.SetUserAgent(const aValue: string);
|
|
begin
|
|
ClientWait.Request.UserAgent := aValue;
|
|
ClientRequest.Request.UserAgent := aValue;
|
|
end;
|
|
|
|
end.
|