$ include "seed7_05.s7i";
include "propertyfile.s7i";
include "httpserv.s7i";
include "x509cert.s7i";
include "osfiles.s7i";
include "http_response.s7i";
const string: htdocsDefault is "../htdocs";
const string: cgiDirDefault is "../prg";
const string: cgiNameDefault is "/cgi-bin/";
const proc: main is func
local
var string: htdocs is htdocsDefault;
var string: cgiDir is cgiDirDefault;
var string: cgiName is cgiNameDefault;
var string: envFileName is "";
var array string: args is 0 times "";
var integer: index is 0;
var boolean: writeHelp is FALSE;
var boolean: useTls is FALSE;
var boolean: htdocsAssigned is FALSE;
var boolean: cgiDirAssigned is FALSE;
var boolean: envFileNameAssigned is FALSE;
var integer: slashPos is 0;
var propertyDataType: cgiEnvironment is propertyDataType.value;
var string: envKey is "";
var string: envValue is "";
var boolean: okay is TRUE;
var integer: port is 1080;
var httpServer: server is httpServer.value;
var httpRequest: request is httpRequest.value;
var httpResponseData: responseData is httpResponseData.value;
begin
writeln("Comanche Version 2.0 - Simple webserver for static and cgi pages");
writeln("Copyright (C) 2009 - 2017, 2023 Thomas Mertes");
writeln("This is free software; see the source for copying conditions. There is NO");
writeln("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
writeln("Comanche is written in the Seed7 programming language");
writeln("Homepage: http://seed7.sourceforge.net");
args := argv(PROGRAM);
for key index range argv(PROGRAM) do
if args[index] in {"-h", "-?"} then
writeHelp := TRUE;
elsif args[index] = "-p" and index < length(args) then
block
port := integer(args[succ(index)]);
exception
catch RANGE_ERROR:
writeln(" ***** Port not numeric. Port " <& port <& " used instead.");
end block;
incr(index);
elsif args[index] = "-c" and index < length(args) then
cgiName := args[succ(index)];
incr(index);
elsif args[index] = "-tls" then
useTls := TRUE;
elsif not htdocsAssigned then
htdocs := convDosPath(args[index]);
htdocsAssigned := TRUE;
elsif not cgiDirAssigned then
cgiDir := convDosPath(args[index]);
cgiDirAssigned := TRUE;
elsif not envFileNameAssigned then
envFileName := convDosPath(args[index]);
envFileNameAssigned := TRUE;
else
writeln(" ***** Unrecognized parameter " <& args[index] <& ".");
end if;
end for;
if writeHelp then
writeln;
writeln("usage: comanche [-h | -?] [-p port] [-c cgi-name] [-tls] [html-dir [cgi-dir [env-file]]]");
writeln;
writeln("Options:");
writeln(" -h or -? Write usage information.");
writeln(" -p port Specify the port (default: 1080).");
writeln(" -c cgi-name Specify the cgi-name used in the HTTP(S) requests (default: " <&
literal(cgiNameDefault) <& ").");
writeln(" If cgi-name is \"\" the cgi-name is taken from cgi-dir.");
writeln(" -tls Use HTTPS instead of HTTP.");
writeln("Parameters:");
writeln(" html-dir The root directory for HTML files (default: " <&
literal(htdocsDefault) <& ").");
writeln(" cgi-dir The root directory for CGI scripts (default: " <&
literal(cgiDirDefault) <& ").");
writeln(" env-file Property file with environment variables to be defined.");
else
if cgiName = "" then
slashPos := rpos(cgiDir, "/");
if slashPos = 0 then
cgiName := "/" & cgiDir & "/";
else
cgiName := cgiDir[slashPos ..] & "/";
end if;
end if;
responseData := httpResponseData(htdocs, cgiDir, cgiName, osFiles);
if fileType(responseData.backendSys, responseData.htdocs) <> FILE_DIR then
writeln(" *** Directory " <& literal(responseData.htdocs) <& " not found.");
writeln(" You need to specify a directory which contains");
writeln(" at least \"index.htm\" and possibly other HTML files.");
okay := FALSE;
end if;
if fileType(responseData.backendSys, responseData.cgiDir) <> FILE_DIR then
writeln(" *** Directory " <& literal(responseData.cgiDir) <& " not found.");
writeln(" You need to specify a directory which contains");
writeln(" executable CGI scripts.");
okay := FALSE;
end if;
if envFileNameAssigned then
if fileType(envFileName) <> FILE_REGULAR then
writeln(" *** File " <& literal(envFileName) <& " not found.");
else
cgiEnvironment := readPropertyFile(envFileName);
for envValue key envKey range cgiEnvironment do
setenv(envKey, envValue);
end for;
end if;
end if;
if not okay then
writeln("Use the option -? (or -h) to get more information.");
else
chdir(responseData.cgiDir);
writeln("HTML directory: " <& responseData.htdocs);
writeln("CGI directory: " <& responseData.cgiDir);
writeln("CGI name: " <& responseData.cgiName);
writeln("Port: " <& port);
server := openHttpServer(port, stdCertificate, useTls);
writeln("To test comanche make sure that " <&
literal(responseData.htdocs & "/index.htm") <& " exists and");
write("open http");
if useTls then
write("s");
end if;
writeln("://localhost:" <& port <& "/ in your browser. \
\To stop comanche press CTRL-C.");
while TRUE do
request := getHttpRequest(server);
if request.method = "GET" then
processGet(responseData, request);
elsif request.method = "POST" then
processPost(responseData, request);
else
sendClientError(request.sock, 405, "Method Not Allowed",
"The HTTP-method " <& request.method <& " is not allowed.");
end if;
end while;
end if;
end if;
end func;