Added abstraction WSF_ROUTED, and WSF_FILTERED.

Added under library/server/obsolete/v0 the previous non concurrent friendly version of EWF/WSF, for backward compatiblity.
Removed WSF_CALLBACK_SERVICE and WSF_TO_WGI_SERVICE which are not need with new EWF.
This commit is contained in:
2015-05-06 19:32:05 +02:00
parent 019393fdb1
commit 8ea443c115
64 changed files with 2741 additions and 90 deletions

View File

@@ -0,0 +1,116 @@
note
description: "Summary description for {NINO_SERVICE}."
date: "$Date$"
revision: "$Revision$"
class
NINO_SERVICE
create
make,
make_custom,
make_with_callback,
make_custom_with_callback
feature {NONE} -- Implementation
make (a_service: WGI_SERVICE)
-- Initialize `Current'.
do
make_custom (a_service, Void)
end
make_custom (a_service: WGI_SERVICE; a_base_url: detachable STRING)
-- Initialize `Current'.
require
base_url_starts_with_slash: (a_base_url /= Void and then not a_base_url.is_empty) implies a_base_url.starts_with ("/")
do
create connector.make_with_base (a_service, a_base_url)
end
make_with_callback (a_callback: PROCEDURE [ANY, TUPLE [req: WGI_REQUEST; res: WGI_RESPONSE]])
-- Initialize `Current'.
do
make_custom_with_callback (a_callback, Void)
end
make_custom_with_callback (a_callback: PROCEDURE [ANY, TUPLE [req: WGI_REQUEST; res: WGI_RESPONSE]]; a_base_url: detachable STRING)
-- Initialize `Current'.
require
base_url_starts_with_slash: (a_base_url /= Void and then not a_base_url.is_empty) implies a_base_url.starts_with ("/")
local
app: WGI_AGENT_SERVICE
do
create app.make (a_callback)
make_custom (app, a_base_url)
end
feature -- Access
connector: WGI_NINO_CONNECTOR
-- Web server connector
feature -- Status report
launched: BOOLEAN
-- Server launched?
do
Result := connector.launched
end
port: INTEGER
-- Port listened
do
Result := connector.port
end
feature -- Status settings
configuration: HTTP_SERVER_CONFIGURATION
do
Result := connector.configuration
end
force_single_threaded
-- Force single threaded behavior
do
configuration.force_single_threaded := True
end
set_is_verbose (b: BOOLEAN)
-- Set verbose message behavior to `b'
do
configuration.set_is_verbose (b)
end
set_base_url (s: detachable READABLE_STRING_8)
-- Set base_url to `s'
do
connector.set_base (s)
end
feature -- Server
listen (a_port: INTEGER)
do
configuration.http_server_port := a_port
connector.launch
end
shutdown
-- Shutdown the server
do
connector.server.shutdown_server
end
note
copyright: "2011-2014, 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

@@ -0,0 +1,160 @@
note
description: "Summary description for {WGI_NINO_CONNECTOR}."
date: "$Date$"
revision: "$Revision$"
class
WGI_NINO_CONNECTOR
inherit
WGI_CONNECTOR
create
make,
make_with_base
feature {NONE} -- Initialization
make (a_service: like service)
local
cfg: HTTP_SERVER_CONFIGURATION
do
service := a_service
create cfg.make
create server.make (cfg)
-- Callbacks
create on_launched_actions
create on_stopped_actions
end
make_with_base (a_service: like service; a_base: like base)
require
a_base_starts_with_slash: (a_base /= Void and then not a_base.is_empty) implies a_base.starts_with ("/")
do
make (a_service)
set_base (a_base)
end
feature -- Access
name: STRING_8 = "Nino"
-- Name of Current connector
version: STRING_8 = "0.1"
-- Version of Current connector
feature {NONE} -- Access
service: WGI_SERVICE
-- Gateway Service
feature -- Access
server: HTTP_SERVER
configuration: HTTP_SERVER_CONFIGURATION
do
Result := server.configuration
end
feature -- Access
base: detachable READABLE_STRING_8
-- Root url base
feature -- Status report
launched: BOOLEAN
-- Server launched and listening on `port'
port: INTEGER
-- Listening port.
--| 0: not launched
feature -- Callbacks
on_launched_actions: ACTION_SEQUENCE [TUPLE [WGI_CONNECTOR]]
-- Actions triggered when launched
on_stopped_actions: ACTION_SEQUENCE [TUPLE [WGI_CONNECTOR]]
-- Actions triggered when stopped
feature -- Element change
on_launched (a_port: INTEGER)
-- Server launched
do
launched := True
port := a_port
on_launched_actions.call ([Current])
end
on_stopped
-- Server stopped
do
on_stopped_actions.call ([Current])
launched := False
port := 0
end
feature -- Element change
set_base (b: like base)
require
b_starts_with_slash: (b /= Void and then not b.is_empty) implies b.starts_with ("/")
do
base := b
ensure
valid_base: (attached base as l_base and then not l_base.is_empty) implies l_base.starts_with ("/")
end
feature -- Server
launch
local
l_http_handler : HTTP_HANDLER
do
launched := False
port := 0
create {WGI_NINO_HANDLER} l_http_handler.make_with_callback (server, Current)
if configuration.is_verbose then
if attached base as l_base then
io.error.put_string ("Base=" + l_base + "%N")
end
end
server.setup (l_http_handler)
end
process_request (env: STRING_TABLE [READABLE_STRING_8]; a_headers_text: STRING; a_socket: TCP_STREAM_SOCKET)
local
req: WGI_REQUEST_FROM_TABLE
res: detachable WGI_NINO_RESPONSE_STREAM
retried: BOOLEAN
do
if not retried then
create req.make (env, create {WGI_NINO_INPUT_STREAM}.make (a_socket), Current)
create res.make (create {WGI_NINO_OUTPUT_STREAM}.make (a_socket), create {WGI_NINO_ERROR_STREAM}.make_stderr (a_socket.descriptor.out))
req.set_meta_string_variable ("RAW_HEADER_DATA", a_headers_text)
service.execute (req, res)
res.push
end
rescue
if not retried then
retried := True
retry
end
end
note
copyright: "2011-2013, 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

@@ -0,0 +1,260 @@
note
description : "Objects that ..."
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
class
WGI_NINO_HANDLER
inherit
HTTP_CONNECTION_HANDLER
redefine
on_launched,
on_stopped
end
create
make_with_callback
feature {NONE} -- Initialization
make_with_callback (a_server: like server; a_callback: like callback)
-- Initialize `Current'.
do
base := a_callback.base
make (a_server)
callback := a_callback
end
callback: WGI_NINO_CONNECTOR
feature -- Access
base: detachable READABLE_STRING_8
-- Root url base
feature -- Element change
on_launched (a_port: INTEGER)
do
Precursor (a_port)
callback.on_launched (a_port)
end
on_stopped
do
Precursor
callback.on_stopped
end
feature -- Element change
set_base (a_uri: like base)
-- Set `base' to `a_uri'
do
base := a_uri
end
feature -- Request processing
process_request (a_handler: HTTP_CONNECTION_HANDLER; a_socket: TCP_STREAM_SOCKET)
-- Process request ...
local
env: STRING_TABLE [READABLE_STRING_8]
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 := a_handler.uri
l_headers_map := a_handler.request_header_map
create e
create enc
if attached e.starting_environment as vars then
create env.make_equal (vars.count)
across
vars as c
loop
env.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 env.make (0)
end
--| for Any Abc-Def-Ghi add (or replace) the HTTP_ABC_DEF_GHI variable to `env'
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, env)
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: env.has ("HTTP_HOST") end
-- set_environment_variable (l_host, "HTTP_HOST", env)
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: env.has ("HTTP_AUTHORIZATION") end
-- set_environment_variable (l_authorization, "HTTP_AUTHORIZATION", env)
p := l_authorization.index_of (' ', 1)
if p > 0 then
set_environment_variable (l_authorization.substring (1, p - 1), "AUTH_TYPE", env)
end
end
set_environment_variable ("CGI/1.1", "GATEWAY_INTERFACE", env)
set_environment_variable (l_query_string, "QUERY_STRING", env)
if attached a_handler.remote_info as l_remote_info then
set_environment_variable (l_remote_info.addr, "REMOTE_ADDR", env)
set_environment_variable (l_remote_info.hostname, "REMOTE_HOST", env)
set_environment_variable (l_remote_info.port.out, "REMOTE_PORT", env)
-- set_environment_variable (Void, "REMOTE_IDENT", env)
-- set_environment_variable (Void, "REMOTE_USER", env)
end
set_environment_variable (l_request_uri, "REQUEST_URI", env)
set_environment_variable (a_handler.method, "REQUEST_METHOD", env)
set_environment_variable (l_script_name, "SCRIPT_NAME", env)
set_environment_variable (l_server_name, "SERVER_NAME", env)
set_environment_variable (l_server_port, "SERVER_PORT", env)
set_environment_variable (a_handler.version, "SERVER_PROTOCOL", env)
set_environment_variable ({HTTP_SERVER_CONFIGURATION}.Server_details, "SERVER_SOFTWARE", env)
--| 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
env.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
env.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)
env.force (enc.decoded_utf_8_string (l_path_info), "PATH_INFO")
end
callback.process_request (env, a_handler.request_header, a_socket)
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-2013, 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