Added SCOOP support for WSF.

WSF_SERVICE is deeply changed, and addition of WSF_EXECUTION.
Todo: code cleaning, removing useless things.
This commit is contained in:
2015-03-24 23:21:49 +01:00
parent ddf73077b3
commit bf0eb9a02d
51 changed files with 951 additions and 316 deletions

View File

@@ -17,33 +17,16 @@ feature {NONE} -- Initialization
make
-- Initialize `Current'.
local
server: separate HTTPD_SERVER
fac: separate WSF_HTTPD_REQUEST_HANDLER_FACTORY [APP_WSF_EXECUTION]
conn: WGI_HTTPD_CONNECTOR [APP_WSF_EXECUTION]
do
print ("Hello%N")
create fac
create server.make (fac)
launch_server (server)
print ("Starting httpd server ...%N")
create conn.make
conn.set_port_number (9090)
conn.set_max_concurrent_connections (100)
conn.launch
end
launch_server (server: separate HTTPD_SERVER)
do
server.configuration.set_max_concurrent_connections (100)
server.configuration.set_http_server_port (9090)
server.launch
end
feature -- Status
feature -- Access
feature -- Change
feature {NONE} -- Implementation
invariant
-- invariant_clause: True
note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"

View File

@@ -1,264 +0,0 @@
note
description: "Summary description for {WSF_HTTPD_REQUEST_HANDLER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
WSF_HTTPD_REQUEST_HANDLER [G -> WSF_EXECUTION create make end]
inherit
HTTPD_REQUEST_HANDLER
WGI_EXPORTER
REFACTORING_HELPER
create
make
feature -- Request processing
process_request (a_socket: HTTPD_STREAM_SOCKET)
-- Process request ...
local
l_input: WGI_INPUT_STREAM
l_output: WGI_OUTPUT_STREAM
l_error: WGI_ERROR_STREAM
req: WGI_REQUEST_FROM_TABLE
res: detachable WGI_HTTPD_RESPONSE_STREAM
exec: WSF_EXECUTION
retried: BOOLEAN
do
if not retried then
create {WGI_HTTPD_INPUT_STREAM} l_input.make (a_socket)
create {WGI_HTTPD_OUTPUT_STREAM} l_output.make (a_socket)
create {WGI_HTTPD_ERROR_STREAM} l_error.make_stderr (a_socket.descriptor.out)
create req.make (httpd_environment (a_socket), l_input, Void)
create res.make (l_output, l_error)
req.set_meta_string_variable ("RAW_HEADER_DATA", request_header)
exec := new_execution (req, res)
exec.execute
res.push
else
end
rescue
if not retried then
retried := True
retry
end
end
new_execution (req: WGI_REQUEST; res: WGI_RESPONSE): WSF_EXECUTION
do
create {G} Result.make (req, res)
end
base: detachable READABLE_STRING_8
do
--TODO
to_implement ("Base url support")
end
httpd_environment (a_socket: HTTPD_STREAM_SOCKET): STRING_TABLE [READABLE_STRING_8]
local
p: INTEGER
l_request_uri, l_script_name, l_query_string, l_path_info: STRING
l_server_name, l_server_port: detachable STRING
l_headers_map: HASH_TABLE [STRING, STRING]
vn: STRING
e: EXECUTION_ENVIRONMENT
enc: URL_ENCODER
utf: UTF_CONVERTER
do
l_request_uri := uri
l_headers_map := request_header_map
create e
create enc
if attached e.starting_environment as vars then
create Result.make_equal (vars.count)
across
vars as c
loop
Result.force (utf.utf_32_string_to_utf_8_string_8 (c.item), utf.utf_32_string_to_utf_8_string_8 (c.key))
end
else
create Result.make (0)
end
--| for Any Abc-Def-Ghi add (or replace) the HTTP_ABC_DEF_GHI variable to `Result'
from
l_headers_map.start
until
l_headers_map.after
loop
create vn.make_from_string (l_headers_map.key_for_iteration.as_upper)
vn.replace_substring_all ("-", "_")
if
vn.starts_with ("CONTENT_") and then
(vn.same_string_general ({WGI_META_NAMES}.content_type) or vn.same_string_general ({WGI_META_NAMES}.content_length))
then
--| Keep this name
else
vn.prepend ("HTTP_")
end
add_environment_variable (l_headers_map.item_for_iteration, vn, Result)
l_headers_map.forth
end
--| Specific cases
p := l_request_uri.index_of ('?', 1)
if p > 0 then
l_script_name := l_request_uri.substring (1, p - 1)
l_query_string := l_request_uri.substring (p + 1, l_request_uri.count)
else
l_script_name := l_request_uri.string
l_query_string := ""
end
if attached l_headers_map.item ("Host") as l_host then
check has_host: Result.has ("HTTP_HOST") end
-- set_environment_variable (l_host, "HTTP_HOST", Result)
p := l_host.index_of (':', 1)
if p > 0 then
l_server_name := l_host.substring (1, p - 1)
l_server_port := l_host.substring (p+1, l_host.count)
else
l_server_name := l_host
l_server_port := "80" -- Default
end
else
check host_available: False end
end
if attached l_headers_map.item ("Authorization") as l_authorization then
check has_authorization: Result.has ("HTTP_AUTHORIZATION") end
-- set_environment_variable (l_authorization, "HTTP_AUTHORIZATION", Result)
p := l_authorization.index_of (' ', 1)
if p > 0 then
set_environment_variable (l_authorization.substring (1, p - 1), "AUTH_TYPE", Result)
end
end
set_environment_variable ("CGI/1.1", "GATEWAY_INTERFACE", Result)
set_environment_variable (l_query_string, "QUERY_STRING", Result)
if attached remote_info as l_remote_info then
set_environment_variable (l_remote_info.addr, "REMOTE_ADDR", Result)
set_environment_variable (l_remote_info.hostname, "REMOTE_HOST", Result)
set_environment_variable (l_remote_info.port.out, "REMOTE_PORT", Result)
-- set_environment_variable (Void, "REMOTE_IDENT", Result)
-- set_environment_variable (Void, "REMOTE_USER", Result)
end
set_environment_variable (l_request_uri, "REQUEST_URI", Result)
set_environment_variable (method, "REQUEST_METHOD", Result)
set_environment_variable (l_script_name, "SCRIPT_NAME", Result)
set_environment_variable (l_server_name, "SERVER_NAME", Result)
set_environment_variable (l_server_port, "SERVER_PORT", Result)
set_environment_variable (version, "SERVER_PROTOCOL", Result)
set_environment_variable ({HTTPD_CONFIGURATION}.Server_details, "SERVER_SOFTWARE", Result)
--| Apply `base' value
if attached base as l_base and then l_request_uri /= Void then
if l_request_uri.starts_with (l_base) then
l_path_info := l_request_uri.substring (l_base.count + 1, l_request_uri.count)
p := l_path_info.index_of ('?', 1)
if p > 0 then
l_path_info.keep_head (p - 1)
end
Result.force (l_base, "SCRIPT_NAME")
else
-- This should not happen, this means the `base' is not correctly set.
-- It is better to consider base as empty, rather than having empty PATH_INFO
check valid_base_value: False end
l_path_info := l_request_uri
p := l_request_uri.index_of ('?', 1)
if p > 0 then
l_path_info := l_request_uri.substring (1, p - 1)
else
l_path_info := l_request_uri.string
end
Result.force ("", "SCRIPT_NAME")
end
--| In order to have same path value for PATH_INFO on various connectors and servers
--| the multiple slashes must be stripped to single slash.
--| tested with: CGI+apache, libfcgi+apache on Windows and Linux
--|
--| For example: "////abc/def///end////" to "/abc/def/end/" ?
convert_multiple_slashes_to_single (l_path_info)
Result.force (enc.decoded_utf_8_string (l_path_info), "PATH_INFO")
end
end
add_environment_variable (a_value: detachable STRING; a_var_name: READABLE_STRING_GENERAL; env: STRING_TABLE [READABLE_STRING_8])
-- Add variable `a_var_name => a_value' to `env'
do
if a_value /= Void then
if env.has_key (a_var_name) and then attached env.found_item as l_existing_value then
--| Check http://www.ietf.org/rfc/rfc3875 4.1.18
check find_proper_rewrite_for_same_header: False end
env.force (l_existing_value + " " + a_value, a_var_name)
else
env.force (a_value, a_var_name)
end
end
end
set_environment_variable (a_value: detachable STRING; a_var_name: READABLE_STRING_GENERAL; env: STRING_TABLE [READABLE_STRING_8])
-- Add variable `a_var_name => a_value' to `env'
do
if a_value /= Void then
env.force (a_value, a_var_name)
end
end
feature {NONE} -- Implementation
convert_multiple_slashes_to_single (s: STRING_8)
-- Replace multiple slashes sequence by a single slash character.
local
i,n: INTEGER
do
from
i := 1
n := s.count
until
i > n
loop
if s[i] = '/' then
-- Remove following slashes '/'.
from
i := i + 1
until
i > n or s[i] /= '/'
loop
s.remove (i)
n := n - 1
end
else
i := i + 1
end
end
end
note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,30 +0,0 @@
note
description: "Summary description for {WSF_HTTPD_REQUEST_HANDLER_FACTORY}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
WSF_HTTPD_REQUEST_HANDLER_FACTORY [G -> WSF_EXECUTION create make end]
inherit
HTTPD_REQUEST_HANDLER_FACTORY
feature -- Factory
new_handler: separate WSF_HTTPD_REQUEST_HANDLER [G]
do
create Result.make
end
note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end