Migrated most of the example and library to new design.
This commit is contained in:
@@ -8,23 +8,11 @@ class
|
||||
|
||||
inherit
|
||||
|
||||
WSF_ROUTED_SERVICE
|
||||
rename
|
||||
execute as execute_router
|
||||
end
|
||||
|
||||
WSF_FILTERED_SERVICE
|
||||
|
||||
WSF_DEFAULT_SERVICE
|
||||
WSF_DEFAULT_SERVICE [APPLICATION_EXECUTION]
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
|
||||
WSF_FILTER
|
||||
rename
|
||||
execute as execute_router
|
||||
end
|
||||
|
||||
create
|
||||
make_and_launch
|
||||
|
||||
@@ -33,75 +21,8 @@ feature {NONE} -- Initialization
|
||||
initialize
|
||||
-- Initialize current service.
|
||||
do
|
||||
initialize_router
|
||||
initialize_filter
|
||||
Precursor
|
||||
set_service_option ("port", 7070)
|
||||
end
|
||||
|
||||
feature -- Router and Filter
|
||||
|
||||
create_filter
|
||||
-- Create `filter'
|
||||
local
|
||||
f, l_filter: detachable WSF_FILTER
|
||||
do
|
||||
l_filter := Void
|
||||
|
||||
-- Maintenance
|
||||
create {WSF_MAINTENANCE_FILTER} f
|
||||
f.set_next (l_filter)
|
||||
l_filter := f
|
||||
|
||||
-- Logging
|
||||
create {WSF_LOGGING_FILTER} f
|
||||
f.set_next (l_filter)
|
||||
l_filter := f
|
||||
filter := l_filter
|
||||
end
|
||||
|
||||
setup_filter
|
||||
-- Setup `filter'
|
||||
local
|
||||
f: WSF_FILTER
|
||||
do
|
||||
from
|
||||
f := filter
|
||||
until
|
||||
not attached f.next as l_next
|
||||
loop
|
||||
f := l_next
|
||||
end
|
||||
f.set_next (Current)
|
||||
end
|
||||
|
||||
setup_router
|
||||
do
|
||||
map_agent_uri ("/", agent execute_hello, Void)
|
||||
-- NOTE: you could put all those files in a specific folder, and use WSF_FILE_SYSTEM_HANDLER with "/"
|
||||
-- this way, it handles the caching and so on
|
||||
router.handle_with_request_methods ("/assets", create {WSF_FILE_SYSTEM_HANDLER}.make_hidden ("assets"), router.methods_GET)
|
||||
end
|
||||
|
||||
feature -- Helper: mapping
|
||||
|
||||
map_agent_uri (a_uri: READABLE_STRING_8; a_action: like {WSF_URI_AGENT_HANDLER}.action; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
do
|
||||
router.map_with_request_methods (create {WSF_URI_MAPPING}.make (a_uri, create {WSF_URI_AGENT_HANDLER}.make (a_action)), rqst_methods)
|
||||
end
|
||||
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute_hello (request: WSF_REQUEST; response: WSF_RESPONSE)
|
||||
local
|
||||
page: EMPTY_PAGE
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
create page.make (request, response)
|
||||
page.execute
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
note
|
||||
description: "simple application root class"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
APPLICATION_EXECUTION
|
||||
|
||||
inherit
|
||||
|
||||
WSF_FILTERED_ROUTED_EXECUTION
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Router and Filter
|
||||
|
||||
create_filter
|
||||
-- Create `filter'
|
||||
do
|
||||
-- Maintenance
|
||||
create {WSF_MAINTENANCE_FILTER} filter
|
||||
end
|
||||
|
||||
setup_filter
|
||||
-- Setup `filter'
|
||||
do
|
||||
append_filters (<<create {WSF_LOGGING_FILTER}>>)
|
||||
end
|
||||
|
||||
setup_router
|
||||
do
|
||||
map_agent_uri ("/", agent execute_hello, Void)
|
||||
-- NOTE: you could put all those files in a specific folder, and use WSF_FILE_SYSTEM_HANDLER with "/"
|
||||
-- this way, it handles the caching and so on
|
||||
router.handle_with_request_methods ("/assets", create {WSF_FILE_SYSTEM_HANDLER}.make_hidden ("assets"), router.methods_GET)
|
||||
end
|
||||
|
||||
feature -- Helper: mapping
|
||||
|
||||
map_agent_uri (a_uri: READABLE_STRING_8; a_action: like {WSF_URI_AGENT_HANDLER}.action; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
do
|
||||
router.map_with_request_methods (create {WSF_URI_MAPPING}.make (a_uri, create {WSF_URI_AGENT_HANDLER}.make (a_action)), rqst_methods)
|
||||
end
|
||||
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute_hello (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
page: EMPTY_PAGE
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
create page.make (req, res)
|
||||
page.execute
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
@@ -8,23 +8,11 @@ class
|
||||
|
||||
inherit
|
||||
|
||||
WSF_ROUTED_SERVICE
|
||||
rename
|
||||
execute as execute_router
|
||||
end
|
||||
|
||||
WSF_FILTERED_SERVICE
|
||||
|
||||
WSF_DEFAULT_SERVICE
|
||||
WSF_DEFAULT_SERVICE [APPLICATION_EXECUTION]
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
|
||||
WSF_FILTER
|
||||
rename
|
||||
execute as execute_router
|
||||
end
|
||||
|
||||
create
|
||||
make_and_launch
|
||||
|
||||
@@ -33,75 +21,8 @@ feature {NONE} -- Initialization
|
||||
initialize
|
||||
-- Initialize current service.
|
||||
do
|
||||
initialize_router
|
||||
initialize_filter
|
||||
Precursor
|
||||
set_service_option ("port", 7070)
|
||||
end
|
||||
|
||||
feature -- Router and Filter
|
||||
|
||||
create_filter
|
||||
-- Create `filter'
|
||||
local
|
||||
f, l_filter: detachable WSF_FILTER
|
||||
do
|
||||
l_filter := Void
|
||||
|
||||
-- Maintenance
|
||||
create {WSF_MAINTENANCE_FILTER} f
|
||||
f.set_next (l_filter)
|
||||
l_filter := f
|
||||
|
||||
-- Logging
|
||||
create {WSF_LOGGING_FILTER} f
|
||||
f.set_next (l_filter)
|
||||
l_filter := f
|
||||
filter := l_filter
|
||||
end
|
||||
|
||||
setup_filter
|
||||
-- Setup `filter'
|
||||
local
|
||||
f: WSF_FILTER
|
||||
do
|
||||
from
|
||||
f := filter
|
||||
until
|
||||
not attached f.next as l_next
|
||||
loop
|
||||
f := l_next
|
||||
end
|
||||
f.set_next (Current)
|
||||
end
|
||||
|
||||
setup_router
|
||||
do
|
||||
map_agent_uri ("/", agent execute_hello, Void)
|
||||
-- NOTE: you could put all those files in a specific folder, and use WSF_FILE_SYSTEM_HANDLER with "/"
|
||||
-- this way, it handles the caching and so on
|
||||
router.handle_with_request_methods ("/assets", create {WSF_FILE_SYSTEM_HANDLER}.make_hidden ("assets"), router.methods_GET)
|
||||
end
|
||||
|
||||
feature -- Helper: mapping
|
||||
|
||||
map_agent_uri (a_uri: READABLE_STRING_8; a_action: like {WSF_URI_AGENT_HANDLER}.action; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
do
|
||||
router.map_with_request_methods (create {WSF_URI_MAPPING}.make (a_uri, create {WSF_URI_AGENT_HANDLER}.make (a_action)), rqst_methods)
|
||||
end
|
||||
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute_hello (request: WSF_REQUEST; response: WSF_RESPONSE)
|
||||
local
|
||||
page: EMPTY_PAGE
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
create page.make (request, response)
|
||||
page.execute
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
note
|
||||
description: "simple application root class"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
APPLICATION_EXECUTION
|
||||
|
||||
inherit
|
||||
|
||||
WSF_FILTERED_ROUTED_EXECUTION
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Router and Filter
|
||||
|
||||
create_filter
|
||||
-- Create `filter'
|
||||
do
|
||||
-- Maintenance
|
||||
create {WSF_MAINTENANCE_FILTER} filter
|
||||
end
|
||||
|
||||
setup_filter
|
||||
-- Setup `filter'
|
||||
do
|
||||
append_filters (<< create {WSF_LOGGING_FILTER} >>)
|
||||
end
|
||||
|
||||
setup_router
|
||||
do
|
||||
map_agent_uri ("/", agent execute_hello, Void)
|
||||
-- NOTE: you could put all those files in a specific folder, and use WSF_FILE_SYSTEM_HANDLER with "/"
|
||||
-- this way, it handles the caching and so on
|
||||
router.handle_with_request_methods ("/assets", create {WSF_FILE_SYSTEM_HANDLER}.make_hidden ("assets"), router.methods_GET)
|
||||
end
|
||||
|
||||
feature -- Helper: mapping
|
||||
|
||||
map_agent_uri (a_uri: READABLE_STRING_8; a_action: like {WSF_URI_AGENT_HANDLER}.action; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
do
|
||||
router.map_with_request_methods (create {WSF_URI_MAPPING}.make (a_uri, create {WSF_URI_AGENT_HANDLER}.make (a_action)), rqst_methods)
|
||||
end
|
||||
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute_hello (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
page: EMPTY_PAGE
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
create page.make (req, res)
|
||||
page.execute
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
@@ -8,168 +8,22 @@ class
|
||||
|
||||
inherit
|
||||
|
||||
WSF_ROUTED_SERVICE
|
||||
rename
|
||||
execute as execute_router
|
||||
end
|
||||
|
||||
WSF_FILTERED_SERVICE
|
||||
|
||||
WSF_DEFAULT_SERVICE
|
||||
WSF_DEFAULT_SERVICE [APPLICATION_EXECUTION]
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
|
||||
WSF_FILTER
|
||||
rename
|
||||
execute as execute_router
|
||||
end
|
||||
|
||||
create
|
||||
make_and_launch
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
-- tt
|
||||
-- local
|
||||
-- lst: ARRAYED_LIST [READABLE_STRING_GENERAL]
|
||||
-- do
|
||||
-- create lst.make (3)
|
||||
-- lst.compare_objects
|
||||
-- lst.extend ({STRING_32} "abc")
|
||||
-- if lst.has ("abc") then
|
||||
-- print ("found%N")
|
||||
-- end
|
||||
-- end
|
||||
|
||||
initialize
|
||||
-- Initialize current service.
|
||||
do
|
||||
-- tt
|
||||
initialize_router
|
||||
initialize_filter
|
||||
Precursor
|
||||
set_service_option ("port", 9090)
|
||||
end
|
||||
|
||||
feature -- Router and Filter
|
||||
|
||||
create_filter
|
||||
-- Create `filter'
|
||||
local
|
||||
f, l_filter: detachable WSF_FILTER
|
||||
do
|
||||
l_filter := Void
|
||||
|
||||
-- Maintenance
|
||||
create {WSF_MAINTENANCE_FILTER} f
|
||||
f.set_next (l_filter)
|
||||
l_filter := f
|
||||
|
||||
-- Logging
|
||||
create {WSF_LOGGING_FILTER} f
|
||||
f.set_next (l_filter)
|
||||
l_filter := f
|
||||
filter := l_filter
|
||||
end
|
||||
|
||||
setup_filter
|
||||
-- Setup `filter'
|
||||
local
|
||||
f: WSF_FILTER
|
||||
do
|
||||
from
|
||||
f := filter
|
||||
until
|
||||
not attached f.next as l_next
|
||||
loop
|
||||
f := l_next
|
||||
end
|
||||
f.set_next (Current)
|
||||
end
|
||||
|
||||
setup_router
|
||||
do
|
||||
map_agent_uri ("/", agent execute_hello, Void)
|
||||
map_agent_uri ("/grid", agent grid_demo, Void)
|
||||
map_agent_uri ("/repeater", agent repeater_demo, Void)
|
||||
map_agent_uri ("/slider", agent slider_demo, Void)
|
||||
map_agent_uri ("/upload", agent upload_demo, Void)
|
||||
map_agent_uri ("/codeview", agent codeview, Void)
|
||||
|
||||
-- NOTE: you could put all those files in a specific folder, and use WSF_FILE_SYSTEM_HANDLER with "/"
|
||||
-- this way, it handles the caching and so on
|
||||
router.handle_with_request_methods ("/assets", create {WSF_FILE_SYSTEM_HANDLER}.make_hidden ("assets"), router.methods_GET)
|
||||
end
|
||||
|
||||
feature -- Helper: mapping
|
||||
|
||||
map_agent_uri (a_uri: READABLE_STRING_8; a_action: like {WSF_URI_AGENT_HANDLER}.action; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
do
|
||||
router.map_with_request_methods (create {WSF_URI_MAPPING}.make (a_uri, create {WSF_URI_AGENT_HANDLER}.make (a_action)), rqst_methods)
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute_hello (request: WSF_REQUEST; response: WSF_RESPONSE)
|
||||
local
|
||||
page: SAMPLE_PAGE
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
create page.make (request, response)
|
||||
page.execute
|
||||
end
|
||||
|
||||
grid_demo (request: WSF_REQUEST; response: WSF_RESPONSE)
|
||||
local
|
||||
page: GRID_PAGE
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
create page.make (request, response)
|
||||
page.execute
|
||||
end
|
||||
|
||||
repeater_demo (request: WSF_REQUEST; response: WSF_RESPONSE)
|
||||
local
|
||||
page: REPEATER_PAGE
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
create page.make (request, response)
|
||||
page.execute
|
||||
end
|
||||
|
||||
slider_demo (request: WSF_REQUEST; response: WSF_RESPONSE)
|
||||
local
|
||||
page: SLIDER_PAGE
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
create page.make (request, response)
|
||||
page.execute
|
||||
end
|
||||
|
||||
upload_demo (request: WSF_REQUEST; response: WSF_RESPONSE)
|
||||
local
|
||||
page: UPLOAD_PAGE
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
create page.make (request, response)
|
||||
page.execute
|
||||
end
|
||||
|
||||
codeview (request: WSF_REQUEST; response: WSF_RESPONSE)
|
||||
local
|
||||
page: CODEVIEW_PAGE
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
create page.make (request, response)
|
||||
page.execute
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
note
|
||||
description: "Summary description for {APPLICATION_EXECUTION}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
APPLICATION_EXECUTION
|
||||
|
||||
inherit
|
||||
WSF_FILTERED_ROUTED_EXECUTION
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Router and Filter
|
||||
|
||||
create_filter
|
||||
-- Create `filter'
|
||||
do
|
||||
-- Maintenance
|
||||
create {WSF_MAINTENANCE_FILTER} filter
|
||||
end
|
||||
|
||||
setup_filter
|
||||
-- Setup `filter'
|
||||
do
|
||||
append_filters (<<create {WSF_LOGGING_FILTER}>>)
|
||||
end
|
||||
|
||||
setup_router
|
||||
do
|
||||
map_agent_uri ("/", agent execute_hello, Void)
|
||||
map_agent_uri ("/grid", agent grid_demo, Void)
|
||||
map_agent_uri ("/repeater", agent repeater_demo, Void)
|
||||
map_agent_uri ("/slider", agent slider_demo, Void)
|
||||
map_agent_uri ("/upload", agent upload_demo, Void)
|
||||
map_agent_uri ("/codeview", agent codeview, Void)
|
||||
|
||||
-- NOTE: you could put all those files in a specific folder, and use WSF_FILE_SYSTEM_HANDLER with "/"
|
||||
-- this way, it handles the caching and so on
|
||||
router.handle_with_request_methods ("/assets", create {WSF_FILE_SYSTEM_HANDLER}.make_hidden ("assets"), router.methods_GET)
|
||||
end
|
||||
|
||||
feature -- Helper: mapping
|
||||
|
||||
map_agent_uri (a_uri: READABLE_STRING_8; a_action: like {WSF_URI_AGENT_HANDLER}.action; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
do
|
||||
router.map_with_request_methods (create {WSF_URI_MAPPING}.make (a_uri, create {WSF_URI_AGENT_HANDLER}.make (a_action)), rqst_methods)
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute_hello (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
page: SAMPLE_PAGE
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
create page.make (req, res)
|
||||
page.execute
|
||||
end
|
||||
|
||||
grid_demo (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
page: GRID_PAGE
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
create page.make (req, res)
|
||||
page.execute
|
||||
end
|
||||
|
||||
repeater_demo (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
page: REPEATER_PAGE
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
create page.make (req, res)
|
||||
page.execute
|
||||
end
|
||||
|
||||
slider_demo (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
page: SLIDER_PAGE
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
create page.make (req, res)
|
||||
page.execute
|
||||
end
|
||||
|
||||
upload_demo (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
page: UPLOAD_PAGE
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
create page.make (req, res)
|
||||
page.execute
|
||||
end
|
||||
|
||||
codeview (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
page: CODEVIEW_PAGE
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
create page.make (req, res)
|
||||
page.execute
|
||||
end
|
||||
|
||||
end
|
||||
@@ -20,15 +20,15 @@
|
||||
<root class="EWF_DEBUG_SERVER" feature="make_and_launch"/>
|
||||
<setting name="concurrency" value="scoop"/>
|
||||
<library name="cgi" location="..\..\library\server\wsf\connector\cgi-safe.ecf" readonly="false"/>
|
||||
<library name="httpd" location="..\..\library\server\wsf\connector\httpd-safe.ecf" readonly="false"/>
|
||||
<library name="standalone" location="..\..\library\server\wsf\connector\standalone-safe.ecf" readonly="false"/>
|
||||
<library name="libfcgi" location="..\..\library\server\wsf\connector\libfcgi-safe.ecf" readonly="false"/>
|
||||
<library name="nino" location="..\..\library\server\wsf\connector\nino-safe.ecf" readonly="false"/>
|
||||
<cluster name="launcher" location=".\launcher\any\" recursive="true"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
<target name="debug_httpd" extends="common">
|
||||
<target name="debug_standalone" extends="common">
|
||||
<root class="EWF_DEBUG_SERVER" feature="make_and_launch"/>
|
||||
<library name="default_httpd" location="..\..\library\server\wsf\default\httpd-safe.ecf" readonly="false"/>
|
||||
<library name="default_standalone" location="..\..\library\server\wsf\default\standalone-safe.ecf" readonly="false"/>
|
||||
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
|
||||
@@ -22,8 +22,8 @@ feature -- Execution
|
||||
nature: like launcher_nature
|
||||
do
|
||||
nature := launcher_nature
|
||||
if nature = Void or else nature = nature_httpd then
|
||||
launch_httpd (opts)
|
||||
if nature = Void or else nature = nature_standalone then
|
||||
launch_standalone (opts)
|
||||
elseif nature = nature_nino then
|
||||
launch_nino (opts)
|
||||
elseif nature = nature_cgi then
|
||||
@@ -52,8 +52,8 @@ feature {NONE} -- Access
|
||||
ext := l_entry.extension
|
||||
end
|
||||
if ext /= Void then
|
||||
if ext.same_string (nature_httpd) then
|
||||
Result := nature_httpd
|
||||
if ext.same_string (nature_standalone) then
|
||||
Result := nature_standalone
|
||||
end
|
||||
if ext.same_string (nature_nino) then
|
||||
Result := nature_nino
|
||||
@@ -65,16 +65,16 @@ feature {NONE} -- Access
|
||||
Result := nature_libfcgi
|
||||
end
|
||||
end
|
||||
Result := nature_httpd
|
||||
Result := nature_standalone
|
||||
end
|
||||
|
||||
feature {NONE} -- nino
|
||||
|
||||
nature_httpd: STRING = "httpd"
|
||||
nature_standalone: STRING = "standalone"
|
||||
|
||||
launch_httpd (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
|
||||
launch_standalone (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
|
||||
local
|
||||
launcher: WSF_HTTPD_SERVICE_LAUNCHER [G]
|
||||
launcher: WSF_STANDALONE_SERVICE_LAUNCHER [G]
|
||||
do
|
||||
create launcher.make_and_launch (opts)
|
||||
end
|
||||
|
||||
@@ -7,17 +7,16 @@
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true"/>
|
||||
</option>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<precompile name="vision2-pre" location="$ISE_PRECOMP\vision2-mt-safe.ecf"/>
|
||||
<setting name="concurrency" value="scoop"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\library\server\ewsgi\ewsgi-safe.ecf"/>
|
||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
|
||||
<library name="vision2" location="$ISE_LIBRARY\library\vision2\vision2-safe.ecf"/>
|
||||
<library name="web_browser" location="$ISE_LIBRARY\library\web_browser\web_browser-safe.ecf" readonly="false"/>
|
||||
<library name="wsf" location="..\..\library\server\wsf\wsf-safe.ecf"/>
|
||||
<library name="wsf_nino" location="..\..\library\server\wsf\connector\nino-safe.ecf"/>
|
||||
<library name="wsf_nino_connector" location="..\..\library\server\ewsgi\connectors\nino\nino-safe.ecf"/>
|
||||
<cluster name="src" location=".\src" recursive="true">
|
||||
<library name="wsf_standalone" location="..\..\library\server\wsf\connector\standalone-safe.ecf"/>
|
||||
<library name="wsf_standalone_connector" location="..\..\library\server\ewsgi\connectors\standalone\standalone-safe.ecf"/>
|
||||
<cluster name="src" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
|
||||
239
examples/desktop_app/src/app_embedded_web_execution.e
Normal file
239
examples/desktop_app/src/app_embedded_web_execution.e
Normal file
@@ -0,0 +1,239 @@
|
||||
note
|
||||
description: "Summary description for {APP_EMBEDDED_WEB_EXECUTION}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
APP_EMBEDDED_WEB_EXECUTION
|
||||
|
||||
inherit
|
||||
EMBEDDED_WEB_EXECUTION
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
initialize
|
||||
do
|
||||
Precursor
|
||||
create request_exit_operation_actions
|
||||
local_connection_restriction_enabled := True
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
request_exit_operation_actions: ACTION_SEQUENCE [TUPLE]
|
||||
|
||||
execute
|
||||
-- Execute the request
|
||||
-- See `request.input' for input stream
|
||||
-- `request.meta_variables' for the CGI meta variable
|
||||
-- and `response' for output buffer
|
||||
local
|
||||
router: WSF_ROUTER
|
||||
sess: detachable WSF_ROUTER_SESSION
|
||||
m: WSF_HTML_PAGE_RESPONSE
|
||||
b: STRING
|
||||
fs: WSF_FILE_SYSTEM_HANDLER
|
||||
req: like request
|
||||
do
|
||||
req := request
|
||||
|
||||
create router.make (3)
|
||||
router.handle ("/test/{var}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_test))
|
||||
router.handle ("/env", create {WSF_URI_AGENT_HANDLER}.make (agent handle_env))
|
||||
router.handle ("/exit", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_exit))
|
||||
create fs.make_with_path ((create {EXECUTION_ENVIRONMENT}).current_working_path.extended ("files"))
|
||||
router.handle ("/files", fs)
|
||||
create sess
|
||||
router.dispatch (req, response, sess)
|
||||
if not sess.dispatched then
|
||||
create m.make
|
||||
create b.make_from_string ("<h1>Hello Eiffel desktop user</h1>")
|
||||
b.append ("<li><a href=%"" + req.script_url ("/test/start") + "%">test</a></li>")
|
||||
b.append ("<li><a href=%"" + req.script_url ("/env") + "%">env</a></li>")
|
||||
b.append ("<li><a href=%"" + req.script_url ("/files") + "%">files</a></li>")
|
||||
b.append ("<li><a href=%"" + req.script_url ("/exit") + "%">exit</a></li>")
|
||||
m.set_body (b)
|
||||
response.send (m)
|
||||
end
|
||||
end
|
||||
|
||||
handle_test (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
m: WSF_HTML_PAGE_RESPONSE
|
||||
b: STRING
|
||||
l_name: READABLE_STRING_32
|
||||
do
|
||||
if attached {WSF_STRING} req.item ("var") as p_name then
|
||||
l_name := p_name.value
|
||||
else
|
||||
l_name := {STRING_32} "Embedded web service and web_browser in vision2 application"
|
||||
end
|
||||
create m.make
|
||||
create b.make_from_string ("<h1>This is a test about "+ m.html_encoded_string (l_name) +"</h1>")
|
||||
b.append ("<li><a href=%"" + req.script_url ("/") + "%">back to home</a></li>")
|
||||
if l_name.is_case_insensitive_equal_general ("start") then
|
||||
b.append ("<li><a href=%"" + req.script_url ("/test/js") + "%">test javascript+ajax</a></li>")
|
||||
elseif l_name.is_case_insensitive_equal_general ("js") then
|
||||
b.append ("[
|
||||
<div id="myDiv"><h2>Let AJAX change this text</h2>
|
||||
<button type="button" onclick="loadXMLDoc()">Change Content</button>
|
||||
</div>
|
||||
]")
|
||||
m.add_javascript_content ("[
|
||||
function loadXMLDoc()
|
||||
{
|
||||
var xmlhttp;
|
||||
if (window.XMLHttpRequest)
|
||||
{// code for IE7+, Firefox, Chrome, Opera, Safari
|
||||
xmlhttp=new XMLHttpRequest();
|
||||
}
|
||||
else
|
||||
{// code for IE6, IE5
|
||||
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
xmlhttp.onreadystatechange=function()
|
||||
{
|
||||
if (xmlhttp.readyState==4 && xmlhttp.status==200)
|
||||
{
|
||||
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
|
||||
}
|
||||
}
|
||||
xmlhttp.open("GET","/test/ajax.txt",true);
|
||||
xmlhttp.send();
|
||||
}
|
||||
]")
|
||||
elseif l_name.is_case_insensitive_equal_general ("ajax.txt") then
|
||||
b := "This is AJAX response ... from " + req.absolute_script_url ("")
|
||||
end
|
||||
m.set_body (b)
|
||||
res.send (m)
|
||||
end
|
||||
|
||||
handle_env (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
s: STRING_8
|
||||
p: WSF_PAGE_RESPONSE
|
||||
v: STRING_8
|
||||
do
|
||||
create s.make (2048)
|
||||
s.append ("**DEBUG**%N")
|
||||
req.set_raw_input_data_recorded (True)
|
||||
|
||||
append_iterable_to ("Meta variables:", req.meta_variables, s)
|
||||
s.append_character ('%N')
|
||||
|
||||
append_iterable_to ("Path parameters", req.path_parameters, s)
|
||||
s.append_character ('%N')
|
||||
|
||||
append_iterable_to ("Query parameters", req.query_parameters, s)
|
||||
s.append_character ('%N')
|
||||
|
||||
append_iterable_to ("Form parameters", req.form_parameters, s)
|
||||
s.append_character ('%N')
|
||||
|
||||
if attached req.content_type as l_type then
|
||||
s.append ("Content: type=" + l_type.debug_output)
|
||||
s.append (" length=")
|
||||
s.append_natural_64 (req.content_length_value)
|
||||
s.append_character ('%N')
|
||||
create v.make (req.content_length_value.to_integer_32)
|
||||
req.read_input_data_into (v)
|
||||
across
|
||||
v.split ('%N') as v_cursor
|
||||
loop
|
||||
s.append (" |")
|
||||
s.append (v_cursor.item)
|
||||
s.append_character ('%N')
|
||||
end
|
||||
end
|
||||
|
||||
create p.make_with_body (s)
|
||||
p.header.put_content_type_text_plain
|
||||
res.send (p)
|
||||
end
|
||||
|
||||
handle_exit (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
m: WSF_HTML_PAGE_RESPONSE
|
||||
b: STRING
|
||||
do
|
||||
create m.make
|
||||
create b.make_from_string ("<h1>Embedded server is about to shutdown</h1>")
|
||||
b.append ("<li><a href=%"" + req.script_url ("/") + "%">back to home</a></li>")
|
||||
b.append ("<li><a href=%"" + req.script_url ("/bye") + "%">Click to confirm exit operation</a></li>")
|
||||
m.set_body (b)
|
||||
res.send (m)
|
||||
if attached {separate WGI_STANDALONE_CONNECTOR [WGI_EXECUTION]} req.wgi_connector as conn then
|
||||
shutdown_server (conn)
|
||||
end
|
||||
request_exit_operation_actions.call (Void)
|
||||
end
|
||||
|
||||
shutdown_server (conn: separate WGI_STANDALONE_CONNECTOR [WGI_EXECUTION])
|
||||
do
|
||||
conn.shutdown_server
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
append_iterable_to (a_title: READABLE_STRING_8; it: detachable ITERABLE [WSF_VALUE]; s: STRING_8)
|
||||
local
|
||||
n: INTEGER
|
||||
t: READABLE_STRING_8
|
||||
v: READABLE_STRING_8
|
||||
do
|
||||
s.append (a_title)
|
||||
s.append_character (':')
|
||||
if it /= Void then
|
||||
across it as c loop
|
||||
n := n + 1
|
||||
end
|
||||
if n = 0 then
|
||||
s.append (" empty")
|
||||
s.append_character ('%N')
|
||||
else
|
||||
s.append_character ('%N')
|
||||
across
|
||||
it as c
|
||||
loop
|
||||
s.append (" - ")
|
||||
s.append (c.item.url_encoded_name)
|
||||
t := c.item.generating_type
|
||||
if t.same_string ("WSF_STRING") then
|
||||
else
|
||||
s.append_character (' ')
|
||||
s.append_character ('{')
|
||||
s.append (t)
|
||||
s.append_character ('}')
|
||||
end
|
||||
s.append_character ('=')
|
||||
v := c.item.string_representation.as_string_8
|
||||
if v.has ('%N') then
|
||||
s.append_character ('%N')
|
||||
across
|
||||
v.split ('%N') as v_cursor
|
||||
loop
|
||||
s.append (" |")
|
||||
s.append (v_cursor.item)
|
||||
s.append_character ('%N')
|
||||
end
|
||||
else
|
||||
s.append (v)
|
||||
s.append_character ('%N')
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
s.append (" none")
|
||||
s.append_character ('%N')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -8,223 +8,11 @@ class
|
||||
APP_EMBEDDED_WEB_SERVICE
|
||||
|
||||
inherit
|
||||
EMBEDDED_WEB_SERVICE
|
||||
redefine
|
||||
make
|
||||
end
|
||||
EMBEDDED_WEB_SERVICE [APP_EMBEDDED_WEB_EXECUTION]
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
Precursor
|
||||
create request_exit_operation_actions
|
||||
local_connection_restriction_enabled := True
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
request_exit_operation_actions: ACTION_SEQUENCE [TUPLE]
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute the request
|
||||
-- See `req.input' for input stream
|
||||
-- `req.meta_variables' for the CGI meta variable
|
||||
-- and `res' for output buffer
|
||||
local
|
||||
router: WSF_ROUTER
|
||||
sess: detachable WSF_ROUTER_SESSION
|
||||
m: WSF_HTML_PAGE_RESPONSE
|
||||
b: STRING
|
||||
fs: WSF_FILE_SYSTEM_HANDLER
|
||||
do
|
||||
create router.make (3)
|
||||
router.handle ("/test/{var}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_test))
|
||||
router.handle ("/env", create {WSF_URI_AGENT_HANDLER}.make (agent handle_env))
|
||||
router.handle ("/exit", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_exit))
|
||||
create fs.make_with_path ((create {EXECUTION_ENVIRONMENT}).current_working_path.extended ("files"))
|
||||
router.handle ("/files", fs)
|
||||
create sess
|
||||
router.dispatch (req, res, sess)
|
||||
if not sess.dispatched then
|
||||
create m.make
|
||||
create b.make_from_string ("<h1>Hello Eiffel desktop user</h1>")
|
||||
b.append ("<li><a href=%"" + req.script_url ("/test/start") + "%">test</a></li>")
|
||||
b.append ("<li><a href=%"" + req.script_url ("/env") + "%">env</a></li>")
|
||||
b.append ("<li><a href=%"" + req.script_url ("/files") + "%">files</a></li>")
|
||||
b.append ("<li><a href=%"" + req.script_url ("/exit") + "%">exit</a></li>")
|
||||
m.set_body (b)
|
||||
res.send (m)
|
||||
end
|
||||
end
|
||||
|
||||
handle_test (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
m: WSF_HTML_PAGE_RESPONSE
|
||||
b: STRING
|
||||
l_name: READABLE_STRING_32
|
||||
do
|
||||
if attached {WSF_STRING} req.item ("var") as p_name then
|
||||
l_name := p_name.value
|
||||
else
|
||||
l_name := {STRING_32} "Embedded web service and web_browser in vision2 application"
|
||||
end
|
||||
create m.make
|
||||
create b.make_from_string ("<h1>This is a test about "+ m.html_encoded_string (l_name) +"</h1>")
|
||||
b.append ("<li><a href=%"" + req.script_url ("/") + "%">back to home</a></li>")
|
||||
if l_name.is_case_insensitive_equal_general ("start") then
|
||||
b.append ("<li><a href=%"" + req.script_url ("/test/js") + "%">test javascript+ajax</a></li>")
|
||||
elseif l_name.is_case_insensitive_equal_general ("js") then
|
||||
b.append ("[
|
||||
<div id="myDiv"><h2>Let AJAX change this text</h2>
|
||||
<button type="button" onclick="loadXMLDoc()">Change Content</button>
|
||||
</div>
|
||||
]")
|
||||
m.add_javascript_content ("[
|
||||
function loadXMLDoc()
|
||||
{
|
||||
var xmlhttp;
|
||||
if (window.XMLHttpRequest)
|
||||
{// code for IE7+, Firefox, Chrome, Opera, Safari
|
||||
xmlhttp=new XMLHttpRequest();
|
||||
}
|
||||
else
|
||||
{// code for IE6, IE5
|
||||
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
xmlhttp.onreadystatechange=function()
|
||||
{
|
||||
if (xmlhttp.readyState==4 && xmlhttp.status==200)
|
||||
{
|
||||
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
|
||||
}
|
||||
}
|
||||
xmlhttp.open("GET","/test/ajax.txt",true);
|
||||
xmlhttp.send();
|
||||
}
|
||||
]")
|
||||
elseif l_name.is_case_insensitive_equal_general ("ajax.txt") then
|
||||
b := "This is AJAX response ... from " + req.absolute_script_url ("")
|
||||
end
|
||||
m.set_body (b)
|
||||
res.send (m)
|
||||
end
|
||||
|
||||
handle_env (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
s: STRING_8
|
||||
p: WSF_PAGE_RESPONSE
|
||||
v: STRING_8
|
||||
do
|
||||
create s.make (2048)
|
||||
s.append ("**DEBUG**%N")
|
||||
req.set_raw_input_data_recorded (True)
|
||||
|
||||
append_iterable_to ("Meta variables:", req.meta_variables, s)
|
||||
s.append_character ('%N')
|
||||
|
||||
append_iterable_to ("Path parameters", req.path_parameters, s)
|
||||
s.append_character ('%N')
|
||||
|
||||
append_iterable_to ("Query parameters", req.query_parameters, s)
|
||||
s.append_character ('%N')
|
||||
|
||||
append_iterable_to ("Form parameters", req.form_parameters, s)
|
||||
s.append_character ('%N')
|
||||
|
||||
if attached req.content_type as l_type then
|
||||
s.append ("Content: type=" + l_type.debug_output)
|
||||
s.append (" length=")
|
||||
s.append_natural_64 (req.content_length_value)
|
||||
s.append_character ('%N')
|
||||
create v.make (req.content_length_value.to_integer_32)
|
||||
req.read_input_data_into (v)
|
||||
across
|
||||
v.split ('%N') as v_cursor
|
||||
loop
|
||||
s.append (" |")
|
||||
s.append (v_cursor.item)
|
||||
s.append_character ('%N')
|
||||
end
|
||||
end
|
||||
|
||||
create p.make_with_body (s)
|
||||
p.header.put_content_type_text_plain
|
||||
res.send (p)
|
||||
end
|
||||
|
||||
handle_exit (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
m: WSF_HTML_PAGE_RESPONSE
|
||||
b: STRING
|
||||
do
|
||||
create m.make
|
||||
create b.make_from_string ("<h1>Embedded server is about to shutdown</h1>")
|
||||
b.append ("<li><a href=%"" + req.script_url ("/") + "%">back to home</a></li>")
|
||||
m.set_body (b)
|
||||
res.send (m)
|
||||
if attached {WGI_NINO_CONNECTOR} req.wgi_connector as nino then
|
||||
nino.server.shutdown_server
|
||||
end
|
||||
request_exit_operation_actions.call (Void)
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
append_iterable_to (a_title: READABLE_STRING_8; it: detachable ITERABLE [WSF_VALUE]; s: STRING_8)
|
||||
local
|
||||
n: INTEGER
|
||||
t: READABLE_STRING_8
|
||||
v: READABLE_STRING_8
|
||||
do
|
||||
s.append (a_title)
|
||||
s.append_character (':')
|
||||
if it /= Void then
|
||||
across it as c loop
|
||||
n := n + 1
|
||||
end
|
||||
if n = 0 then
|
||||
s.append (" empty")
|
||||
s.append_character ('%N')
|
||||
else
|
||||
s.append_character ('%N')
|
||||
across
|
||||
it as c
|
||||
loop
|
||||
s.append (" - ")
|
||||
s.append (c.item.url_encoded_name)
|
||||
t := c.item.generating_type
|
||||
if t.same_string ("WSF_STRING") then
|
||||
else
|
||||
s.append_character (' ')
|
||||
s.append_character ('{')
|
||||
s.append (t)
|
||||
s.append_character ('}')
|
||||
end
|
||||
s.append_character ('=')
|
||||
v := c.item.string_representation.as_string_8
|
||||
if v.has ('%N') then
|
||||
s.append_character ('%N')
|
||||
across
|
||||
v.split ('%N') as v_cursor
|
||||
loop
|
||||
s.append (" |")
|
||||
s.append (v_cursor.item)
|
||||
s.append_character ('%N')
|
||||
end
|
||||
else
|
||||
s.append (v)
|
||||
s.append_character ('%N')
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
s.append (" none")
|
||||
s.append_character ('%N')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -24,18 +24,17 @@ feature {NONE} -- Initialization
|
||||
-- then launch the application.
|
||||
local
|
||||
l_win: like main_window
|
||||
l_embeded_services: APP_EMBEDDED_WEB_SERVICE
|
||||
l_embedded_service: APP_EMBEDDED_WEB_SERVICE
|
||||
do
|
||||
default_create
|
||||
create l_win.make
|
||||
main_window := l_win
|
||||
l_win.show
|
||||
create l_embeded_services.make
|
||||
l_embeded_services.set_port_number (0) -- Use first available port number
|
||||
create l_embedded_service.make
|
||||
l_embedded_service.set_port_number (0) -- Use first available port number
|
||||
|
||||
l_embeded_services.on_launched_actions.force (agent on_web_service_launched (l_win))
|
||||
l_embeded_services.request_exit_operation_actions.force (agent on_quit)
|
||||
l_embeded_services.launch
|
||||
l_embedded_service.on_launched_actions.force (agent on_web_service_launched (l_win, l_embedded_service))
|
||||
l_embedded_service.launch
|
||||
launch
|
||||
end
|
||||
|
||||
@@ -46,11 +45,44 @@ feature {NONE} -- Initialization
|
||||
end
|
||||
end
|
||||
|
||||
on_web_service_launched (a_win: attached like main_window)
|
||||
on_web_service_launched (a_win: attached like main_window; s: APP_EMBEDDED_WEB_SERVICE)
|
||||
do
|
||||
add_idle_action_kamikaze (agent wait_for_termination (s, Void))
|
||||
add_idle_action_kamikaze (agent a_win.open_link)
|
||||
end
|
||||
|
||||
wait_for_termination (s: APP_EMBEDDED_WEB_SERVICE; a_timeout: detachable EV_TIMEOUT)
|
||||
local
|
||||
t: detachable EV_TIMEOUT
|
||||
do
|
||||
t := a_timeout
|
||||
if t /= Void then
|
||||
t.set_interval (0)
|
||||
end
|
||||
if
|
||||
attached s.observer as obs and then
|
||||
observer_has_terminaded (obs)
|
||||
then
|
||||
if t /= Void then
|
||||
t.destroy
|
||||
end
|
||||
on_quit
|
||||
else
|
||||
if t = Void then
|
||||
create t
|
||||
t.actions.extend (agent wait_for_termination (s, t))
|
||||
else
|
||||
t.set_interval (1_000)
|
||||
end
|
||||
t.set_interval (1_000)
|
||||
end
|
||||
end
|
||||
|
||||
observer_has_terminaded (obs: separate WGI_STANDALONE_SERVER_OBSERVER): BOOLEAN
|
||||
do
|
||||
Result := obs.terminated
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
main_window: detachable MAIN_WINDOW
|
||||
|
||||
63
examples/desktop_app/src/service/embedded_web_execution.e
Normal file
63
examples/desktop_app/src/service/embedded_web_execution.e
Normal file
@@ -0,0 +1,63 @@
|
||||
note
|
||||
description: "Summary description for {EMBEDDED_WEB_EXECUTION}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
EMBEDDED_WEB_EXECUTION
|
||||
|
||||
inherit
|
||||
WSF_EXECUTION
|
||||
rename
|
||||
execute as execute_embedded
|
||||
end
|
||||
|
||||
SHARED_EMBEDED_WEB_SERVICE_INFORMATION
|
||||
|
||||
feature {NONE} -- Execution
|
||||
|
||||
execute_embedded
|
||||
-- Execute the request
|
||||
-- See `request.input' for input stream
|
||||
-- `request.meta_variables' for the CGI meta variable
|
||||
-- and `response' for output buffer
|
||||
local
|
||||
filter: WSF_AGENT_FILTER
|
||||
m: WSF_PAGE_RESPONSE
|
||||
do
|
||||
if local_connection_restriction_enabled then
|
||||
if
|
||||
attached request.remote_addr as l_remote_addr and then
|
||||
l_remote_addr.is_case_insensitive_equal_general ("127.0.0.1")
|
||||
then
|
||||
execute
|
||||
else
|
||||
create m.make_with_body ("Only local connection is allowed")
|
||||
m.set_status_code (403) -- Forbidden
|
||||
response.send (m)
|
||||
end
|
||||
else
|
||||
execute
|
||||
end
|
||||
end
|
||||
|
||||
execute
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
local_connection_restriction_enabled: BOOLEAN
|
||||
-- Accept only local connection?
|
||||
--| based on 127.0.0.1 IP
|
||||
--| TO IMPROVE
|
||||
|
||||
feature -- Change
|
||||
|
||||
set_local_connection_restriction_enabled (b: BOOLEAN)
|
||||
do
|
||||
local_connection_restriction_enabled := b
|
||||
end
|
||||
|
||||
end
|
||||
@@ -5,19 +5,10 @@ note
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
EMBEDDED_WEB_SERVICE
|
||||
EMBEDDED_WEB_SERVICE [G -> EMBEDDED_WEB_EXECUTION create make end]
|
||||
|
||||
inherit
|
||||
THREAD
|
||||
rename
|
||||
make as make_thread,
|
||||
execute as execute_thread
|
||||
end
|
||||
|
||||
WSF_SERVICE
|
||||
rename
|
||||
execute as execute_embedded
|
||||
end
|
||||
|
||||
SHARED_EMBEDED_WEB_SERVICE_INFORMATION
|
||||
|
||||
@@ -25,90 +16,35 @@ feature -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
make_thread
|
||||
create on_launched_actions
|
||||
end
|
||||
|
||||
feature {NONE} -- Execution
|
||||
feature -- Execution
|
||||
|
||||
execute_embedded (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute the request
|
||||
-- See `req.input' for input stream
|
||||
-- `req.meta_variables' for the CGI meta variable
|
||||
-- and `res' for output buffer
|
||||
launch
|
||||
local
|
||||
filter: WSF_AGENT_FILTER
|
||||
m: WSF_PAGE_RESPONSE
|
||||
do
|
||||
if local_connection_restriction_enabled then
|
||||
if
|
||||
attached req.remote_addr as l_remote_addr and then
|
||||
l_remote_addr.is_case_insensitive_equal_general ("127.0.0.1")
|
||||
then
|
||||
execute (req, res)
|
||||
else
|
||||
create m.make_with_body ("Only local connection is allowed")
|
||||
m.set_status_code (403) -- Forbidden
|
||||
res.send (m)
|
||||
end
|
||||
else
|
||||
execute (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
execute_thread
|
||||
local
|
||||
nino: WSF_NINO_SERVICE_LAUNCHER
|
||||
launcher: WSF_STANDALONE_SERVICE_LAUNCHER [G]
|
||||
opts: WSF_SERVICE_LAUNCHER_OPTIONS
|
||||
do
|
||||
create opts.default_create
|
||||
opts.set_verbose (True)
|
||||
opts.set_option ("port", port_number)
|
||||
create nino.make (Current, opts)
|
||||
nino.on_launched_actions.force (agent on_launched)
|
||||
nino.launch
|
||||
create launcher.make (opts)
|
||||
observer := launcher.connector.observer
|
||||
launcher.on_launched_actions.force (agent on_launched)
|
||||
launcher.launch
|
||||
end
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute the request
|
||||
-- See `req.input' for input stream
|
||||
-- `req.meta_variables' for the CGI meta variable
|
||||
-- and `res' for output buffer
|
||||
deferred
|
||||
end
|
||||
observer: detachable separate WGI_STANDALONE_SERVER_OBSERVER
|
||||
|
||||
on_launched (conn: WGI_CONNECTOR)
|
||||
on_launched (conn: WGI_STANDALONE_CONNECTOR [G])
|
||||
do
|
||||
if attached {WGI_NINO_CONNECTOR} conn as nino then
|
||||
set_port_number (nino.port)
|
||||
end
|
||||
set_port_number (conn.port)
|
||||
on_launched_actions.call (Void)
|
||||
end
|
||||
|
||||
feature -- Control
|
||||
|
||||
wait
|
||||
-- Wait for server to be terminated.
|
||||
do
|
||||
join
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
on_launched_actions: ACTION_SEQUENCE [TUPLE]
|
||||
|
||||
feature -- Status report
|
||||
|
||||
local_connection_restriction_enabled: BOOLEAN
|
||||
-- Accept only local connection?
|
||||
--| based on 127.0.0.1 IP
|
||||
--| TO IMPROVE
|
||||
|
||||
feature -- Change
|
||||
|
||||
set_local_connection_restriction_enabled (b: BOOLEAN)
|
||||
do
|
||||
local_connection_restriction_enabled := b
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -11,15 +11,25 @@ feature -- Access
|
||||
|
||||
port_number: INTEGER
|
||||
do
|
||||
Result := port_number_cell.item
|
||||
Result := separate_port_number (port_number_cell)
|
||||
end
|
||||
|
||||
set_port_number (a_port: like port_number)
|
||||
do
|
||||
port_number_cell.replace (a_port)
|
||||
separate_set_port_number (port_number_cell, a_port)
|
||||
end
|
||||
|
||||
port_number_cell: CELL [INTEGER]
|
||||
separate_port_number (cl: like port_number_cell): like port_number
|
||||
do
|
||||
Result := cl.item
|
||||
end
|
||||
|
||||
separate_set_port_number (cl: like port_number_cell; a_port: like port_number)
|
||||
do
|
||||
cl.replace (a_port)
|
||||
end
|
||||
|
||||
port_number_cell: separate CELL [INTEGER]
|
||||
once ("process")
|
||||
create Result.put (0)
|
||||
end
|
||||
|
||||
@@ -1,30 +1,36 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-9-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-9-0 http://www.eiffel.com/developers/xml/configuration-1-9-0.xsd" name="filter" uuid="52FF4B77-0614-4D8B-9B96-C07EC852793E" library_target="filter">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="filter" uuid="52FF4B77-0614-4D8B-9B96-C07EC852793E" library_target="filter">
|
||||
<target name="common">
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option debug="true" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
|
||||
<option debug="true" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="transitional" syntax="provisional">
|
||||
<debug name="nino" enabled="true"/>
|
||||
<assertions precondition="true" postcondition="true" invariant="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf" readonly="true"/>
|
||||
<library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf" readonly="true"/>
|
||||
<library name="http" location="../../library/network/protocol/http/http-safe.ecf" readonly="true"/>
|
||||
<library name="json" location="..\..\contrib\library\text\parser\json\library\json-safe.ecf" readonly="true"/>
|
||||
<library name="wsf" location="..\..\library\server\wsf\wsf-safe.ecf" readonly="true"/>
|
||||
<library name="wsf_router_context" location="..\..\library\server\wsf\wsf_router_context-safe.ecf" readonly="true"/>
|
||||
<library name="wsf_extension" location="..\..\library\server\wsf\wsf_extension-safe.ecf" readonly="true"/>
|
||||
<library name="http" location="..\..\library\network\protocol\http\http-safe.ecf" readonly="true"/>
|
||||
<library name="http_authorization" location="..\..\library\server\authentication\http_authorization\http_authorization-safe.ecf" readonly="true"/>
|
||||
<library name="json" location="..\..\contrib\library\text\parser\json\library\json-safe.ecf" readonly="true"/>
|
||||
<library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf" readonly="true"/>
|
||||
<library name="wsf" location="..\..\library\server\wsf\wsf-safe.ecf" readonly="false"/>
|
||||
<library name="wsf_extension" location="..\..\library\server\wsf\wsf_extension-safe.ecf" readonly="true"/>
|
||||
<library name="wsf_router_context" location="..\..\library\server\wsf\wsf_router_context-safe.ecf" readonly="true"/>
|
||||
</target>
|
||||
<target name="filter_nino" extends="common">
|
||||
<root class="FILTER_SERVER" feature="make"/>
|
||||
<library name="default_nino" location="..\..\library\server\wsf\default\nino-safe.ecf" readonly="true"/>
|
||||
<cluster name="filter" location="src\" recursive="true"/>
|
||||
</target>
|
||||
<target name="filter_standalone" extends="common">
|
||||
<root class="FILTER_SERVER" feature="make"/>
|
||||
<setting name="concurrency" value="scoop"/>
|
||||
<library name="default_standalone" location="..\..\library\server\wsf\default\standalone-safe.ecf" readonly="true"/>
|
||||
<cluster name="filter" location="src\" recursive="true"/>
|
||||
</target>
|
||||
<target name="filter_fcgi" extends="common">
|
||||
<root class="FILTER_SERVER" feature="make"/>
|
||||
<library name="default_libfcgi" location="..\..\library\server\wsf\default\libfcgi-safe.ecf"/>
|
||||
|
||||
@@ -24,6 +24,24 @@ feature -- Initialization
|
||||
|
||||
feature -- Access
|
||||
|
||||
user_by_id (a_id: INTEGER): detachable USER
|
||||
do
|
||||
Result := users.item (a_id)
|
||||
end
|
||||
|
||||
user_by_name (a_name: READABLE_STRING_GENERAL): detachable USER
|
||||
do
|
||||
across
|
||||
users as c
|
||||
until
|
||||
Result /= Void
|
||||
loop
|
||||
if attached c.item as u and then a_name.same_string (u.name) then
|
||||
Result := u
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
user (a_id: INTEGER; a_name: detachable READABLE_STRING_GENERAL): detachable USER
|
||||
-- User with id `a_id' or name `a_name'.
|
||||
require
|
||||
@@ -32,18 +50,9 @@ feature -- Access
|
||||
n: like {USER}.name
|
||||
do
|
||||
if a_id > 0 then
|
||||
Result := users.item (a_id)
|
||||
Result := user_by_id (a_id)
|
||||
elseif a_name /= Void then
|
||||
n := a_name.as_string_8
|
||||
across
|
||||
users as c
|
||||
until
|
||||
Result /= Void
|
||||
loop
|
||||
if attached c.item as u and then u.name.same_string (n) then
|
||||
Result := u
|
||||
end
|
||||
end
|
||||
Result := user_by_name (a_name)
|
||||
end
|
||||
ensure
|
||||
Result /= Void implies ((a_id > 0 and then Result.id = a_id) xor (a_name /= Void and then Result.name.same_string_general (a_name)))
|
||||
@@ -52,6 +61,6 @@ feature -- Access
|
||||
users: HASH_TABLE [USER, INTEGER]
|
||||
|
||||
;note
|
||||
copyright: "2011-2012, Olivier Ligot, Jocelyn Fiat and others"
|
||||
copyright: "2011-2015, Olivier Ligot, Jocelyn Fiat and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
end
|
||||
|
||||
@@ -48,18 +48,31 @@ feature {NONE} -- Implementation
|
||||
-- Handle forbidden.
|
||||
local
|
||||
h: HTTP_HEADER
|
||||
s: STRING
|
||||
do
|
||||
create h.make
|
||||
h.put_content_type_text_plain
|
||||
h.put_content_length (a_description.count)
|
||||
h.put_current_date
|
||||
h.put_header_key_value ({HTTP_HEADER_NAMES}.header_www_authenticate, "Basic realm=%"User%"")
|
||||
s := "Basic realm=%"For this demo, use any of: "
|
||||
across
|
||||
db_access.users as ic
|
||||
loop
|
||||
s.append_character ('(')
|
||||
s.append (ic.item.name)
|
||||
s.append_character (':')
|
||||
s.append (ic.item.password)
|
||||
s.append_character (')')
|
||||
s.append_character (' ')
|
||||
end
|
||||
s.append_character ('"')
|
||||
h.put_header_key_value ({HTTP_HEADER_NAMES}.header_www_authenticate, s)
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
|
||||
res.put_header_text (h.string)
|
||||
res.put_string (a_description)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Olivier Ligot, Jocelyn Fiat and others"
|
||||
copyright: "2011-2015, Olivier Ligot, Jocelyn Fiat and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
end
|
||||
|
||||
@@ -8,18 +8,7 @@ class
|
||||
FILTER_SERVER
|
||||
|
||||
inherit
|
||||
ANY
|
||||
|
||||
WSF_DEFAULT_SERVICE
|
||||
|
||||
WSF_ROUTED_SERVICE
|
||||
undefine
|
||||
execute
|
||||
end
|
||||
|
||||
WSF_FILTERED_SERVICE
|
||||
|
||||
SHARED_EJSON
|
||||
WSF_DEFAULT_SERVICE [FILTER_SERVER_EXECUTION]
|
||||
|
||||
create
|
||||
make
|
||||
@@ -31,9 +20,6 @@ feature {NONE} -- Initialization
|
||||
l_message: STRING
|
||||
l_factory: INET_ADDRESS_FACTORY
|
||||
do
|
||||
initialize_router
|
||||
initialize_filter
|
||||
initialize_json
|
||||
set_service_option ("port", port)
|
||||
create l_message.make_empty
|
||||
l_message.append_string ("Launching filter server at ")
|
||||
@@ -46,60 +32,13 @@ feature {NONE} -- Initialization
|
||||
make_and_launch
|
||||
end
|
||||
|
||||
create_filter
|
||||
-- Create `filter'
|
||||
do
|
||||
create {WSF_CORS_FILTER} filter
|
||||
end
|
||||
|
||||
setup_filter
|
||||
-- Setup `filter'
|
||||
local
|
||||
l_routing_filter: WSF_ROUTING_FILTER
|
||||
l_logging_filter: WSF_LOGGING_FILTER
|
||||
do
|
||||
create l_routing_filter.make (router)
|
||||
l_routing_filter.set_execute_default_action (agent execute_default)
|
||||
filter.set_next (l_routing_filter)
|
||||
|
||||
create l_logging_filter
|
||||
l_routing_filter.set_next (l_logging_filter)
|
||||
end
|
||||
|
||||
setup_router
|
||||
-- Setup `router'
|
||||
local
|
||||
l_options_filter: WSF_CORS_OPTIONS_FILTER
|
||||
l_authentication_filter: AUTHENTICATION_FILTER
|
||||
l_user_filter: USER_HANDLER
|
||||
l_methods: WSF_REQUEST_METHODS
|
||||
do
|
||||
create l_options_filter.make (router)
|
||||
create l_authentication_filter
|
||||
create l_user_filter
|
||||
|
||||
l_options_filter.set_next (l_authentication_filter)
|
||||
l_authentication_filter.set_next (l_user_filter)
|
||||
|
||||
create l_methods
|
||||
l_methods.enable_options
|
||||
l_methods.enable_get
|
||||
router.handle_with_request_methods ("/user/{userid}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent l_options_filter.execute), l_methods)
|
||||
end
|
||||
|
||||
initialize_json
|
||||
-- Initialize `json'.
|
||||
do
|
||||
json.add_converter (create {JSON_USER_CONVERTER}.make)
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
port: INTEGER = 9090
|
||||
-- Port number
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Olivier Ligot, Jocelyn Fiat and others"
|
||||
copyright: "2011-2015, Olivier Ligot, Jocelyn Fiat and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
82
examples/filter/src/filter_server_execution.e
Normal file
82
examples/filter/src/filter_server_execution.e
Normal file
@@ -0,0 +1,82 @@
|
||||
note
|
||||
description : "Filter example."
|
||||
author : "Olivier Ligot"
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
class
|
||||
FILTER_SERVER_EXECUTION
|
||||
|
||||
inherit
|
||||
WSF_FILTERED_ROUTED_EXECUTION
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
|
||||
SHARED_EJSON
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
initialize
|
||||
do
|
||||
Precursor
|
||||
initialize_json
|
||||
end
|
||||
|
||||
create_filter
|
||||
-- Create `filter'
|
||||
do
|
||||
create {WSF_CORS_FILTER} filter
|
||||
end
|
||||
|
||||
setup_filter
|
||||
-- Setup `filter'
|
||||
local
|
||||
l_logging_filter: WSF_LOGGING_FILTER
|
||||
do
|
||||
create l_logging_filter
|
||||
filter.set_next (l_logging_filter)
|
||||
end
|
||||
|
||||
setup_router
|
||||
-- Setup `router'
|
||||
local
|
||||
l_options_filter: WSF_CORS_OPTIONS_FILTER
|
||||
l_authentication_filter: AUTHENTICATION_FILTER
|
||||
l_user_filter: USER_HANDLER
|
||||
l_methods: WSF_REQUEST_METHODS
|
||||
do
|
||||
create l_options_filter.make (router)
|
||||
create l_authentication_filter
|
||||
create l_user_filter
|
||||
|
||||
l_options_filter.set_next (l_authentication_filter)
|
||||
l_authentication_filter.set_next (l_user_filter)
|
||||
|
||||
create l_methods
|
||||
l_methods.enable_options
|
||||
l_methods.enable_get
|
||||
router.handle_with_request_methods ("/user/{userid}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent l_options_filter.execute), l_methods)
|
||||
end
|
||||
|
||||
initialize_json
|
||||
-- Initialize `json'.
|
||||
once
|
||||
-- See SHARED_EJSON, and the once function per thread `json'.
|
||||
json.add_converter (create {JSON_USER_CONVERTER}.make)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Olivier Ligot, Jocelyn Fiat 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
|
||||
@@ -41,7 +41,7 @@ feature -- Basic operations
|
||||
local
|
||||
id : STRING
|
||||
do
|
||||
if attached req.orig_path_info as orig_path then
|
||||
if attached req.path_info as orig_path then
|
||||
id := get_user_id_from_path (orig_path)
|
||||
if attached retrieve_user (id) as l_user then
|
||||
if l_user ~ req.execution_variable ("user") then
|
||||
@@ -86,12 +86,14 @@ feature {NONE} -- Implementation
|
||||
retrieve_user (id: STRING) : detachable USER
|
||||
-- Retrieve the user by id if it exist, in other case, Void
|
||||
do
|
||||
if id.is_integer and then Db_access.users.has (id.to_integer) then
|
||||
Result := db_access.users.item (id.to_integer)
|
||||
if id.is_integer then
|
||||
Result := db_access.user_by_id (id.to_integer)
|
||||
else
|
||||
Result := db_access.user_by_name (id)
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Olivier Ligot, Jocelyn Fiat and others"
|
||||
copyright: "2011-2015, Olivier Ligot, Jocelyn Fiat and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
end
|
||||
|
||||
@@ -6,19 +6,7 @@ note
|
||||
class RESTBUCKS_SERVER
|
||||
|
||||
inherit
|
||||
|
||||
WSF_ROUTED_SKELETON_SERVICE
|
||||
undefine
|
||||
requires_proxy
|
||||
end
|
||||
|
||||
WSF_URI_TEMPLATE_HELPER_FOR_ROUTED_SERVICE
|
||||
|
||||
WSF_HANDLER_HELPER
|
||||
|
||||
WSF_DEFAULT_SERVICE
|
||||
|
||||
WSF_NO_PROXY_POLICY
|
||||
WSF_DEFAULT_SERVICE [RESTBUCKS_SERVER_EXECUTION]
|
||||
|
||||
create
|
||||
make
|
||||
@@ -27,26 +15,12 @@ feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
initialize_router
|
||||
set_service_option ("port", 9090)
|
||||
make_and_launch
|
||||
end
|
||||
|
||||
setup_router
|
||||
local
|
||||
order_handler: ORDER_HANDLER
|
||||
doc: WSF_ROUTER_SELF_DOCUMENTATION_HANDLER
|
||||
do
|
||||
create order_handler.make_with_router (router)
|
||||
router.handle_with_request_methods ("/order", order_handler, router.methods_POST)
|
||||
router.handle_with_request_methods ("/order/{orderid}", order_handler, router.methods_GET + router.methods_DELETE + router.methods_PUT)
|
||||
create doc.make_hidden (router)
|
||||
router.handle_with_request_methods ("/api/doc", doc, router.methods_GET)
|
||||
end
|
||||
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Javier Velilla and others"
|
||||
copyright: "2011-2015, Javier Velilla and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
57
examples/restbucksCRUD/src/restbucks_server_execution.e
Normal file
57
examples/restbucksCRUD/src/restbucks_server_execution.e
Normal file
@@ -0,0 +1,57 @@
|
||||
note
|
||||
description : "REST Buck server"
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
class RESTBUCKS_SERVER_EXECUTION
|
||||
|
||||
inherit
|
||||
|
||||
WSF_ROUTED_SKELETON_EXECUTION
|
||||
undefine
|
||||
requires_proxy
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
|
||||
WSF_URI_TEMPLATE_HELPER_FOR_ROUTED_EXECUTION
|
||||
|
||||
WSF_HANDLER_HELPER
|
||||
|
||||
WSF_NO_PROXY_POLICY
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
initialize
|
||||
do
|
||||
Precursor
|
||||
initialize_router
|
||||
end
|
||||
|
||||
setup_router
|
||||
local
|
||||
order_handler: ORDER_HANDLER
|
||||
doc: WSF_ROUTER_SELF_DOCUMENTATION_HANDLER
|
||||
do
|
||||
create order_handler.make_with_router (router)
|
||||
router.handle_with_request_methods ("/order", order_handler, router.methods_POST)
|
||||
router.handle_with_request_methods ("/order/{orderid}", order_handler, router.methods_GET + router.methods_DELETE + router.methods_PUT)
|
||||
create doc.make_hidden (router)
|
||||
router.handle_with_request_methods ("/api/doc", doc, router.methods_GET)
|
||||
end
|
||||
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Javier Velilla 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
|
||||
@@ -7,7 +7,7 @@ class
|
||||
APPLICATION
|
||||
|
||||
inherit
|
||||
WSF_DEFAULT_SERVICE
|
||||
WSF_DEFAULT_SERVICE [APPLICATION_EXECUTION]
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
@@ -23,14 +23,6 @@ feature {NONE} -- Initialization
|
||||
set_service_option ("port", 9090)
|
||||
end
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
res.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/plain"], ["Content-Length", "11"]>>)
|
||||
res.put_string ("Hello World")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
34
examples/simple/application_execution.e
Normal file
34
examples/simple/application_execution.e
Normal file
@@ -0,0 +1,34 @@
|
||||
note
|
||||
description : "simple application execution"
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
class
|
||||
APPLICATION_EXECUTION
|
||||
|
||||
inherit
|
||||
WSF_EXECUTION
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
execute
|
||||
local
|
||||
s: STRING
|
||||
do
|
||||
-- To send a response we need to setup, the status code and
|
||||
-- the response headers.
|
||||
s := "Hello World!<img src=%"foobar.png%" />"
|
||||
response.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", s.count.out]>>)
|
||||
response.set_status_code ({HTTP_STATUS_CODE}.ok)
|
||||
response.header.put_content_type_text_html
|
||||
response.header.put_content_length (s.count)
|
||||
if attached request.http_connection as l_connection and then l_connection.is_case_insensitive_equal_general ("keep-alive") then
|
||||
response.header.put_header_key_value ("Connection", "keep-alive")
|
||||
end
|
||||
response.put_string (s)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -13,12 +13,12 @@
|
||||
<library name="http" location="..\..\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="wsf" location="..\..\library\server\wsf\wsf-safe.ecf"/>
|
||||
</target>
|
||||
<target name="simple_httpd" extends="common">
|
||||
<target name="simple_standalone" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_httpd" location="..\..\library\server\wsf\default\httpd-safe.ecf"/>
|
||||
<library name="default_standalone" location="..\..\library\server\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="simple" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="simple_nino" extends="common">
|
||||
@@ -45,6 +45,6 @@
|
||||
<library name="default_libfcgi" location="..\..\library\server\wsf\default\libfcgi-safe.ecf"/>
|
||||
<cluster name="simple" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="simple" extends="simple_nino">
|
||||
<target name="simple" extends="simple_standalone">
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="connector_httpd" location="..\..\library\server\ewsgi\connectors\httpd\httpd-safe.ecf"/>
|
||||
<library name="default_httpd" location="..\..\library\server\wsf\default\httpd-safe.ecf"/>
|
||||
<library name="connector_standalone" location="..\..\library\server\ewsgi\connectors\standalone\standalone-safe.ecf"/>
|
||||
<library name="default_standalone" location="..\..\library\server\wsf\default\standalone-safe.ecf"/>
|
||||
<library name="http" location="../../library/network/protocol/http/http-safe.ecf"/>
|
||||
<library name="wsf" location="..\..\library\server\wsf\wsf-safe.ecf"/>
|
||||
<cluster name="service_file" location=".\" recursive="true">
|
||||
|
||||
@@ -8,20 +8,19 @@ class
|
||||
IMAGE_UPLOADER_EXECUTION
|
||||
|
||||
inherit
|
||||
WSF_EXECUTION
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
|
||||
WSF_ROUTED_SKELETON_EXECUTION
|
||||
undefine
|
||||
requires_proxy
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
|
||||
WSF_NO_PROXY_POLICY
|
||||
|
||||
WSF_URI_TEMPLATE_HELPER_FOR_ROUTED_EXECUTION
|
||||
|
||||
SHARED_EXECUTION_ENVIRONMENT
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
@@ -41,7 +40,7 @@ feature {NONE} -- Initialization
|
||||
map_uri_template_agent_with_request_methods ("/upload/{name}{?nb}", agent execute_upload_put, router.methods_put)
|
||||
map_uri_template_agent ("/upload{?nb}", agent execute_upload)
|
||||
|
||||
create www.make (document_root)
|
||||
create www.make_with_path (document_root)
|
||||
www.set_directory_index (<<"index.html">>)
|
||||
www.set_not_found_handler (agent execute_not_found)
|
||||
router.handle_with_request_methods ("", www, router.methods_GET)
|
||||
@@ -49,31 +48,16 @@ feature {NONE} -- Initialization
|
||||
|
||||
feature -- Configuration
|
||||
|
||||
document_root: READABLE_STRING_8
|
||||
document_root: PATH
|
||||
-- Document root to look for files or directories
|
||||
local
|
||||
e: EXECUTION_ENVIRONMENT
|
||||
dn: DIRECTORY_NAME
|
||||
once
|
||||
create e
|
||||
create dn.make_from_string (e.current_working_directory)
|
||||
dn.extend ("htdocs")
|
||||
Result := dn.string
|
||||
if Result [Result.count] = Operating_environment.directory_separator then
|
||||
Result := Result.substring (1, Result.count - 1)
|
||||
end
|
||||
ensure
|
||||
not Result.ends_with (Operating_environment.directory_separator.out)
|
||||
Result := execution_environment.current_working_path.extended ("htdocs")
|
||||
end
|
||||
|
||||
files_root: READABLE_STRING_8
|
||||
files_root: PATH
|
||||
-- Uploaded files will be stored in `files_root' folder
|
||||
local
|
||||
dn: DIRECTORY_NAME
|
||||
once
|
||||
create dn.make_from_string (document_root)
|
||||
dn.extend ("files")
|
||||
Result := dn.string
|
||||
Result := document_root.extended ("files")
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
@@ -109,8 +93,7 @@ feature -- Execution
|
||||
n := 1
|
||||
end
|
||||
if attached {WSF_STRING} req.query_parameter ("demo") as p_demo then
|
||||
create fn.make_from_string (document_root)
|
||||
fn := fn.extended (p_demo.value)
|
||||
fn := document_root.extended (p_demo.value)
|
||||
l_body.append ("File: <input type=%"file%" name=%"uploaded_file[]%" size=%"60%" value=%""+ html_encode (fn.name) +"%"></br>%N")
|
||||
end
|
||||
|
||||
@@ -134,9 +117,8 @@ feature -- Execution
|
||||
n := n + 1
|
||||
l_body.append ("<li>")
|
||||
l_body.append ("<div>" + c.item.name + "=" + html_encode (c.item.filename) + " size=" + c.item.size.out + " type=" + c.item.content_type + "</div>")
|
||||
create fn.make_from_string (files_root)
|
||||
l_safe_filename := c.item.safe_filename
|
||||
fn := fn.extended (l_safe_filename)
|
||||
fn := files_root.extended (l_safe_filename)
|
||||
if c.item.move_to (fn.name) then
|
||||
if c.item.content_type.starts_with ("image") then
|
||||
l_body.append ("%N<a href=%"../files/" + url_encode (l_safe_filename) + "%"><img src=%"../files/"+ l_safe_filename +"%" /></a>")
|
||||
@@ -182,8 +164,7 @@ feature -- Execution
|
||||
if attached new_temporary_output_file ("tmp-uploaded-file_" + n.out) as f then
|
||||
req.read_input_data_into_file (f)
|
||||
f.close
|
||||
create fn.make_from_string (files_root)
|
||||
fn := fn.extended (l_safe_filename)
|
||||
fn := files_root.extended (l_safe_filename)
|
||||
f.rename_file (fn.name)
|
||||
l_body.append ("<li>")
|
||||
l_body.append ("<div>Input data : size=" + f.count.out + " (" + req.content_length_value.out + ")</div>")
|
||||
|
||||
@@ -8,17 +8,8 @@ class
|
||||
|
||||
inherit
|
||||
|
||||
WSF_ROUTED_SKELETON_SERVICE
|
||||
undefine
|
||||
requires_proxy
|
||||
end
|
||||
|
||||
WSF_URI_TEMPLATE_HELPER_FOR_ROUTED_SERVICE
|
||||
|
||||
WSF_SERVICE
|
||||
|
||||
WSF_NO_PROXY_POLICY
|
||||
|
||||
SHARED_EXECUTION_ENVIRONMENT
|
||||
export
|
||||
{NONE} all
|
||||
@@ -31,15 +22,13 @@ feature {NONE} -- Initialization
|
||||
|
||||
make_and_launch
|
||||
local
|
||||
launcher: WSF_NINO_SERVICE_LAUNCHER
|
||||
launcher: WSF_NINO_SERVICE_LAUNCHER [APPLICATION_EXECUTION]
|
||||
opts: WSF_SERVICE_LAUNCHER_OPTIONS
|
||||
do
|
||||
initialize_router
|
||||
|
||||
create opts.make
|
||||
opts.set_verbose (True)
|
||||
opts.set_option ("port", 0)
|
||||
create launcher.make (Current, opts)
|
||||
create launcher.make (opts)
|
||||
launcher.on_launched_actions.extend (agent on_launched)
|
||||
launcher.launch
|
||||
end
|
||||
@@ -49,7 +38,7 @@ feature {NONE} -- Initialization
|
||||
e: EXECUTION_ENVIRONMENT
|
||||
cmd: STRING_32
|
||||
do
|
||||
if attached {WGI_NINO_CONNECTOR} conn as nino then
|
||||
if attached {WGI_NINO_CONNECTOR [APPLICATION_EXECUTION]} conn as nino then
|
||||
e := execution_environment
|
||||
create cmd.make (32)
|
||||
if attached e.item ("COMSPEC") as l_comspec then
|
||||
@@ -64,105 +53,4 @@ feature {NONE} -- Initialization
|
||||
end
|
||||
end
|
||||
|
||||
setup_router
|
||||
do
|
||||
map_uri_template_agent ("/", agent handle_root)
|
||||
map_uri_template_agent ("/openid", agent handle_openid)
|
||||
end
|
||||
|
||||
handle_root (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
m: WSF_HTML_PAGE_RESPONSE
|
||||
s: STRING
|
||||
do
|
||||
create m.make
|
||||
m.set_title ("EWF::OpenID demo")
|
||||
create s.make_empty
|
||||
s.append ("<form action=%"" + req.script_url ("/openid") + "%" method=%"POST%">%N")
|
||||
s.append ("<strong>OpenID identifier</strong> <input type='text' name='openid_identifier' value='' size='60'/>")
|
||||
s.append ("<input type='submit' name='op' value='sign with OpenID' />")
|
||||
s.append ("</form>%N")
|
||||
s.append ("<form action=%"" + req.script_url ("/openid") + "%" method=%"POST%">%N")
|
||||
s.append ("<strong>OpenID identifier</strong> <input type='text' name='openid_identifier' value='https://www.google.com/accounts/o8/id' size='60'/>")
|
||||
s.append ("<input type='submit' name='op' value='sign with Google' />")
|
||||
s.append ("</form>%N")
|
||||
m.set_body (s)
|
||||
res.send (m)
|
||||
end
|
||||
|
||||
handle_openid (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
m: WSF_HTML_PAGE_RESPONSE
|
||||
redir: WSF_HTML_DELAYED_REDIRECTION_RESPONSE
|
||||
s: STRING
|
||||
o: OPENID_CONSUMER
|
||||
v: OPENID_CONSUMER_VALIDATION
|
||||
do
|
||||
if attached req.string_item ("openid.mode") as l_openid_mode then
|
||||
create m.make
|
||||
m.set_title ("EWF::OpenID demo")
|
||||
create s.make_empty
|
||||
|
||||
if l_openid_mode.same_string ("id_res") then
|
||||
o := new_openid_consumer (req)
|
||||
create v.make_from_items (o, req.items_as_string_items)
|
||||
v.validate
|
||||
if v.is_valid then
|
||||
s.append ("<div>User authenticated</div>")
|
||||
s.append ("<ul>Request items")
|
||||
across
|
||||
req.items as c
|
||||
loop
|
||||
s.append ("<li>" + c.item.url_encoded_name + "=" + c.item.string_representation + "</li>")
|
||||
end
|
||||
s.append ("</ul>")
|
||||
s.append ("<ul>Attributes")
|
||||
across
|
||||
v.attributes as c
|
||||
loop
|
||||
s.append ("<li>" + c.key + "=" + c.item + "</li>")
|
||||
end
|
||||
s.append ("</ul>")
|
||||
else
|
||||
s.append ("<div>User authentication failed!!!</div>")
|
||||
end
|
||||
else
|
||||
s.append ("<div>Unexpected OpenID.mode=" + l_openid_mode + "</div>")
|
||||
end
|
||||
m.set_body (s)
|
||||
res.send (m)
|
||||
elseif attached req.string_item ("openid_identifier") as l_id then
|
||||
create s.make_empty
|
||||
|
||||
o := new_openid_consumer (req)
|
||||
s.append ("Testing " + l_id + "<br>%N")
|
||||
s.append ("Return-to" + o.return_url + "<br>")
|
||||
if attached o.auth_url (l_id) as l_auth_url then
|
||||
s.append ("<a href=%""+ l_auth_url + "%">Click to sign with " + l_id + "</a><br>")
|
||||
create redir.make (l_auth_url, 1)
|
||||
s.append ("Automatically follow link in " + redir.delay.out + " second(s)<br>")
|
||||
redir.set_title ("EWF::OpenID demo")
|
||||
redir.set_body (s)
|
||||
res.send (redir)
|
||||
else
|
||||
create m.make
|
||||
m.set_title ("EWF::OpenID demo")
|
||||
m.set_body (s)
|
||||
res.send (m)
|
||||
end
|
||||
else
|
||||
res.redirect_now ("/")
|
||||
end
|
||||
end
|
||||
|
||||
new_openid_consumer (req: WSF_REQUEST): OPENID_CONSUMER
|
||||
do
|
||||
create Result.make (req.absolute_script_url ("/openid"))
|
||||
|
||||
Result.ask_email (True)
|
||||
Result.ask_all_info (False)
|
||||
-- Result.ask_nickname (False)
|
||||
-- Result.ask_fullname (False)
|
||||
-- Result.ask_country (True)
|
||||
end
|
||||
end
|
||||
|
||||
131
library/security/openid/consumer/demo/application_execution.e
Normal file
131
library/security/openid/consumer/demo/application_execution.e
Normal file
@@ -0,0 +1,131 @@
|
||||
note
|
||||
description : "OPENID demo application root class"
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
class
|
||||
APPLICATION_EXECUTION
|
||||
|
||||
inherit
|
||||
|
||||
WSF_ROUTED_SKELETON_EXECUTION
|
||||
undefine
|
||||
requires_proxy
|
||||
end
|
||||
|
||||
WSF_URI_TEMPLATE_HELPER_FOR_ROUTED_EXECUTION
|
||||
|
||||
WSF_NO_PROXY_POLICY
|
||||
|
||||
SHARED_EXECUTION_ENVIRONMENT
|
||||
export
|
||||
{NONE} all
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
setup_router
|
||||
do
|
||||
map_uri_template_agent ("/", agent handle_root)
|
||||
map_uri_template_agent ("/openid", agent handle_openid)
|
||||
end
|
||||
|
||||
handle_root (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
m: WSF_HTML_PAGE_RESPONSE
|
||||
s: STRING
|
||||
do
|
||||
create m.make
|
||||
m.set_title ("EWF::OpenID demo")
|
||||
create s.make_empty
|
||||
s.append ("<form action=%"" + req.script_url ("/openid") + "%" method=%"POST%">%N")
|
||||
s.append ("<strong>OpenID identifier</strong> <input type='text' name='openid_identifier' value='' size='60'/>")
|
||||
s.append ("<input type='submit' name='op' value='sign with OpenID' />")
|
||||
s.append ("</form>%N")
|
||||
s.append ("<form action=%"" + req.script_url ("/openid") + "%" method=%"POST%">%N")
|
||||
s.append ("<strong>OpenID identifier</strong> <input type='text' name='openid_identifier' value='https://www.google.com/accounts/o8/id' size='60'/>")
|
||||
s.append ("<input type='submit' name='op' value='sign with Google' />")
|
||||
s.append ("</form>%N")
|
||||
m.set_body (s)
|
||||
res.send (m)
|
||||
end
|
||||
|
||||
handle_openid (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
m: WSF_HTML_PAGE_RESPONSE
|
||||
redir: WSF_HTML_DELAYED_REDIRECTION_RESPONSE
|
||||
s: STRING
|
||||
o: OPENID_CONSUMER
|
||||
v: OPENID_CONSUMER_VALIDATION
|
||||
do
|
||||
if attached req.string_item ("openid.mode") as l_openid_mode then
|
||||
create m.make
|
||||
m.set_title ("EWF::OpenID demo")
|
||||
create s.make_empty
|
||||
|
||||
if l_openid_mode.same_string ("id_res") then
|
||||
o := new_openid_consumer (req)
|
||||
create v.make_from_items (o, req.items_as_string_items)
|
||||
v.validate
|
||||
if v.is_valid then
|
||||
s.append ("<div>User authenticated</div>")
|
||||
s.append ("<ul>Request items")
|
||||
across
|
||||
req.items as c
|
||||
loop
|
||||
s.append ("<li>" + c.item.url_encoded_name + "=" + c.item.string_representation + "</li>")
|
||||
end
|
||||
s.append ("</ul>")
|
||||
s.append ("<ul>Attributes")
|
||||
across
|
||||
v.attributes as c
|
||||
loop
|
||||
s.append ("<li>" + c.key + "=" + c.item + "</li>")
|
||||
end
|
||||
s.append ("</ul>")
|
||||
else
|
||||
s.append ("<div>User authentication failed!!!</div>")
|
||||
end
|
||||
else
|
||||
s.append ("<div>Unexpected OpenID.mode=" + l_openid_mode + "</div>")
|
||||
end
|
||||
m.set_body (s)
|
||||
res.send (m)
|
||||
elseif attached req.string_item ("openid_identifier") as l_id then
|
||||
create s.make_empty
|
||||
|
||||
o := new_openid_consumer (req)
|
||||
s.append ("Testing " + l_id + "<br>%N")
|
||||
s.append ("Return-to" + o.return_url + "<br>")
|
||||
if attached o.auth_url (l_id) as l_auth_url then
|
||||
s.append ("<a href=%""+ l_auth_url + "%">Click to sign with " + l_id + "</a><br>")
|
||||
create redir.make (l_auth_url, 1)
|
||||
s.append ("Automatically follow link in " + redir.delay.out + " second(s)<br>")
|
||||
redir.set_title ("EWF::OpenID demo")
|
||||
redir.set_body (s)
|
||||
res.send (redir)
|
||||
else
|
||||
create m.make
|
||||
m.set_title ("EWF::OpenID demo")
|
||||
m.set_body (s)
|
||||
res.send (m)
|
||||
end
|
||||
else
|
||||
res.redirect_now ("/")
|
||||
end
|
||||
end
|
||||
|
||||
new_openid_consumer (req: WSF_REQUEST): OPENID_CONSUMER
|
||||
do
|
||||
create Result.make (req.absolute_script_url ("/openid"))
|
||||
|
||||
Result.ask_email (True)
|
||||
Result.ask_all_info (False)
|
||||
-- Result.ask_nickname (False)
|
||||
-- Result.ask_fullname (False)
|
||||
-- Result.ask_country (True)
|
||||
end
|
||||
end
|
||||
@@ -7,13 +7,11 @@ class
|
||||
DEMO_BASIC
|
||||
|
||||
inherit
|
||||
WSF_DEFAULT_SERVICE
|
||||
WSF_DEFAULT_SERVICE [DEMO_BASIC_EXECUTION]
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
|
||||
SHARED_HTML_ENCODER
|
||||
|
||||
create
|
||||
make_and_launch
|
||||
|
||||
@@ -26,210 +24,4 @@ feature {NONE} -- Initialization
|
||||
set_service_option ("verbose", True)
|
||||
end
|
||||
|
||||
feature -- Credentials
|
||||
|
||||
is_known_login (a_login: READABLE_STRING_GENERAL): BOOLEAN
|
||||
-- Is `a_login' a known username?
|
||||
do
|
||||
Result := valid_credentials.has (a_login)
|
||||
end
|
||||
|
||||
is_valid_credential (a_login: READABLE_STRING_GENERAL; a_password: detachable READABLE_STRING_GENERAL): BOOLEAN
|
||||
-- Is `a_login:a_password' a valid credential?
|
||||
do
|
||||
if
|
||||
a_password /= Void and
|
||||
attached valid_credentials.item (a_login) as l_passwd
|
||||
then
|
||||
Result := a_password.is_case_insensitive_equal (l_passwd)
|
||||
end
|
||||
ensure
|
||||
Result implies is_known_login (a_login)
|
||||
end
|
||||
|
||||
demo_credential: STRING_32
|
||||
-- First valid known credential display for demo in dialog.
|
||||
do
|
||||
valid_credentials.start
|
||||
create Result.make_from_string_general (valid_credentials.key_for_iteration)
|
||||
Result.append_character (':')
|
||||
Result.append (valid_credentials.item_for_iteration)
|
||||
end
|
||||
|
||||
valid_credentials: STRING_TABLE [READABLE_STRING_32]
|
||||
-- Password indexed by login.
|
||||
once
|
||||
create Result.make_caseless (3)
|
||||
Result.force ("world", "eiffel")
|
||||
Result.force ("bar", "foo")
|
||||
Result.force ("password", "user")
|
||||
ensure
|
||||
not Result.is_empty
|
||||
end
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
auth: HTTP_AUTHORIZATION
|
||||
l_authenticated_username: detachable READABLE_STRING_32
|
||||
l_invalid_credential: BOOLEAN
|
||||
do
|
||||
if attached req.http_authorization as l_http_auth then
|
||||
create auth.make (l_http_auth)
|
||||
if attached auth.login as l_login and then is_valid_credential (l_login, auth.password) then
|
||||
l_authenticated_username := auth.login
|
||||
else
|
||||
l_invalid_credential := True
|
||||
end
|
||||
end
|
||||
if l_invalid_credential then
|
||||
handle_unauthorized ("ERROR: Invalid credential", req, res)
|
||||
else
|
||||
if l_authenticated_username /= Void then
|
||||
handle_authenticated (l_authenticated_username, req, res)
|
||||
elseif req.path_info.same_string_general ("/login") then
|
||||
handle_unauthorized ("Please provide credential ...", req, res)
|
||||
elseif req.path_info.starts_with_general ("/protected/") then
|
||||
-- any "/protected/*" url
|
||||
handle_unauthorized ("Protected area, please sign in before", req, res)
|
||||
else
|
||||
handle_anonymous (req, res)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
handle_authenticated (a_username: READABLE_STRING_32; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- User `a_username' is authenticated, execute request `req' with response `res'.
|
||||
require
|
||||
valid_username: not a_username.is_empty
|
||||
known_username: is_known_login (a_username)
|
||||
local
|
||||
s: STRING
|
||||
page: WSF_HTML_PAGE_RESPONSE
|
||||
do
|
||||
create s.make_empty
|
||||
|
||||
append_html_header (req, s)
|
||||
|
||||
s.append ("<p>The authenticated user is <strong>")
|
||||
s.append (html_encoder.general_encoded_string (a_username))
|
||||
s.append ("</strong> ...</p>")
|
||||
|
||||
append_html_menu (a_username, req, s)
|
||||
append_html_logout (a_username, req, s)
|
||||
append_html_footer (req, s)
|
||||
|
||||
create page.make
|
||||
page.set_body (s)
|
||||
res.send (page)
|
||||
end
|
||||
|
||||
handle_anonymous (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- No user is authenticated, execute request `req' with response `res'.
|
||||
local
|
||||
s: STRING
|
||||
page: WSF_HTML_PAGE_RESPONSE
|
||||
do
|
||||
create s.make_empty
|
||||
append_html_header (req, s)
|
||||
|
||||
s.append ("Anonymous visitor ...<br/>")
|
||||
|
||||
append_html_login (req, s)
|
||||
append_html_menu (Void, req, s)
|
||||
append_html_footer (req, s)
|
||||
|
||||
create page.make
|
||||
page.set_body (s)
|
||||
res.send (page)
|
||||
end
|
||||
|
||||
handle_unauthorized (a_description: STRING; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Restricted page, authenticated user is required.
|
||||
-- Send `a_description' as part of the response.
|
||||
local
|
||||
h: HTTP_HEADER
|
||||
s: STRING
|
||||
page: WSF_HTML_PAGE_RESPONSE
|
||||
do
|
||||
create s.make_from_string (a_description)
|
||||
|
||||
append_html_login (req, s)
|
||||
append_html_menu (Void, req, s)
|
||||
append_html_footer (req, s)
|
||||
|
||||
create page.make
|
||||
page.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
|
||||
page.header.put_header_key_value ({HTTP_HEADER_NAMES}.header_www_authenticate,
|
||||
"Basic realm=%"Please enter a valid username and password (demo [" + html_encoder.encoded_string (demo_credential) + "])%""
|
||||
--| warning: for this example: a valid credential is provided in the message, of course that for real application.
|
||||
)
|
||||
page.set_body (s)
|
||||
res.send (page)
|
||||
end
|
||||
|
||||
feature -- Helper
|
||||
|
||||
append_html_header (req: WSF_REQUEST; s: STRING)
|
||||
-- Append header paragraph to `s'.
|
||||
do
|
||||
s.append ("<p>The current page is " + html_encoder.encoded_string (req.path_info) + "</p>")
|
||||
end
|
||||
|
||||
append_html_menu (a_username: detachable READABLE_STRING_32; req: WSF_REQUEST; s: STRING)
|
||||
-- Append menu to `s'.
|
||||
-- when an user is authenticated, `a_username' is attached.
|
||||
do
|
||||
if a_username /= Void then
|
||||
s.append ("<li><a href=%""+ req.absolute_script_url ("") +"%">Your account</a> (displayed only is user is authenticated!)</li>")
|
||||
end
|
||||
s.append ("<li><a href=%""+ req.absolute_script_url ("") +"%">home</a></li>")
|
||||
s.append ("<li><a href=%""+ req.script_url ("/public/area") +"%">public area</a></li>")
|
||||
s.append ("<li><a href=%""+ req.script_url ("/protected/area") +"%">protected area</a></li>")
|
||||
end
|
||||
|
||||
append_html_login (req: WSF_REQUEST; s: STRING)
|
||||
-- Append login link to `s'.
|
||||
do
|
||||
s.append ("<li><a href=%""+ req.script_url ("/login") +"%">sign in</a></li>")
|
||||
end
|
||||
|
||||
append_html_logout (a_username: detachable READABLE_STRING_32; req: WSF_REQUEST; s: STRING)
|
||||
-- Append logout link to `s'.
|
||||
local
|
||||
l_logout_url: STRING
|
||||
do
|
||||
l_logout_url := req.absolute_script_url ("/login")
|
||||
l_logout_url.replace_substring_all ("://", "://_@") -- Hack to clear http authorization, i.e connect with bad username "_".
|
||||
s.append ("<li><a href=%""+ l_logout_url +"%">logout</a></li>")
|
||||
end
|
||||
|
||||
append_html_footer (req: WSF_REQUEST; s: STRING)
|
||||
-- Append html footer to `s'.
|
||||
local
|
||||
hauth: HTTP_AUTHORIZATION
|
||||
do
|
||||
s.append ("<hr/>")
|
||||
if attached req.http_authorization as l_http_authorization then
|
||||
s.append ("Has <em>Authorization:</em> header: ")
|
||||
create hauth.make (req.http_authorization)
|
||||
if attached hauth.login as l_login then
|
||||
s.append (" login=<strong>" + html_encoder.encoded_string (l_login)+ "</strong>")
|
||||
end
|
||||
if attached hauth.password as l_password then
|
||||
s.append (" password=<strong>" + html_encoder.encoded_string (l_password)+ "</strong>")
|
||||
end
|
||||
s.append ("<br/>")
|
||||
end
|
||||
if attached req.raw_header_data as l_header then
|
||||
-- Append the raw header data for information
|
||||
s.append ("Raw header data:")
|
||||
s.append ("<pre>")
|
||||
s.append (l_header)
|
||||
s.append ("</pre>")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
note
|
||||
description : "simple application root class"
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
class
|
||||
DEMO_BASIC_EXECUTION
|
||||
|
||||
inherit
|
||||
WSF_EXECUTION
|
||||
|
||||
SHARED_HTML_ENCODER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Credentials
|
||||
|
||||
is_known_login (a_login: READABLE_STRING_GENERAL): BOOLEAN
|
||||
-- Is `a_login' a known username?
|
||||
do
|
||||
Result := valid_credentials.has (a_login)
|
||||
end
|
||||
|
||||
is_valid_credential (a_login: READABLE_STRING_GENERAL; a_password: detachable READABLE_STRING_GENERAL): BOOLEAN
|
||||
-- Is `a_login:a_password' a valid credential?
|
||||
do
|
||||
if
|
||||
a_password /= Void and
|
||||
attached valid_credentials.item (a_login) as l_passwd
|
||||
then
|
||||
Result := a_password.is_case_insensitive_equal (l_passwd)
|
||||
end
|
||||
ensure
|
||||
Result implies is_known_login (a_login)
|
||||
end
|
||||
|
||||
demo_credential: STRING_32
|
||||
-- First valid known credential display for demo in dialog.
|
||||
do
|
||||
valid_credentials.start
|
||||
create Result.make_from_string_general (valid_credentials.key_for_iteration)
|
||||
Result.append_character (':')
|
||||
Result.append (valid_credentials.item_for_iteration)
|
||||
end
|
||||
|
||||
valid_credentials: STRING_TABLE [READABLE_STRING_32]
|
||||
-- Password indexed by login.
|
||||
once
|
||||
create Result.make_caseless (3)
|
||||
Result.force ("world", "eiffel")
|
||||
Result.force ("bar", "foo")
|
||||
Result.force ("password", "user")
|
||||
ensure
|
||||
not Result.is_empty
|
||||
end
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
execute
|
||||
-- <Precursor>
|
||||
local
|
||||
auth: HTTP_AUTHORIZATION
|
||||
l_authenticated_username: detachable READABLE_STRING_32
|
||||
l_invalid_credential: BOOLEAN
|
||||
req: WSF_REQUEST
|
||||
res: WSF_RESPONSE
|
||||
do
|
||||
req := request
|
||||
res := response
|
||||
if attached req.http_authorization as l_http_auth then
|
||||
create auth.make (l_http_auth)
|
||||
if attached auth.login as l_login and then is_valid_credential (l_login, auth.password) then
|
||||
l_authenticated_username := auth.login
|
||||
else
|
||||
l_invalid_credential := True
|
||||
end
|
||||
end
|
||||
if l_invalid_credential then
|
||||
handle_unauthorized ("ERROR: Invalid credential", req, res)
|
||||
else
|
||||
if l_authenticated_username /= Void then
|
||||
handle_authenticated (l_authenticated_username, req, res)
|
||||
elseif req.path_info.same_string_general ("/login") then
|
||||
handle_unauthorized ("Please provide credential ...", req, res)
|
||||
elseif req.path_info.starts_with_general ("/protected/") then
|
||||
-- any "/protected/*" url
|
||||
handle_unauthorized ("Protected area, please sign in before", req, res)
|
||||
else
|
||||
handle_anonymous (req, res)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
handle_authenticated (a_username: READABLE_STRING_32; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- User `a_username' is authenticated, execute request `req' with response `res'.
|
||||
require
|
||||
valid_username: not a_username.is_empty
|
||||
known_username: is_known_login (a_username)
|
||||
local
|
||||
s: STRING
|
||||
page: WSF_HTML_PAGE_RESPONSE
|
||||
do
|
||||
create s.make_empty
|
||||
|
||||
append_html_header (req, s)
|
||||
|
||||
s.append ("<p>The authenticated user is <strong>")
|
||||
s.append (html_encoder.general_encoded_string (a_username))
|
||||
s.append ("</strong> ...</p>")
|
||||
|
||||
append_html_menu (a_username, req, s)
|
||||
append_html_logout (a_username, req, s)
|
||||
append_html_footer (req, s)
|
||||
|
||||
create page.make
|
||||
page.set_body (s)
|
||||
res.send (page)
|
||||
end
|
||||
|
||||
handle_anonymous (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- No user is authenticated, execute request `req' with response `res'.
|
||||
local
|
||||
s: STRING
|
||||
page: WSF_HTML_PAGE_RESPONSE
|
||||
do
|
||||
create s.make_empty
|
||||
append_html_header (req, s)
|
||||
|
||||
s.append ("Anonymous visitor ...<br/>")
|
||||
|
||||
append_html_login (req, s)
|
||||
append_html_menu (Void, req, s)
|
||||
append_html_footer (req, s)
|
||||
|
||||
create page.make
|
||||
page.set_body (s)
|
||||
res.send (page)
|
||||
end
|
||||
|
||||
handle_unauthorized (a_description: STRING; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Restricted page, authenticated user is required.
|
||||
-- Send `a_description' as part of the response.
|
||||
local
|
||||
s: STRING
|
||||
page: WSF_HTML_PAGE_RESPONSE
|
||||
do
|
||||
create s.make_from_string (a_description)
|
||||
|
||||
append_html_login (req, s)
|
||||
append_html_menu (Void, req, s)
|
||||
append_html_footer (req, s)
|
||||
|
||||
create page.make
|
||||
page.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
|
||||
page.header.put_header_key_value ({HTTP_HEADER_NAMES}.header_www_authenticate,
|
||||
"Basic realm=%"Please enter a valid username and password (demo [" + html_encoder.encoded_string (demo_credential) + "])%""
|
||||
--| warning: for this example: a valid credential is provided in the message, of course that for real application.
|
||||
)
|
||||
page.set_body (s)
|
||||
res.send (page)
|
||||
end
|
||||
|
||||
feature -- Helper
|
||||
|
||||
append_html_header (req: WSF_REQUEST; s: STRING)
|
||||
-- Append header paragraph to `s'.
|
||||
do
|
||||
s.append ("<p>The current page is " + html_encoder.encoded_string (req.path_info) + "</p>")
|
||||
end
|
||||
|
||||
append_html_menu (a_username: detachable READABLE_STRING_32; req: WSF_REQUEST; s: STRING)
|
||||
-- Append menu to `s'.
|
||||
-- when an user is authenticated, `a_username' is attached.
|
||||
do
|
||||
if a_username /= Void then
|
||||
s.append ("<li><a href=%""+ req.absolute_script_url ("") +"%">Your account</a> (displayed only is user is authenticated!)</li>")
|
||||
end
|
||||
s.append ("<li><a href=%""+ req.absolute_script_url ("") +"%">home</a></li>")
|
||||
s.append ("<li><a href=%""+ req.script_url ("/public/area") +"%">public area</a></li>")
|
||||
s.append ("<li><a href=%""+ req.script_url ("/protected/area") +"%">protected area</a></li>")
|
||||
end
|
||||
|
||||
append_html_login (req: WSF_REQUEST; s: STRING)
|
||||
-- Append login link to `s'.
|
||||
do
|
||||
s.append ("<li><a href=%""+ req.script_url ("/login") +"%">sign in</a></li>")
|
||||
end
|
||||
|
||||
append_html_logout (a_username: detachable READABLE_STRING_32; req: WSF_REQUEST; s: STRING)
|
||||
-- Append logout link to `s'.
|
||||
local
|
||||
l_logout_url: STRING
|
||||
do
|
||||
l_logout_url := req.absolute_script_url ("/login")
|
||||
l_logout_url.replace_substring_all ("://", "://_@") -- Hack to clear http authorization, i.e connect with bad username "_".
|
||||
s.append ("<li><a href=%""+ l_logout_url +"%">logout</a></li>")
|
||||
end
|
||||
|
||||
append_html_footer (req: WSF_REQUEST; s: STRING)
|
||||
-- Append html footer to `s'.
|
||||
local
|
||||
hauth: HTTP_AUTHORIZATION
|
||||
do
|
||||
s.append ("<hr/>")
|
||||
if attached req.http_authorization as l_http_authorization then
|
||||
s.append ("Has <em>Authorization:</em> header: ")
|
||||
create hauth.make (req.http_authorization)
|
||||
if attached hauth.login as l_login then
|
||||
s.append (" login=<strong>" + html_encoder.encoded_string (l_login)+ "</strong>")
|
||||
end
|
||||
if attached hauth.password as l_password then
|
||||
s.append (" password=<strong>" + html_encoder.encoded_string (l_password)+ "</strong>")
|
||||
end
|
||||
s.append ("<br/>")
|
||||
end
|
||||
if attached req.raw_header_data as l_header then
|
||||
-- Append the raw header data for information
|
||||
s.append ("Raw header data:")
|
||||
s.append ("<pre>")
|
||||
s.append (l_header)
|
||||
s.append ("</pre>")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -26,23 +26,6 @@ feature {NONE} -- Implementation
|
||||
create connector.make_with_base (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 [G]
|
||||
|
||||
@@ -17,16 +17,27 @@ feature {NONE} -- Initialization
|
||||
make
|
||||
-- Initialize `Current'.
|
||||
local
|
||||
conn: WGI_HTTPD_CONNECTOR [APP_WSF_EXECUTION]
|
||||
conn: WGI_STANDALONE_CONNECTOR [APP_WSF_EXECUTION]
|
||||
do
|
||||
print ("Starting httpd server ...%N")
|
||||
|
||||
create conn.make
|
||||
conn.on_launched_actions.extend (agent on_launched)
|
||||
conn.set_port_number (9090)
|
||||
conn.set_max_concurrent_connections (100)
|
||||
conn.launch
|
||||
end
|
||||
|
||||
on_launched (conn: WGI_STANDALONE_CONNECTOR [WGI_EXECUTION])
|
||||
do
|
||||
print ("Server listening on port " + conn.port.out + "%N")
|
||||
end
|
||||
|
||||
on_stopped (conn: WGI_STANDALONE_CONNECTOR [WGI_EXECUTION])
|
||||
do
|
||||
print ("Server terminated%N")
|
||||
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)"
|
||||
@@ -19,14 +19,19 @@ feature {NONE} -- Initialization
|
||||
|
||||
reset
|
||||
do
|
||||
has_error := False
|
||||
version := Void
|
||||
remote_info := Void
|
||||
reset_request
|
||||
|
||||
has_error := False
|
||||
if attached internal_client_socket as l_sock then
|
||||
l_sock.cleanup
|
||||
end
|
||||
internal_client_socket := Void
|
||||
end
|
||||
|
||||
reset_request
|
||||
do
|
||||
version := Void
|
||||
remote_info := Void
|
||||
|
||||
-- FIXME: optimize to just wipe_out if needed
|
||||
create method.make_empty
|
||||
@@ -34,6 +39,7 @@ feature {NONE} -- Initialization
|
||||
create request_header.make_empty
|
||||
create request_header_map.make (10)
|
||||
|
||||
keep_alive_enabled := False
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
@@ -79,6 +85,24 @@ feature -- Access
|
||||
remote_info: detachable TUPLE [addr: STRING; hostname: STRING; port: INTEGER]
|
||||
-- Information related to remote client
|
||||
|
||||
keep_alive_enabled: BOOLEAN
|
||||
-- Inside a persistent connection?
|
||||
|
||||
is_http_version_1_0: BOOLEAN
|
||||
do
|
||||
Result := not attached version as v or else v.same_string ("HTTP/1.0")
|
||||
end
|
||||
|
||||
is_http_version_1_1: BOOLEAN
|
||||
do
|
||||
Result := not attached version as v or else v.same_string ("HTTP/1.1")
|
||||
end
|
||||
|
||||
is_http_version_2: BOOLEAN
|
||||
do
|
||||
Result := not attached version as v or else v.same_string ("HTTP/2.0")
|
||||
end
|
||||
|
||||
feature -- Settings
|
||||
|
||||
is_verbose: BOOLEAN
|
||||
@@ -93,6 +117,7 @@ feature -- Change
|
||||
set_is_verbose (b: BOOLEAN)
|
||||
do
|
||||
is_verbose := b
|
||||
print ("set_is_verbose " + b.out + "%N")
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
@@ -118,6 +143,33 @@ feature -- Execution
|
||||
end
|
||||
|
||||
execute
|
||||
require
|
||||
is_connected: is_connected
|
||||
local
|
||||
l_socket: like client_socket
|
||||
l_exit: BOOLEAN
|
||||
n: INTEGER
|
||||
do
|
||||
l_socket := client_socket
|
||||
check
|
||||
socket_attached: l_socket /= Void
|
||||
socket_valid: l_socket.is_open_read and then l_socket.is_open_write
|
||||
end
|
||||
from
|
||||
-- Process persistent connection as long the socket is not closed.
|
||||
n := 0
|
||||
until
|
||||
l_exit
|
||||
loop
|
||||
n := n + 1
|
||||
-- FIXME: it seems to be called one more time, mostly to see this is done.
|
||||
execute_request
|
||||
l_exit := has_error or l_socket.is_closed or not l_socket.is_open_read or not keep_alive_enabled
|
||||
reset_request
|
||||
end
|
||||
end
|
||||
|
||||
execute_request
|
||||
require
|
||||
is_connected: is_connected
|
||||
local
|
||||
@@ -132,14 +184,15 @@ feature -- Execution
|
||||
end
|
||||
if l_socket.is_closed then
|
||||
debug ("dbglog")
|
||||
dbglog (generator + ".execute {socket is Closed!}")
|
||||
dbglog (generator + ".execute_request {socket is Closed!}")
|
||||
end
|
||||
else
|
||||
debug ("dbglog")
|
||||
dbglog (generator + ".execute socket=" + l_socket.descriptor.out + " ENTER")
|
||||
dbglog (generator + ".execute_request socket=" + l_socket.descriptor.out + " ENTER")
|
||||
end
|
||||
from until l_continue loop
|
||||
if l_socket.ready_for_reading then
|
||||
if l_socket.try_ready_for_reading then
|
||||
-- ready_for_reading then
|
||||
l_continue := True
|
||||
create l_remote_info
|
||||
if attached l_socket.peer_address as l_addr then
|
||||
@@ -150,7 +203,11 @@ feature -- Execution
|
||||
end
|
||||
analyze_request_message (l_socket)
|
||||
else
|
||||
log (generator + ".execute socket=" + l_socket.descriptor.out + "} WAITING")
|
||||
has_error := True
|
||||
l_continue := True
|
||||
debug ("dbglog")
|
||||
dbglog (generator + ".execute_request socket=" + l_socket.descriptor.out + "} WAITING")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -164,7 +221,7 @@ feature -- Execution
|
||||
process_request (l_socket)
|
||||
end
|
||||
debug ("dbglog")
|
||||
dbglog (generator + ".execute {" + l_socket.descriptor.out + "} LEAVE")
|
||||
dbglog (generator + ".execute_request {" + l_socket.descriptor.out + "} LEAVE")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -243,6 +300,22 @@ feature -- Parsing
|
||||
line := next_line (a_socket)
|
||||
end
|
||||
end
|
||||
if not {HTTPD_SERVER}.is_persistent_connection_supported then
|
||||
keep_alive_enabled := False
|
||||
elseif is_http_version_1_0 then
|
||||
keep_alive_enabled := attached request_header_map.item ("Connection") as l_connection and then
|
||||
l_connection.is_case_insensitive_equal_general ("keep-alive")
|
||||
else
|
||||
-- By default HTTP:1/1 support persistent connection.
|
||||
if
|
||||
attached request_header_map.item ("Connection") as l_connection and then
|
||||
l_connection.is_case_insensitive_equal_general ("close")
|
||||
then
|
||||
keep_alive_enabled := False
|
||||
else
|
||||
keep_alive_enabled := True
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -251,7 +324,7 @@ feature -- Parsing
|
||||
require
|
||||
valid_line: line /= Void and then not line.is_empty
|
||||
local
|
||||
pos, next_pos: INTEGER
|
||||
n, pos, next_pos: INTEGER
|
||||
do
|
||||
if is_verbose then
|
||||
log ("%N## Parse HTTP request line ##")
|
||||
@@ -261,7 +334,11 @@ feature -- Parsing
|
||||
method := line.substring (1, pos - 1)
|
||||
next_pos := line.index_of (' ', pos + 1)
|
||||
uri := line.substring (pos + 1, next_pos - 1)
|
||||
version := line.substring (next_pos + 1, line.count)
|
||||
n := line.count
|
||||
if line[n] = '%R' then
|
||||
n := n - 1
|
||||
end
|
||||
version := line.substring (next_pos + 1, n)
|
||||
has_error := method.is_empty
|
||||
end
|
||||
|
||||
@@ -269,11 +346,18 @@ feature -- Parsing
|
||||
-- Next line fetched from `a_socket' is available.
|
||||
require
|
||||
is_readable: a_socket.is_open_read
|
||||
local
|
||||
retried: BOOLEAN
|
||||
do
|
||||
if a_socket.socket_ok then
|
||||
if retried then
|
||||
Result := Void
|
||||
elseif a_socket.socket_ok then
|
||||
a_socket.read_line_thread_aware
|
||||
Result := a_socket.last_string
|
||||
end
|
||||
rescue
|
||||
retried := True
|
||||
retry
|
||||
end
|
||||
|
||||
feature -- Output
|
||||
@@ -58,6 +58,19 @@ feature -- Access
|
||||
|
||||
factory: separate HTTPD_REQUEST_HANDLER_FACTORY
|
||||
|
||||
is_persistent_connection_supported: BOOLEAN = False
|
||||
-- Is persistent connection supported?
|
||||
--| For now, disabled during dev.
|
||||
|
||||
feature -- Callbacks
|
||||
|
||||
observer: detachable separate HTTPD_SERVER_OBSERVER
|
||||
|
||||
set_observer (obs: like observer)
|
||||
do
|
||||
observer := obs
|
||||
end
|
||||
|
||||
feature -- Access: listening
|
||||
|
||||
port: INTEGER
|
||||
@@ -91,22 +104,10 @@ feature -- Execution
|
||||
end
|
||||
is_shutdown_requested := False
|
||||
listen
|
||||
is_terminated := True
|
||||
on_terminated
|
||||
end
|
||||
|
||||
on_terminated
|
||||
require
|
||||
is_terminated
|
||||
do
|
||||
if is_terminated then
|
||||
log ("%N%NTerminating Web Application Server (port="+ port.out +"):%N")
|
||||
end
|
||||
if attached output as o then
|
||||
o.flush
|
||||
o.close
|
||||
end
|
||||
end
|
||||
|
||||
shutdown_server
|
||||
do
|
||||
debug ("dbglog")
|
||||
@@ -251,8 +252,12 @@ feature -- Event
|
||||
require
|
||||
not_launched: not is_launched
|
||||
do
|
||||
-- print ("port=" + a_port.out + "%N")
|
||||
is_launched := True
|
||||
port := a_port
|
||||
if attached observer as obs then
|
||||
observer_on_launched (obs, a_port)
|
||||
end
|
||||
ensure
|
||||
is_launched: is_launched
|
||||
end
|
||||
@@ -262,10 +267,43 @@ feature -- Event
|
||||
require
|
||||
is_launched: is_launched
|
||||
do
|
||||
is_launched := False
|
||||
is_terminated := True
|
||||
ensure
|
||||
stopped: not is_launched
|
||||
if attached observer as obs then
|
||||
observer_on_stopped (obs)
|
||||
end
|
||||
end
|
||||
|
||||
on_terminated
|
||||
-- Server terminated
|
||||
require
|
||||
is_terminated
|
||||
do
|
||||
if is_terminated and is_verbose then
|
||||
log ("%N%NTerminating Web Application Server (port="+ port.out +"):%N")
|
||||
end
|
||||
if attached output as o then
|
||||
o.flush
|
||||
o.close
|
||||
end
|
||||
if attached observer as obs then
|
||||
observer_on_terminated (obs)
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Separate event
|
||||
|
||||
observer_on_launched (obs: attached like observer; a_port: INTEGER)
|
||||
do
|
||||
obs.on_launched (a_port)
|
||||
end
|
||||
|
||||
observer_on_stopped (obs: attached like observer)
|
||||
do
|
||||
obs.on_stopped
|
||||
end
|
||||
|
||||
observer_on_terminated (obs: attached like observer)
|
||||
do
|
||||
obs.on_terminated
|
||||
end
|
||||
|
||||
feature -- Configuration change
|
||||
@@ -0,0 +1,24 @@
|
||||
note
|
||||
description: "Summary description for {HTTPD_SERVER_OBSERVER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
HTTPD_SERVER_OBSERVER
|
||||
|
||||
feature -- Event
|
||||
|
||||
on_launched (a_port: INTEGER)
|
||||
deferred
|
||||
end
|
||||
|
||||
on_stopped
|
||||
deferred
|
||||
end
|
||||
|
||||
on_terminated
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
@@ -26,9 +26,14 @@ feature {NONE} -- Initialization
|
||||
do
|
||||
make
|
||||
connector := conn
|
||||
-- if conn /= Void then
|
||||
-- set_is_verbose (is_connector_verbose (conn))
|
||||
-- end
|
||||
end
|
||||
|
||||
connector: detachable separate WGI_HTTPD_CONNECTOR [G]
|
||||
feature -- Access
|
||||
|
||||
connector: detachable separate WGI_STANDALONE_CONNECTOR [G]
|
||||
|
||||
base: detachable IMMUTABLE_STRING_8
|
||||
do
|
||||
@@ -39,11 +44,18 @@ feature {NONE} -- Initialization
|
||||
end
|
||||
end
|
||||
|
||||
connector_base (conn: separate WGI_HTTPD_CONNECTOR [G]): detachable separate READABLE_STRING_8
|
||||
feature -- SCOOP helpers
|
||||
|
||||
connector_base (conn: separate WGI_STANDALONE_CONNECTOR [G]): detachable separate READABLE_STRING_8
|
||||
do
|
||||
Result := conn.base
|
||||
end
|
||||
|
||||
is_connector_verbose (conn: separate WGI_STANDALONE_CONNECTOR [G]): BOOLEAN
|
||||
do
|
||||
Result := conn.is_verbose
|
||||
end
|
||||
|
||||
feature -- Request processing
|
||||
|
||||
process_request (a_socket: HTTPD_STREAM_SOCKET)
|
||||
@@ -53,14 +65,14 @@ feature -- Request processing
|
||||
l_output: WGI_OUTPUT_STREAM
|
||||
l_error: WGI_ERROR_STREAM
|
||||
req: WGI_REQUEST_FROM_TABLE
|
||||
res: detachable WGI_HTTPD_RESPONSE_STREAM
|
||||
res: detachable WGI_STANDALONE_RESPONSE_STREAM
|
||||
exec: detachable WGI_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 {WGI_STANDALONE_INPUT_STREAM} l_input.make (a_socket)
|
||||
create {WGI_STANDALONE_OUTPUT_STREAM} l_output.make (a_socket)
|
||||
create {WGI_STANDALONE_ERROR_STREAM} l_error.make_stderr (a_socket.descriptor.out)
|
||||
|
||||
create req.make (httpd_environment (a_socket), l_input, connector)
|
||||
create res.make (l_output, l_error)
|
||||
@@ -12,7 +12,7 @@ inherit
|
||||
|
||||
feature -- Access
|
||||
|
||||
connector: detachable separate WGI_HTTPD_CONNECTOR [G]
|
||||
connector: detachable separate WGI_STANDALONE_CONNECTOR [G]
|
||||
|
||||
feature -- Element change
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
note
|
||||
description: "Summary description for {WGI_HTTPD_CONNECTOR}."
|
||||
description: "Summary description for {WGI_STANDALONE_CONNECTOR}."
|
||||
author: ""
|
||||
todo: "[
|
||||
Check if server and configuration has to be 'separate' ?
|
||||
@@ -11,7 +11,7 @@ note
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WGI_HTTPD_CONNECTOR [G -> WGI_EXECUTION create make end]
|
||||
WGI_STANDALONE_CONNECTOR [G -> WGI_EXECUTION create make end]
|
||||
|
||||
inherit
|
||||
WGI_CONNECTOR
|
||||
@@ -28,14 +28,15 @@ feature {NONE} -- Initialization
|
||||
do
|
||||
-- Callbacks
|
||||
create on_launched_actions
|
||||
create on_stopped_actions
|
||||
|
||||
-- Server
|
||||
create fac
|
||||
create server.make (fac)
|
||||
create observer
|
||||
configuration := server_configuration (server)
|
||||
|
||||
controller := server_controller (server)
|
||||
set_factory_connector (Current, fac)
|
||||
initialize_server (server)
|
||||
end
|
||||
|
||||
make_with_base (a_base: like base)
|
||||
@@ -46,11 +47,23 @@ feature {NONE} -- Initialization
|
||||
set_base (a_base)
|
||||
end
|
||||
|
||||
set_factory_connector (conn: detachable separate WGI_HTTPD_CONNECTOR [G]; fac: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G])
|
||||
initialize_server (a_server: like server)
|
||||
do
|
||||
a_server.set_observer (observer)
|
||||
end
|
||||
|
||||
feature {NONE} -- Separate helper
|
||||
|
||||
set_factory_connector (conn: detachable separate WGI_STANDALONE_CONNECTOR [G]; fac: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G])
|
||||
do
|
||||
fac.set_connector (conn)
|
||||
end
|
||||
|
||||
server_configuration (a_server: like server): like configuration
|
||||
do
|
||||
Result := a_server.configuration
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING_8 = "httpd"
|
||||
@@ -63,12 +76,11 @@ feature -- Access
|
||||
|
||||
server: separate HTTPD_SERVER
|
||||
|
||||
configuration: separate HTTPD_CONFIGURATION
|
||||
controller: separate HTTPD_CONTROLLER
|
||||
|
||||
server_configuration (a_server: like server): like configuration
|
||||
do
|
||||
Result := a_server.configuration
|
||||
end
|
||||
observer: separate WGI_STANDALONE_SERVER_OBSERVER
|
||||
|
||||
configuration: separate HTTPD_CONFIGURATION
|
||||
|
||||
feature -- Access
|
||||
|
||||
@@ -84,15 +96,15 @@ feature -- Status report
|
||||
-- Listening port.
|
||||
--| 0: not launched
|
||||
|
||||
is_verbose: BOOLEAN
|
||||
-- Is verbose?
|
||||
|
||||
feature -- Callbacks
|
||||
|
||||
on_launched_actions: ACTION_SEQUENCE [TUPLE [WGI_CONNECTOR]]
|
||||
on_launched_actions: ACTION_SEQUENCE [TUPLE [WGI_STANDALONE_CONNECTOR [WGI_EXECUTION]]]
|
||||
-- Actions triggered when launched
|
||||
|
||||
on_stopped_actions: ACTION_SEQUENCE [TUPLE [WGI_CONNECTOR]]
|
||||
-- Actions triggered when stopped
|
||||
|
||||
feature -- Element change
|
||||
feature -- Event
|
||||
|
||||
on_launched (a_port: INTEGER)
|
||||
-- Server launched
|
||||
@@ -102,14 +114,6 @@ feature -- Element change
|
||||
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)
|
||||
@@ -154,6 +158,7 @@ feature {NONE} -- Implementation
|
||||
|
||||
set_is_verbose_on_configuration (b: BOOLEAN; cfg: like configuration)
|
||||
do
|
||||
is_verbose := b
|
||||
cfg.set_is_verbose (b)
|
||||
end
|
||||
|
||||
@@ -164,6 +169,29 @@ feature -- Server
|
||||
launched := False
|
||||
port := 0
|
||||
launch_server (server)
|
||||
on_server_started (observer)
|
||||
end
|
||||
|
||||
shutdown_server
|
||||
do
|
||||
if launched then
|
||||
-- FIXME jfiat [2015/03/27] : prevent multiple calls (otherwise it hangs)
|
||||
separate_shutdown_server_on_controller (controller)
|
||||
end
|
||||
end
|
||||
|
||||
server_controller (a_server: like server): separate HTTPD_CONTROLLER
|
||||
do
|
||||
Result := a_server.controller
|
||||
end
|
||||
|
||||
on_server_started (obs: like observer)
|
||||
require
|
||||
obs.started
|
||||
do
|
||||
if obs.port > 0 then
|
||||
on_launched (obs.port)
|
||||
end
|
||||
end
|
||||
|
||||
configure_server (a_configuration: like configuration)
|
||||
@@ -181,6 +209,19 @@ feature -- Server
|
||||
a_server.launch
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
separate_server_terminated (a_server: like server): BOOLEAN
|
||||
do
|
||||
Result := a_server.is_terminated
|
||||
end
|
||||
|
||||
separate_shutdown_server_on_controller (a_controller: separate HTTPD_CONTROLLER)
|
||||
do
|
||||
a_controller.shutdown
|
||||
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)"
|
||||
@@ -1,12 +1,12 @@
|
||||
note
|
||||
description: "Summary description for WGI_HTTPD_ERROR_STREAM."
|
||||
description: "Summary description for WGI_STANDALONE_ERROR_STREAM."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WGI_HTTPD_ERROR_STREAM
|
||||
WGI_STANDALONE_ERROR_STREAM
|
||||
|
||||
inherit
|
||||
WGI_ERROR_STREAM
|
||||
@@ -58,7 +58,7 @@ feature -- Error
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
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
|
||||
@@ -1,12 +1,12 @@
|
||||
note
|
||||
description: "Summary description for {WGI_HTTPD_INPUT_STREAM}."
|
||||
description: "Summary description for {WGI_STANDALONE_INPUT_STREAM}."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WGI_HTTPD_INPUT_STREAM
|
||||
WGI_STANDALONE_INPUT_STREAM
|
||||
|
||||
inherit
|
||||
WGI_INPUT_STREAM
|
||||
@@ -22,7 +22,7 @@ feature {NONE} -- Initialization
|
||||
set_source (a_source)
|
||||
end
|
||||
|
||||
feature {WGI_HTTPD_CONNECTOR, WGI_SERVICE} -- Nino
|
||||
feature {WGI_STANDALONE_CONNECTOR, WGI_SERVICE} -- Nino
|
||||
|
||||
set_source (i: like source)
|
||||
do
|
||||
@@ -1,12 +1,12 @@
|
||||
note
|
||||
description: "Summary description for {WGI_HTTPD_OUTPUT_STREAM}."
|
||||
description: "Summary description for {WGI_STANDALONE_OUTPUT_STREAM}."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WGI_HTTPD_OUTPUT_STREAM
|
||||
WGI_STANDALONE_OUTPUT_STREAM
|
||||
|
||||
inherit
|
||||
WGI_OUTPUT_STREAM
|
||||
@@ -26,7 +26,7 @@ feature {NONE} -- Initialization
|
||||
set_target (a_target)
|
||||
end
|
||||
|
||||
feature {WGI_HTTPD_CONNECTOR, WGI_SERVICE} -- Nino
|
||||
feature {WGI_STANDALONE_CONNECTOR, WGI_SERVICE} -- Nino
|
||||
|
||||
set_target (o: like target)
|
||||
do
|
||||
@@ -7,7 +7,7 @@ note
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WGI_HTTPD_RESPONSE_STREAM
|
||||
WGI_STANDALONE_RESPONSE_STREAM
|
||||
|
||||
inherit
|
||||
WGI_RESPONSE_STREAM
|
||||
@@ -27,9 +27,11 @@ feature -- Header output operation
|
||||
o := output
|
||||
o.put_string (a_text)
|
||||
|
||||
-- Nino does not support persistent connection for now
|
||||
o.put_string ("Connection: close")
|
||||
o.put_crlf
|
||||
if not {HTTPD_SERVER}.is_persistent_connection_supported then
|
||||
-- standalone does not support persistent connection for now
|
||||
o.put_string ("Connection: close")
|
||||
o.put_crlf
|
||||
end
|
||||
|
||||
-- end of headers
|
||||
o.put_crlf
|
||||
@@ -38,7 +40,7 @@ feature -- Header output operation
|
||||
end
|
||||
|
||||
;note
|
||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
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
|
||||
@@ -1,28 +1,45 @@
|
||||
note
|
||||
description: "Summary description for {APP_WSF_HTTPD_REQUEST_HANDLER}."
|
||||
description: "Summary description for {WGI_STANDALONE_SERVER_OBSERVER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
APP_WSF_HTTPD_REQUEST_HANDLER
|
||||
WGI_STANDALONE_SERVER_OBSERVER
|
||||
|
||||
inherit
|
||||
WSF_HTTPD_REQUEST_HANDLER
|
||||
HTTPD_SERVER_OBSERVER
|
||||
|
||||
create
|
||||
make
|
||||
feature -- Access
|
||||
|
||||
feature -- Execute
|
||||
started: BOOLEAN
|
||||
|
||||
do_more (req: WGI_REQUEST; res: WGI_RESPONSE)
|
||||
local
|
||||
exec: WSF_EXECUTION
|
||||
stopped: BOOLEAN
|
||||
|
||||
terminated: BOOLEAN
|
||||
|
||||
port: INTEGER
|
||||
|
||||
feature -- Event
|
||||
|
||||
on_launched (a_port: INTEGER)
|
||||
do
|
||||
create {APP_WSF_EXECUTION} exec.make (req, res)
|
||||
exec.execute
|
||||
started := True
|
||||
port := a_port
|
||||
end
|
||||
|
||||
on_stopped
|
||||
do
|
||||
stopped := True
|
||||
end
|
||||
|
||||
on_terminated
|
||||
do
|
||||
port := 0
|
||||
terminated := True
|
||||
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)"
|
||||
@@ -1,13 +1,13 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="connector_httpd" uuid="49C99A6E-CCC1-4015-81F6-D7C43B592034" library_target="connector_httpd">
|
||||
<target name="connector_httpd">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="connector_standalone" uuid="49C99A6E-CCC1-4015-81F6-D7C43B592034" library_target="connector_standalone">
|
||||
<target name="connector_standalone">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option debug="false" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<option debug="true" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<debug name="dbglog" enabled="true"/>
|
||||
<assertions precondition="true"/>
|
||||
</option>
|
||||
@@ -16,16 +16,14 @@
|
||||
<library name="encoder" location="..\..\..\..\text\encoder\encoder-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/>
|
||||
<library name="http" location="..\..\..\..\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="httpd" location="src\httpd\httpd-safe.ecf"/>
|
||||
<cluster name="src" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/httpd$</exclude>
|
||||
</file_rule>
|
||||
<library name="httpd" location="src\httpd\httpd-safe.ecf" readonly="false"/>
|
||||
<cluster name="src" location=".\src\">
|
||||
<cluster name="implementation" location="$|implementation\" hidden="true"/>
|
||||
</cluster>
|
||||
</target>
|
||||
<target name="dev" extends="connector_httpd">
|
||||
<target name="dev_scoop" extends="connector_standalone">
|
||||
<root class="HTTPD_CONNECTOR_DEV" feature="make"/>
|
||||
<option debug="false">
|
||||
<option debug="true">
|
||||
<debug name="dbglog" enabled="true"/>
|
||||
<assertions precondition="true" postcondition="true" check="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
@@ -33,10 +31,10 @@
|
||||
<library name="wsf" location="..\..\..\wsf\wsf-safe.ecf" readonly="false"/>
|
||||
<cluster name="dev" location="dev\" recursive="true"/>
|
||||
</target>
|
||||
<target name="dev_mt" extends="dev">
|
||||
<target name="dev_mt" extends="dev_scoop">
|
||||
<setting name="concurrency" value="thread"/>
|
||||
</target>
|
||||
<target name="dev_none" extends="dev">
|
||||
<target name="dev_none" extends="dev_scoop">
|
||||
<setting name="concurrency" value="none"/>
|
||||
</target>
|
||||
</system>
|
||||
23
library/server/ewsgi/connectors/standalone/standalone.ecf
Normal file
23
library/server/ewsgi/connectors/standalone/standalone.ecf
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="connector_standalone" uuid="49C99A6E-CCC1-4015-81F6-D7C43B592034" library_target="connector_standalone">
|
||||
<target name="connector_standalone">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" void_safety="none" syntax="transitional">
|
||||
<assertions precondition="true"/>
|
||||
</option>
|
||||
<setting name="concurrency" value="scoop"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="encoder" location="..\..\..\..\text\encoder\encoder.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi.ecf" readonly="false"/>
|
||||
<library name="http" location="..\..\..\..\network\protocol\http\http.ecf"/>
|
||||
<library name="httpd" location="src\httpd\httpd.ecf" readonly="false"/>
|
||||
<cluster name="src" location=".\src\">
|
||||
<cluster name="implementation" location="$|implementation\" hidden="true"/>
|
||||
</cluster>
|
||||
</target>
|
||||
</system>
|
||||
@@ -18,20 +18,13 @@ feature {NONE} -- Initialization
|
||||
make
|
||||
do
|
||||
print ("Example: start a Nino web server on port " + port_number.out + ", %Nand reply Hello World for any request such as http://localhost:8123/%N")
|
||||
(create {NINO_SERVICE}.make_custom (Current, "")).listen (port_number)
|
||||
end
|
||||
|
||||
execute (req: WGI_REQUEST; res: WGI_RESPONSE)
|
||||
do
|
||||
res.set_status_code (200, Void)
|
||||
res.put_header_text ("Content-Type: text/plain%R%N")
|
||||
res.put_string ("Hello World!%N")
|
||||
(create {NINO_SERVICE [HELLO_WORLD_EXECUTION]}.make_custom ("")).listen (port_number)
|
||||
end
|
||||
|
||||
port_number: INTEGER = 8123
|
||||
|
||||
note
|
||||
copyright: "2011-2012, Eiffel Software and others"
|
||||
copyright: "2011-2015, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
note
|
||||
description: "Summary description for {HELLO_WORLD_EXECUTION}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
HELLO_WORLD_EXECUTION
|
||||
|
||||
inherit
|
||||
WGI_EXECUTION
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
execute
|
||||
do
|
||||
response.set_status_code (200, Void)
|
||||
response.put_header_text ("Content-Type: text/plain%R%N")
|
||||
response.put_string ("Hello World!%N")
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, 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
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
note
|
||||
description: "Summary description for {WSF_DEFAULT_RESPONSE_SERVICE}."
|
||||
description: "Summary description for {WGI_EXECUTION_FACTORY}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
WSF_DEFAULT_RESPONSE_SERVICE [G -> WSF_EXECUTION create make end]
|
||||
WGI_EXECUTION_FACTORY
|
||||
|
||||
inherit
|
||||
WSF_DEFAULT_SERVICE [G]
|
||||
feature -- Factory
|
||||
|
||||
WSF_RESPONSE_SERVICE [G]
|
||||
execution (req: WGI_REQUEST; res: WGI_RESPONSE): WGI_EXECUTION
|
||||
deferred
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
@@ -22,13 +22,13 @@ feature {NONE} -- Initialization
|
||||
local
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
auth_type := req.auth_type
|
||||
content_length := req.content_length
|
||||
if attached req.content_type as ct then
|
||||
content_type := ct.string
|
||||
else
|
||||
content_type := Void
|
||||
end
|
||||
auth_type := req.auth_type
|
||||
gateway_interface := req.gateway_interface
|
||||
path_info := req.path_info
|
||||
path_translated := req.path_translated
|
||||
|
||||
@@ -16,10 +16,10 @@ note
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WSF_OPENSHIFT_SERVICE_LAUNCHER
|
||||
WSF_OPENSHIFT_SERVICE_LAUNCHER [G -> WSF_EXECUTION create make end]
|
||||
|
||||
inherit
|
||||
WSF_NINO_SERVICE_LAUNCHER
|
||||
WSF_NINO_SERVICE_LAUNCHER [G]
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
@@ -31,9 +31,7 @@ inherit
|
||||
|
||||
create
|
||||
make,
|
||||
make_and_launch,
|
||||
make_callback,
|
||||
make_callback_and_launch
|
||||
make_and_launch
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
@@ -86,7 +84,7 @@ feature {NONE} -- Implementation
|
||||
|
||||
|
||||
;note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-12-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-12-0 http://www.eiffel.com/developers/xml/configuration-1-12-0.xsd" name="wsf_httpd" uuid="9BF2D71A-0986-4025-9C97-15B65F07C568" library_target="wsf_httpd">
|
||||
<target name="wsf_httpd">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-12-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-12-0 http://www.eiffel.com/developers/xml/configuration-1-12-0.xsd" name="wsf_standalone" uuid="9BF2D71A-0986-4025-9C97-15B65F07C568" library_target="wsf_standalone">
|
||||
<target name="wsf_standalone">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
@@ -10,13 +10,13 @@
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="connector_httpd" location="..\..\ewsgi\connectors\httpd\httpd-safe.ecf"/>
|
||||
<library name="connector_standalone" location="..\..\ewsgi\connectors\standalone\standalone-safe.ecf"/>
|
||||
<library name="encoder" location="..\..\..\text\encoder\encoder-safe.ecf" readonly="false"/>
|
||||
<library name="error" location="..\..\..\utility\general\error\error-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf"/>
|
||||
<library name="http" location="..\..\..\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||
<library name="wsf" location="..\wsf-safe.ecf"/>
|
||||
<cluster name="wsf_httpd" location=".\httpd\" recursive="true"/>
|
||||
<cluster name="wsf_standalone" location=".\standalone\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
22
library/server/wsf/connector/standalone.ecf
Normal file
22
library/server/wsf/connector/standalone.ecf
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-12-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-12-0 http://www.eiffel.com/developers/xml/configuration-1-12-0.xsd" name="wsf_standalone" uuid="9BF2D71A-0986-4025-9C97-15B65F07C568" library_target="wsf_standalone">
|
||||
<target name="wsf_standalone">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" void_safety="none" syntax="provisional">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="connector_standalone" location="..\..\ewsgi\connectors\standalone\standalone.ecf"/>
|
||||
<library name="encoder" location="..\..\..\text\encoder\encoder.ecf" readonly="false"/>
|
||||
<library name="error" location="..\..\..\utility\general\error\error.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi\ewsgi.ecf"/>
|
||||
<library name="http" location="..\..\..\network\protocol\http\http.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||
<library name="wsf" location="..\wsf.ecf"/>
|
||||
<cluster name="wsf_standalone" location=".\standalone\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
@@ -8,8 +8,8 @@ note
|
||||
The httpd default connector support options:
|
||||
port: numeric such as 8099 (or equivalent string as "8099")
|
||||
base: base_url (very specific to standalone server)
|
||||
verbose: to display verbose output, useful for Nino
|
||||
force_single_threaded: use only one thread, useful for Nino
|
||||
verbose: to display verbose output, useful for standalone connector
|
||||
force_single_threaded: use only one thread, useful for standalone connector
|
||||
|
||||
check WSF_SERVICE_LAUNCHER for more documentation
|
||||
]"
|
||||
@@ -17,7 +17,7 @@ note
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WSF_HTTPD_SERVICE_LAUNCHER [G -> WSF_EXECUTION create make end]
|
||||
WSF_STANDALONE_SERVICE_LAUNCHER [G -> WSF_EXECUTION create make end]
|
||||
|
||||
inherit
|
||||
WSF_SERVICE_LAUNCHER [G]
|
||||
@@ -71,7 +71,6 @@ feature {NONE} -- Initialization
|
||||
create conn.make
|
||||
connector := conn
|
||||
conn.on_launched_actions.extend (agent on_launched)
|
||||
conn.on_stopped_actions.extend (agent on_stopped)
|
||||
conn.set_base (base_url)
|
||||
|
||||
update_configuration (conn.configuration)
|
||||
@@ -88,7 +87,6 @@ feature -- Execution
|
||||
if attached server_name as l_server_name then
|
||||
cfg.set_http_server_name (l_server_name)
|
||||
end
|
||||
-- conn.set_port_number (port_number)
|
||||
cfg.http_server_port := port_number
|
||||
end
|
||||
|
||||
@@ -102,7 +100,7 @@ feature -- Execution
|
||||
conn.set_base (base_url)
|
||||
debug ("nino")
|
||||
if verbose then
|
||||
io.error.put_string ("Launching Nino web server on port " + port_number.out)
|
||||
io.error.put_string ("Launching standalone web server on port " + port_number.out)
|
||||
if attached server_name as l_name then
|
||||
io.error.put_string ("%N http://" + l_name + ":" + port_number.out + "/" + base_url + "%N")
|
||||
else
|
||||
@@ -116,24 +114,19 @@ feature -- Execution
|
||||
|
||||
feature -- Callback
|
||||
|
||||
on_launched_actions: ACTION_SEQUENCE [TUPLE [WGI_CONNECTOR]]
|
||||
on_launched_actions: ACTION_SEQUENCE [TUPLE [WGI_STANDALONE_CONNECTOR [G]]]
|
||||
-- Actions triggered when launched
|
||||
|
||||
on_stopped_actions: ACTION_SEQUENCE [TUPLE [WGI_CONNECTOR]]
|
||||
on_stopped_actions: ACTION_SEQUENCE [TUPLE [WGI_STANDALONE_CONNECTOR [G]]]
|
||||
-- Actions triggered when stopped
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
on_launched (conn: WGI_CONNECTOR)
|
||||
on_launched (conn: WGI_STANDALONE_CONNECTOR [G])
|
||||
do
|
||||
on_launched_actions.call ([conn])
|
||||
end
|
||||
|
||||
on_stopped (conn: WGI_CONNECTOR)
|
||||
do
|
||||
on_stopped_actions.call ([conn])
|
||||
end
|
||||
|
||||
port_number: INTEGER
|
||||
|
||||
server_name: detachable READABLE_STRING_8
|
||||
@@ -146,7 +139,7 @@ feature {NONE} -- Implementation
|
||||
|
||||
feature -- Status report
|
||||
|
||||
connector: WGI_HTTPD_CONNECTOR [G]
|
||||
connector: WGI_STANDALONE_CONNECTOR [G]
|
||||
-- Default connector
|
||||
|
||||
launchable: BOOLEAN
|
||||
@@ -1,24 +0,0 @@
|
||||
note
|
||||
description: "Summary description for {WSF_DEFAULT_RESPONSE_SERVICE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
WSF_DEFAULT_RESPONSE_SERVICE
|
||||
|
||||
inherit
|
||||
WSF_DEFAULT_SERVICE
|
||||
|
||||
WSF_RESPONSE_SERVICE
|
||||
|
||||
note
|
||||
copyright: "2011-2012, 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
|
||||
@@ -4,13 +4,13 @@ note
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
WSF_DEFAULT_SERVICE
|
||||
WSF_DEFAULT_SERVICE [G -> WSF_EXECUTION create make end]
|
||||
|
||||
inherit
|
||||
WSF_DEFAULT_SERVICE_I [WSF_DEFAULT_SERVICE_LAUNCHER]
|
||||
WSF_DEFAULT_SERVICE_I [WSF_DEFAULT_SERVICE_LAUNCHER [G]]
|
||||
|
||||
note
|
||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
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
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
note
|
||||
description: "Summary description for {WSF_DEFAULT_RESPONSE_SERVICE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
WSF_DEFAULT_RESPONSE_SERVICE
|
||||
|
||||
inherit
|
||||
WSF_DEFAULT_SERVICE
|
||||
|
||||
WSF_RESPONSE_SERVICE
|
||||
|
||||
note
|
||||
copyright: "2011-2012, 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
|
||||
@@ -1,24 +0,0 @@
|
||||
note
|
||||
description: "Summary description for {WSF_DEFAULT_RESPONSE_SERVICE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
WSF_DEFAULT_RESPONSE_SERVICE
|
||||
|
||||
inherit
|
||||
WSF_DEFAULT_SERVICE
|
||||
|
||||
WSF_RESPONSE_SERVICE
|
||||
|
||||
note
|
||||
copyright: "2011-2012, 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
|
||||
@@ -4,13 +4,13 @@ note
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
WSF_DEFAULT_SERVICE
|
||||
WSF_DEFAULT_SERVICE [G -> WSF_EXECUTION create make end]
|
||||
|
||||
inherit
|
||||
WSF_DEFAULT_SERVICE_I [WSF_DEFAULT_SERVICE_LAUNCHER]
|
||||
WSF_DEFAULT_SERVICE_I [WSF_DEFAULT_SERVICE_LAUNCHER [G]]
|
||||
|
||||
note
|
||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
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
|
||||
|
||||
@@ -5,19 +5,17 @@ note
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WSF_DEFAULT_SERVICE_LAUNCHER
|
||||
WSF_DEFAULT_SERVICE_LAUNCHER [G -> WSF_EXECUTION create make end]
|
||||
|
||||
inherit
|
||||
WSF_LIBFCGI_SERVICE_LAUNCHER
|
||||
WSF_LIBFCGI_SERVICE_LAUNCHER [G]
|
||||
|
||||
create
|
||||
make,
|
||||
make_and_launch,
|
||||
make_callback,
|
||||
make_callback_and_launch
|
||||
make_and_launch
|
||||
|
||||
note
|
||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
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
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
note
|
||||
description: "Summary description for {WSF_DEFAULT_RESPONSE_SERVICE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
WSF_DEFAULT_RESPONSE_SERVICE
|
||||
|
||||
inherit
|
||||
WSF_DEFAULT_SERVICE
|
||||
|
||||
WSF_RESPONSE_SERVICE
|
||||
|
||||
note
|
||||
copyright: "2011-2012, 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
|
||||
@@ -4,13 +4,13 @@ note
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
WSF_DEFAULT_SERVICE
|
||||
WSF_DEFAULT_SERVICE [G -> WSF_EXECUTION create make end]
|
||||
|
||||
inherit
|
||||
WSF_DEFAULT_SERVICE_I [WSF_DEFAULT_SERVICE_LAUNCHER]
|
||||
WSF_DEFAULT_SERVICE_I [WSF_DEFAULT_SERVICE_LAUNCHER [G]]
|
||||
|
||||
note
|
||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
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
|
||||
|
||||
@@ -6,19 +6,17 @@ note
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WSF_DEFAULT_SERVICE_LAUNCHER
|
||||
WSF_DEFAULT_SERVICE_LAUNCHER [G -> WSF_EXECUTION create make end]
|
||||
|
||||
inherit
|
||||
WSF_OPENSHIFT_SERVICE_LAUNCHER
|
||||
WSF_OPENSHIFT_SERVICE_LAUNCHER [G]
|
||||
|
||||
create
|
||||
make,
|
||||
make_and_launch,
|
||||
make_callback,
|
||||
make_callback_and_launch
|
||||
make_and_launch
|
||||
|
||||
note
|
||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-12-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-12-0 http://www.eiffel.com/developers/xml/configuration-1-12-0.xsd" name="default_httpd" uuid="5CBA8C5A-3191-434A-8DE1-C0C3CAC9C4F4" library_target="default_httpd">
|
||||
<target name="default_httpd">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-12-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-12-0 http://www.eiffel.com/developers/xml/configuration-1-12-0.xsd" name="default_standalone" uuid="5CBA8C5A-3191-434A-8DE1-C0C3CAC9C4F4" library_target="default_standalone">
|
||||
<target name="default_standalone">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
@@ -11,7 +11,7 @@
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="wsf" location="..\wsf-safe.ecf"/>
|
||||
<library name="wsf_httpd" location="..\connector\httpd-safe.ecf"/>
|
||||
<cluster name="default_httpd" location=".\httpd\" recursive="true"/>
|
||||
<library name="wsf_standalone" location="..\connector\standalone-safe.ecf"/>
|
||||
<cluster name="default_standalone" location=".\standalone\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
17
library/server/wsf/default/standalone.ecf
Normal file
17
library/server/wsf/default/standalone.ecf
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-12-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-12-0 http://www.eiffel.com/developers/xml/configuration-1-12-0.xsd" name="default_standalone" uuid="5CBA8C5A-3191-434A-8DE1-C0C3CAC9C4F4" library_target="default_standalone">
|
||||
<target name="default_standalone">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" void_safety="none" syntax="provisional">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="wsf" location="..\wsf.ecf"/>
|
||||
<library name="wsf_standalone" location="..\connector\standalone.ecf"/>
|
||||
<cluster name="default_standalone" location=".\standalone\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user