mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-04 20:38:25 +02:00
276 lines
7.5 KiB
ObjectPascal
276 lines
7.5 KiB
ObjectPascal
program testcgiapp;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
uses
|
|
Classes, SysUtils, CustApp, inifiles, process, httpdefs,custcgi
|
|
{ you can add units after this };
|
|
|
|
type
|
|
|
|
{ TTestCGIApplication }
|
|
|
|
TTestCGIApplication = class(TCustomApplication)
|
|
private
|
|
FCGB: String;
|
|
FCGIE: TStrings;
|
|
FCGV: TStrings;
|
|
FMethod: String;
|
|
Foutput: String;
|
|
FPostData: String;
|
|
FPathInfo : String;
|
|
FScriptName: String;
|
|
FURL: String;
|
|
procedure CheckEnvironment;
|
|
procedure CheckMethod;
|
|
procedure ProcessConfig;
|
|
procedure RunCGI;
|
|
protected
|
|
Property CGIEnvironment : TStrings Read FCGIE Write FCGIE;
|
|
Property URL : String Read FURL Write FURL;
|
|
Property PostData : String Read FPostData Write FPostData;
|
|
Property Method : String Read FMethod Write FMethod;
|
|
Property CGIOutput : String Read Foutput Write FOutput;
|
|
Property CGIBinary : String Read FCGB Write FCGB;
|
|
Property CGIVariables : TStrings Read FCGV Write FCGV;
|
|
Property PathInfo : String Read FPathInfo Write FPathInfo;
|
|
Property ScriptName : String Read FScriptName Write FScriptName;
|
|
procedure DoRun; override;
|
|
public
|
|
constructor Create(TheOwner: TComponent); override;
|
|
Destructor Destroy; override;
|
|
procedure WriteHelp; virtual;
|
|
end;
|
|
|
|
{ TTestCGIApplication }
|
|
|
|
Resourcestring
|
|
SErrUnsupportedMethod = 'Unsupported method: "%s"';
|
|
SErrNoCGIBinary = 'No CGI binary specified';
|
|
|
|
Const
|
|
SConfig = 'Config';
|
|
KeyURL = 'URL';
|
|
KeyEnvironment = 'Environment';
|
|
KeyMethod = 'Method';
|
|
KeyPost = 'PostData';
|
|
|
|
SEnvironment = KeyEnvironment;
|
|
SVariables = 'Variables';
|
|
|
|
|
|
procedure TTestCGIApplication.ProcessConfig;
|
|
|
|
Var
|
|
Ini : TInifile;
|
|
S : String;
|
|
|
|
begin
|
|
Ini:=TIniFile.Create(GetOptionValue('c','config'));
|
|
try
|
|
With Ini do
|
|
begin
|
|
URL:=ReadString(SConfig,KeyURL,'');
|
|
S:=ReadString(SConfig,KeyEnvironment,'');
|
|
If (S<>'') and FileExists(S) then
|
|
CGIEnvironment.LoadFromFile(S);
|
|
If SectionExists(SEnvironment) then
|
|
ReadSectionValues(SEnvironment,CGIEnvironment);
|
|
If SectionExists(SVariables) then
|
|
ReadSectionValues(SVariables,CGIVariables);
|
|
If (Method='') then
|
|
Method:=ReadString(SConfig,KeyMethod,'GET');
|
|
PostData:=ReadString(SConfig,KeyPost,'');
|
|
|
|
end;
|
|
finally
|
|
Ini.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TTestCGIApplication.RunCGI;
|
|
|
|
Var
|
|
Proc : TProcess;
|
|
|
|
begin
|
|
If (CGIBinary='') then
|
|
Raise Exception.Create(SerrNoCGIBinary);
|
|
Proc:=TProcess.Create(Self);
|
|
try
|
|
Proc.CommandLine:=CGIBinary;
|
|
Proc.Environment:=CGIEnvironment;
|
|
Proc.Execute;
|
|
|
|
finally
|
|
Proc.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TTestCGIApplication.CheckMethod;
|
|
|
|
begin
|
|
If (Method='') then
|
|
Method:='GET'
|
|
else
|
|
begin
|
|
Method:=Uppercase(Method);
|
|
end;
|
|
end;
|
|
(*
|
|
({ 1: 'AUTH_TYPE' } fieldWWWAuthenticate, // ?
|
|
{ 2: 'CONTENT_LENGTH' } FieldContentLength,
|
|
{ 3: 'CONTENT_TYPE' } FieldContentType,
|
|
{ 4: 'GATEWAY_INTERFACE' } '',
|
|
{ 5: 'PATH_INFO' } '',
|
|
{ 6: 'PATH_TRANSLATED' } '',
|
|
{ 7: 'QUERY_STRING' } '',
|
|
{ 8: 'REMOTE_ADDR' } '',
|
|
{ 9: 'REMOTE_HOST' } '',
|
|
{ 10: 'REMOTE_IDENT' } '',
|
|
{ 11: 'REMOTE_USER' } '',
|
|
{ 12: 'REQUEST_METHOD' } '',
|
|
{ 13: 'SCRIPT_NAME' } '',
|
|
{ 14: 'SERVER_NAME' } '',
|
|
{ 15: 'SERVER_PORT' } '',
|
|
{ 16: 'SERVER_PROTOCOL' } '',
|
|
{ 17: 'SERVER_SOFTWARE' } '',
|
|
{ 18: 'HTTP_ACCEPT' } FieldAccept,
|
|
{ 19: 'HTTP_ACCEPT_CHARSET' } FieldAcceptCharset,
|
|
{ 20: 'HTTP_ACCEPT_ENCODING' } FieldAcceptEncoding,
|
|
{ 21: 'HTTP_IF_MODIFIED_SINCE' } FieldIfModifiedSince,
|
|
{ 22: 'HTTP_REFERER' } FieldReferer,
|
|
{ 23: 'HTTP_USER_AGENT' } FieldUserAgent,
|
|
{ 24: 'HTTP_COOKIE' } FieldCookie,
|
|
// Additional Apache vars
|
|
{ 25: 'HTTP_CONNECTION' } FieldConnection,
|
|
{ 26: 'HTTP_ACCEPT_LANGUAGE' } FieldAcceptLanguage,
|
|
{ 27: 'HTTP_HOST' } '',
|
|
{ 28: 'SERVER_SIGNATURE' } '',
|
|
{ 29: 'SERVER_ADDR' } '',
|
|
{ 30: 'DOCUMENT_ROOT' } '',
|
|
{ 31: 'SERVER_ADMIN' } '',
|
|
{ 32: 'SCRIPT_FILENAME' } '',
|
|
{ 33: 'REMOTE_PORT' } '',
|
|
{ 34: 'REQUEST_URI' } '',
|
|
{ 35: 'CONTENT' } '',
|
|
{ 36: 'XHTTPREQUESTEDWITH' } ''
|
|
|
|
*)
|
|
|
|
procedure TTestCGIApplication.CheckEnvironment;
|
|
|
|
Var
|
|
L : TStrings;
|
|
S,N,V : String;
|
|
I : Integer;
|
|
|
|
begin
|
|
L:=CGIEnvironment;
|
|
If L.IndexOfName('REQUEST_METHOD')=-1 then
|
|
L.Values['REQUEST_METHOD']:=Method;
|
|
S:=ScriptName;
|
|
If (S='') then
|
|
S:=CGIBinary;
|
|
If L.IndexOfName('SCRIPT_NAME')=-1 then
|
|
L.Values['SCRIPT_NAME']:=S;
|
|
If L.IndexOfName('SCRIPT_FILENAME')=-1 then
|
|
L.Values['SCRIPT_FILENAME']:=S;
|
|
If (PathInfo<>'') then
|
|
L.Values['PATH_INFO']:=PathInfo;
|
|
If (Method='GET') then
|
|
begin
|
|
If L.IndexOfName('QUERY_STRING')=-1 then
|
|
begin
|
|
S:='';
|
|
If (CGIVariables.Count>0) then
|
|
For I:=0 to CGIVariables.Count-1 do
|
|
begin
|
|
CGIVariables.GetNameValue(I,N,V);
|
|
If (S<>'') then
|
|
S:=S+'&';
|
|
S:=S+N+'='+HTTPEncode(V);
|
|
end;
|
|
L.Add('QUERY_STRING='+S)
|
|
end;
|
|
end
|
|
end;
|
|
|
|
|
|
procedure TTestCGIApplication.DoRun;
|
|
var
|
|
ErrorMsg: String;
|
|
begin
|
|
// parse parameters
|
|
if HasOption('h','help') then begin
|
|
WriteHelp;
|
|
Terminate;
|
|
Exit;
|
|
end;
|
|
if HasOption('c','config') then
|
|
ProcessConfig;
|
|
If HasOption('u','url') then
|
|
URL:=GetOptionValue('u','url');
|
|
If HasOption('e','environment') then
|
|
CGIEnvironment.LoadFromFile(GetOptionValue('e','environment'));
|
|
If HasOption('o','output') then
|
|
CGIOutput:=GetOptionValue('o','output');
|
|
If HasOption('m','method') then
|
|
Method:=GetOptionValue('m','method');
|
|
If HasOption('p','pathinfo') then
|
|
PathInfo:=GetOptionValue('p','pathinfo');
|
|
If HasOption('s','scriptname') then
|
|
ScriptName:=GetOptionValue('s','scriptname');
|
|
If HasOption('r','variables') then
|
|
CGIOutput:=GetOptionValue('v','variables');
|
|
If HasOption('i','input') then
|
|
CGIBinary:=GetOptionValue('i','input');
|
|
CheckMethod;
|
|
CheckEnvironment;
|
|
RunCGI;
|
|
{ add your program here }
|
|
// stop program loop
|
|
Terminate;
|
|
end;
|
|
|
|
constructor TTestCGIApplication.Create(TheOwner: TComponent);
|
|
begin
|
|
inherited Create(TheOwner);
|
|
StopOnException:=True;
|
|
FCGIE:=TStringList.Create;
|
|
FCGV:=TStringList.Create;
|
|
end;
|
|
|
|
destructor TTestCGIApplication.Destroy;
|
|
begin
|
|
FreeAndNil(FCGIE);
|
|
FreeAndNil(FCGV);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TTestCGIApplication.WriteHelp;
|
|
begin
|
|
Writeln('Usage: ',ExeName,' [options]');
|
|
Writeln('Where options is one of : ');
|
|
Writeln(' -h this help');
|
|
Writeln(' -c|--config=file use file for configuration');
|
|
Writeln(' -e|--environment=file use file for CGI environment (overrides config).');
|
|
Writeln(' -i|--input=file use file as CGI binary.');
|
|
Writeln(' -m|--method=method use method to invoke CGI (overrides config, default is GET).');
|
|
Writeln(' -o|--output=file use file for CGI output (overrides config).');
|
|
Writeln(' -p|--pathinfo=path use path for PATH_INFO environment variable (overrides config).');
|
|
Writeln(' -r|--variables=file read query variables from file (overrides config).');
|
|
Writeln(' -u|--url=URL use URL as the URL (overrides config).');
|
|
end;
|
|
|
|
var
|
|
Application: TTestCGIApplication;
|
|
|
|
begin
|
|
Application:=TTestCGIApplication.Create(nil);
|
|
Application.Title:='Test CGI application';
|
|
Application.Run;
|
|
Application.Free;
|
|
end.
|
|
|