forked from ThomasMertes/seed7
-
Notifications
You must be signed in to change notification settings - Fork 0
/
comanche.sd7
178 lines (171 loc) · 7.66 KB
/
comanche.sd7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
(********************************************************************)
(* *)
(* comanche.sd7 Simple webserver for static and cgi pages. *)
(* Copyright (C) 2009 - 2017, 2023 Thomas Mertes *)
(* *)
(* This program is free software; you can redistribute it and/or *)
(* modify it under the terms of the GNU General Public License as *)
(* published by the Free Software Foundation; either version 2 of *)
(* the License, or (at your option) any later version. *)
(* *)
(* This program is distributed in the hope that it will be useful, *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)
(* GNU General Public License for more details. *)
(* *)
(* You should have received a copy of the GNU General Public *)
(* License along with this program; if not, write to the *)
(* Free Software Foundation, Inc., 51 Franklin Street, *)
(* Fifth Floor, Boston, MA 02110-1301, USA. *)
(* *)
(********************************************************************)
$ 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);
# writeln(request.method <& " " <& request.path);
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;
# process(request);
end while;
end if;
end if;
end func;