Added handler to add support for CGI scripts.

Added a new tool `httpd` which is a basic httpd server product (with file server and CGI handler).
This commit is contained in:
Jocelyn Fiat
2017-11-03 18:00:39 +01:00
parent 95cebe26bb
commit 211fc425a3
8 changed files with 442 additions and 1 deletions

12
tools/httpd/README.md Normal file
View File

@@ -0,0 +1,12 @@
Simple web server
=================
This server is very simple and limited, it is, for now:
- a file server
- a CGI handler (for `*.cgi` executables)
Usage:
httpd (--root path)
--root <path>: document directory for file server (default: www)

56
tools/httpd/httpd.ecf Normal file
View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-17-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-17-0 http://www.eiffel.com/developers/xml/configuration-1-17-0.xsd" name="httpd" uuid="60DBA808-B014-47BB-BDEF-11B87C1DC6DE">
<target name="common" abstract="true">
<file_rule>
<exclude>/CVS$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/\.svn$</exclude>
</file_rule>
<option warning="true">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="http" location="..\..\library\network\protocol\http\http.ecf"/>
<library name="process" location="$ISE_LIBRARY\library\process\base\base_process.ecf"/>
<library name="wsf" location="..\..\library\server\wsf\wsf.ecf" readonly="false"/>
<library name="wsf_extension" location="..\..\library\server\wsf\wsf_extension.ecf" readonly="false"/>
</target>
<target name="httpd_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/>
<option warning="true">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="default_standalone" location="..\..\library\server\wsf\default\standalone.ecf"/>
<cluster name="httpd" location=".\src" recursive="true"/>
</target>
<target name="httpd_standalone_mt" extends="httpd_standalone">
<capability>
<concurrency support="thread" use="thread"/>
</capability>
</target>
<target name="httpd_standalone_st" extends="httpd_standalone">
<capability>
<concurrency support="none" use="none"/>
</capability>
</target>
<target name="httpd_cgi" extends="common">
<root class="APPLICATION" feature="make_and_launch"/>
<option warning="true">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<capability>
<concurrency use="scoop"/>
</capability>
<library name="default_cgi" location="..\..\library\server\wsf\default\cgi.ecf"/>
<cluster name="httpd" location=".\src" recursive="true"/>
</target>
<target name="httpd_libfcgi" extends="common">
<root class="APPLICATION" feature="make_and_launch"/>
<option warning="true">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="default_libfcgi" location="..\..\library\server\wsf\default\libfcgi.ecf"/>
<cluster name="httpd" location=".\src" recursive="true"/>
</target>
</system>

9
tools/httpd/server.ini Normal file
View File

@@ -0,0 +1,9 @@
verbose=true
verbose_level=ALERT
port=9090
#max_concurrent_connections=100
#keep_alive_timeout=5
#max_keep_alive_requests=300
#max_tcp_clients=100
#socket_timeout=60
#socket_recv_timeout=15

View File

@@ -0,0 +1,31 @@
note
description : "simple application root class"
date : "$Date$"
revision : "$Revision$"
class
APPLICATION
inherit
WSF_DEFAULT_SERVICE [APPLICATION_EXECUTION]
redefine
initialize
end
SHARED_EXECUTION_ENVIRONMENT
create
make_and_launch
feature {NONE} -- Initialization
initialize
-- Initialize current service.
do
-- Specific to `standalone' connector (the EiffelWeb server).
-- See `{WSF_STANDALONE_SERVICE_LAUNCHER}.initialize'
set_service_option ("port", 9090)
import_service_options (create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI}.make_from_file ("server.ini"))
end
end

View File

@@ -0,0 +1,95 @@
note
description : "simple application execution"
date : "$Date$"
revision : "$Revision$"
class
APPLICATION_EXECUTION
inherit
WSF_ROUTED_EXECUTION
SHARED_EXECUTION_ENVIRONMENT
create
make
feature -- Setup
cgi_file_extensions: ITERABLE [READABLE_STRING_GENERAL]
once
Result := <<"cgi">>
end
directory_index_file_names: ITERABLE [READABLE_STRING_GENERAL]
once
Result := <<"index.html">>
end
document_location: PATH
-- Root folder for the httpd files server.
local
i,n: INTEGER
d: detachable READABLE_STRING_GENERAL
once
Result := execution_environment.current_working_path.extended ("www")
if attached execution_environment.arguments as args then
from
i := 1
n := args.argument_count
until
i > n or d /= Void
loop
if
attached args.argument (i) as v and then
v.same_string_general ("--root") and then
i < n
then
i := i + 1
d := args.argument (i)
end
i := i + 1
end
if d /= Void then
create Result.make_from_string (d)
end
end
end
setup_router
-- Setup `router'
local
cgi: WSF_CGI_HANDLER
cgi_cond: WSF_ROUTING_CONDITION
fs: WSF_FILE_SYSTEM_HANDLER
m: WSF_STARTS_WITH_MAPPING
cond: WSF_WITH_CONDITION_MAPPING
s: STRING_32
do
create cgi.make (document_location)
cgi_cond := create {WSF_ROUTING_FILE_EXISTS_CONDITION}.make (document_location) and create {WSF_ROUTING_EXTENSION_CONDITION}.make (cgi_file_extensions)
create cond.make (cgi_cond, cgi)
create s.make_empty
across
cgi_file_extensions as ic
loop
if not s.is_empty then
s.append_string_general (", ")
end
s.append_string_general ("*.")
s.append_string_general (ic.item)
end
cond.set_condition_description (s)
router.map (cond, Void)
create fs.make_with_path (document_location)
fs.enable_index
fs.set_directory_index (directory_index_file_names)
fs.set_not_found_handler (agent (i_uri: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE) do execute_default (req, res) end)
create m.make ("", fs)
router.map (m, router.methods_get)
end
end

View File

@@ -0,0 +1 @@
Hello EiffelWeb httpd server.