Migrated most of the example and library to new design.

This commit is contained in:
2015-03-31 14:50:20 +02:00
parent 7d2ce8a77f
commit 4907bc3085
124 changed files with 2399 additions and 1789 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View 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

View File

@@ -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

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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"/>

View File

@@ -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

View File

@@ -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

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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

View 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

View File

@@ -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

View 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

View File

@@ -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>

View File

@@ -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">

View File

@@ -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>")

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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]

View File

@@ -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)"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -12,7 +12,7 @@ inherit
feature -- Access
connector: detachable separate WGI_HTTPD_CONNECTOR [G]
connector: detachable separate WGI_STANDALONE_CONNECTOR [G]
feature -- Element change

View File

@@ -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
@@ -82,17 +94,17 @@ feature -- Status report
port: INTEGER
-- Listening port.
--| 0: not launched
--| 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)"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)"

View File

@@ -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>

View 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>

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View 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>

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View 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