Added a few example based on the obsolete libraries (v0).

Updated the tutorial example.
Added WSF_MESSAGE_EXECUTION.
This commit is contained in:
2015-06-10 16:49:23 +02:00
parent b790c7fd21
commit 0e3e97a7fd
68 changed files with 3282 additions and 324 deletions

View File

@@ -8,10 +8,11 @@ To write once and run on any web server, on any platforms thanks to the notion o
== What is a connector? ==
A connector is the layer between the underlying httpd server, and your application based on EWF.
Currently, 3 connectors are available within EWF (but others are available outside).
Currently, 4 connectors are available within EWF (but others are available outside).
*­ CGI: the common CGI application (apache, iis, ...)
* FastCGI: on any server supporting libfcgi handling (apache, iis, ...)
* Nino: using the standalone Eiffel Web Nino server, you can run anywhere easily, and debug simply with EiffelStudio's debugger
* Standalone: a standalone Eiffel Web server, it can be run anywhere easily, and debug simply with EiffelStudio's debugger. It supports all concurrency modes, and require EiffelStudio >= 15.05.
* Nino: similar to the "standalone" connectors, but lack good concurrency support.
Supporting a new connector is fairly simple, it just has to support the simple EWSGI specification which is really small. Then EWF will bring the power on top of it.

View File

@@ -7,12 +7,12 @@ or go to [[step_2.wiki|step 2]]
== Get EWF package ==
=== From the archive ===
* Get recent archive from https://github.com/EiffelWebFramework/EWF/downloads
* Get recent archive of version v1 from https://github.com/EiffelWebFramework/EWF/releases
=== From the source ===
* '''Requirement''': install [http://www.git-scm.org/ git] on your machine
$ git clone --recursive https://github.com/EiffelWebFramework/EWF.git ewf
$ git clone -b v1 --recursive https://github.com/EiffelWebFramework/EWF.git ewf
== Install EWF ==
For now, there is nothing specific to do.

View File

@@ -13,14 +13,14 @@ or go to [[step_3.wiki|step 3]]
== "hello" project ==
* using the "wsf" library:
** It provides service, request, response, ...
* using the "default_nino" library
** This is used to build the application in a portable manner, but for this compilation, it uses Eiffel Web Nino as connector.
** We use Eiffel Web Nino for this tutorial, because there is no need to configure any apache, iis, and so on. And it is convenient to execute inside EiffelStudio
* using the "default_standalone" library
** This is used to build the application in a portable manner, but for this compilation, it uses the standalone web server as connector.
** We use that standalone connection this tutorial, because there is no need to configure any apache, iis, and so on. And it is convenient to execute with EiffelStudio debugger.
* To see the result, you should open http://localhost/ on your web browser. Note if the application is using another port such as 9999, you should open http://localhost:9999/
* You will find inside [[step_2]] the "hello" project
** target "hello" provides a very simple implementation (But by default, it is using port 80 with Eiffel Web Nino, which might already be busy by other application)
** target "hello" provides a very simple implementation (But by default, it is using port 80 with standalone web server, which might already be busy by other application)
** target "hello_custom" which uses almost the same code, but in addition, you can use the ewf.ini file to precise the port number (9999 for this example)
* To see the result, open http://localhost/ in a web browser.
@@ -28,25 +28,38 @@ or go to [[step_3.wiki|step 3]]
* Eiffel code
class
HELLO_APPLICATION
HELLO_APPLICATION
inherit
WSF_DEFAULT_RESPONSE_SERVICE
WSF_DEFAULT_SERVICE [HELLO_EXECUTION]
create
make_and_launch
feature {NONE} -- Initialization
response (req: WSF_REQUEST): WSF_PAGE_RESPONSE
-- Computed response message.
do
create Result.make
Result.put_string ("Hello World")
end
make_and_launch
end
class
HELLO_EXECUTION
inherit
WSF_EXECUTION
create
make
feature -- Execution
execute
local
msg: WSF_PAGE_RESPONSE
do
create msg.make_with_body ("Hello World")
response.send (msg)
end
end
Note: we could also declare the root class as being "WSF_DEFAULT_SERVICE [HELLO_EXECUTION]" to avoid this HELLO_APPLICATION class.
----

View File

@@ -1,11 +1,11 @@
This folder contains 2 alternatives code
1) "execute" using the WSF_SERVICE interface, i.e
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
1) "message" using the WSF_MESSAGE_EXECUTION interface, i.e
message: WSF_RESPONSE_MESSAGE
do
...
end
2) "launcher" using the WSF_RESPONSE_SERVICE interface, but it uses a launcher to start the service, instead of inheriting from WSF_DEFAULT_SERVICE or WSF_DEFAULT_RESPONSE_SERVICE
2) "launcher" using the WSF_RESPONSE_SERVICE interface, but it uses a launcher to start the service, instead of inheriting from WSF_DEFAULT_SERVICE

View File

@@ -1,39 +0,0 @@
note
description: "[
APPLICATION implements the `Hello World' service.
It inherits from WSF_DEFAULT_SERVICE to get default EWF connector ready
only `execute' needs to be implemented.
`initialize' can be redefine to provide custom options if needed.
]"
class
HELLO_APPLICATION
inherit
WSF_DEFAULT_SERVICE
create
make_and_launch
feature {NONE} -- Initialization
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
local
page: WSF_PAGE_RESPONSE
do
create page.make
page.put_string ("Hello World")
res.send (page)
--| another alternative would have been more low level
--| by setting the status code, the content type, and the content length which is 11 for "Hello World"
--| res.put_header ({WSF_HEADER}.ok, <<["Content-Type", "text/plain"], ["Content-Length", "11"]>>)
--| res.put_string ("Hello World")
end
end

View File

@@ -11,30 +11,31 @@ class
HELLO_APPLICATION
inherit
WSF_RESPONSE_SERVICE
WSF_LAUNCHABLE_SERVICE
redefine
initialize
end
create
make_and_launch
feature {NONE} -- Initialization
make_and_launch
initialize
local
launcher: WSF_DEFAULT_SERVICE_LAUNCHER
opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS
do
--| Uncomment the following line, to read options from "ewf.ini" configuration file
-- create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} opts.make_from_file ("ewf.ini")
create launcher.make_and_launch (Current, opts)
Precursor
--| Uncomment the following 2 lines, to read options from "ewf.ini" configuration file
-- create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} opts.make_from_file ("ewf.ini")
-- import_service_options (opts)
end
feature {NONE} -- Initialization
response (req: WSF_REQUEST): WSF_PAGE_RESPONSE
launch (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local
launcher: WSF_DEFAULT_SERVICE_LAUNCHER [HELLO_EXECUTION]
do
create Result.make
Result.put_string ("Hello World")
create launcher.make_and_launch (opts)
end
end

View File

@@ -0,0 +1,35 @@
note
description: "[
Request execution for Current application.
Implement `execute' based on `request' and `response'.
]"
author: "$Author$"
date: "$Date$"
revision: "$Revision$"
class
HELLO_EXECUTION
inherit
WSF_EXECUTION
create
make
feature -- Execution
execute
local
msg: WSF_PAGE_RESPONSE
do
create msg.make_with_body ("Hello World")
response.send (msg)
--| alternative would have been more low level
--| by setting the content type, and the content length which is 11 for "Hello World"
-- response.header.put_content_type_text_plain
-- response.header.put_content_length (11)
-- response.put_string ("Hello World")
end
end

View File

@@ -0,0 +1,21 @@
note
description: "[
APPLICATION implements the `Hello World' service.
It inherits from WSF_DEFAULT_SERVICE to get default EWF connector ready
only `execute' needs to be implemented.
`initialize' can be redefine to provide custom options if needed.
]"
class
HELLO_APPLICATION
inherit
WSF_DEFAULT_SERVICE [HELLO_EXECUTION]
create
make_and_launch
end

View File

@@ -0,0 +1,27 @@
note
description: "[
Request execution for Current application.
Implement `message' based on `request' and `response'.
]"
author: "$Author$"
date: "$Date$"
revision: "$Revision$"
class
HELLO_EXECUTION
inherit
WSF_MESSAGE_EXECUTION
create
make
feature -- Execution
message: WSF_PAGE_RESPONSE
do
create Result.make_with_body ("Hello World")
response.send (Result)
end
end

View File

@@ -11,9 +11,10 @@
<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>
<setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="wsf" location="..\..\..\..\..\..\library\server\wsf\wsf-safe.ecf"/>
<library name="default_nino" location="..\..\..\..\..\..\library\server\wsf\default\nino-safe.ecf"/>
<library name="default_standalone" location="..\..\..\..\..\..\library\server\wsf\default\standalone-safe.ecf"/>
<cluster name="src" location=".\" />
</target>

View File

@@ -1,4 +1,4 @@
# For nino connector, use port 9999
# For standalone connectors, use port 9999
port=9999
#verbose=true

View File

@@ -12,7 +12,7 @@
</option>
<precompile name="precomp_wsf" location="..\..\..\..\precomp\wsf-safe.ecf"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="default_nino" location="..\..\..\..\library\server\wsf\default\nino-safe.ecf"/>
<library name="default_standalone" location="..\..\..\..\library\server\wsf\default\standalone-safe.ecf"/>
<library name="wsf" location="..\..\..\..\library\server\wsf\wsf-safe.ecf"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
@@ -29,7 +29,7 @@
<setting name="concurrency" value="thread"/>
<precompile name="precomp_wsf-mt" location="..\..\..\..\precomp\wsf-mt-safe.ecf"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="default_nino" location="..\..\..\..\library\server\wsf\default\nino-safe.ecf"/>
<library name="default_standalone" location="..\..\..\..\library\server\wsf\default\standalone-safe.ecf"/>
<library name="wsf" location="..\..\..\..\library\server\wsf\wsf-safe.ecf"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>

View File

@@ -2,19 +2,17 @@ note
description: "[
This class implements the `Hello World' service.
It inherits from WSF_DEFAULT_RESPONSE_SERVICE to get default EWF connector ready
only `response' needs to be implemented.
In this example, it is redefined and specialized to be WSF_PAGE_RESPONSE
`initialize' can be redefine to provide custom options if needed.
It inherits from WSF_DEFAULT_SERVICE to get default EWF connector ready
only `HELLO_EXECUTION' needs to be implemented.
`initialize' is redefined to provide custom options if needed.
]"
class
CUSTOM_HELLO_APPLICATION
inherit
WSF_DEFAULT_RESPONSE_SERVICE
WSF_DEFAULT_SERVICE [HELLO_EXECUTION]
redefine
initialize
end
@@ -32,7 +30,7 @@ feature {NONE} -- Initialization
--| You can also uncomment the following line if you use the Nino connector
--| so that the server listens on port 9999
--| quite often the port 80 is already busy
-- set_service_option ("port", 9999)
set_service_option ("port", 9999)
--| Uncomment next line to have verbose option if available
-- set_service_option ("verbose", True)
@@ -41,13 +39,4 @@ feature {NONE} -- Initialization
Precursor
end
feature {NONE} -- Initialization
response (req: WSF_REQUEST): WSF_PAGE_RESPONSE
-- Computed response message.
do
create Result.make
Result.put_string ("Hello World")
end
end

View File

@@ -2,30 +2,20 @@ note
description: "[
This class implements the `Hello World' service.
It inherits from WSF_DEFAULT_RESPONSE_SERVICE to get default EWF connector ready
only `response' needs to be implemented.
In this example, it is redefined and specialized to be WSF_PAGE_RESPONSE
`initialize' can be redefine to provide custom options if needed.
It inherits from WSF_DEFAULT_SERVICE to get default EWF connector ready.
And implement HELLO_EXECUTION.
`initialize' can be redefine to provide custom options if needed,
such as specific port number.
]"
class
HELLO_APPLICATION
inherit
WSF_DEFAULT_RESPONSE_SERVICE
WSF_DEFAULT_SERVICE [HELLO_EXECUTION]
create
make_and_launch
feature {NONE} -- Initialization
response (req: WSF_REQUEST): WSF_PAGE_RESPONSE
-- Computed response message.
do
create Result.make
Result.put_string ("Hello World")
end
end

View File

@@ -0,0 +1,35 @@
note
description: "[
Request execution for Current application.
Implement `execute' based on `request' and `response'.
]"
author: "$Author$"
date: "$Date$"
revision: "$Revision$"
class
HELLO_EXECUTION
inherit
WSF_EXECUTION
create
make
feature -- Execution
execute
local
msg: WSF_PAGE_RESPONSE
do
create msg.make_with_body ("Hello World")
response.send (msg)
--| alternative would have been more low level
--| by setting the content type, and the content length which is 11 for "Hello World"
-- response.header.put_content_type_text_plain
-- response.header.put_content_length (11)
-- response.put_string ("Hello World")
end
end

View File

@@ -11,12 +11,12 @@ or go to [[step_4.wiki|step 4]]
== "hello" project ==
* Let's start from the "hello_custom" project
* you will learn how to use the req: WSF_REQUEST argument
* you will learn how to use the request: WSF_REQUEST argument
* See the hello project from [[step_3|step #3]] folder
* You can find code in [[step_3]] folder :
response (req: WSF_REQUEST): WSF_HTML_PAGE_RESPONSE
message: WSF_HTML_PAGE_RESPONSE
-- Computed response message.
do
--| It is now returning a WSF_HTML_PAGE_RESPONSE
@@ -25,7 +25,7 @@ or go to [[step_4.wiki|step 4]]
Result.set_title ("EWF tutorial / Hello World!")
--| Check if the request contains a parameter named "user"
--| this could be a query, or a form parameter
if attached req.string_item ("user") as l_user then
if attached request.string_item ("user") as l_user then
--| If yes, say hello world #name
Result.set_body ("Hello " + l_user + "!")
--| We should html encode this name
@@ -43,8 +43,8 @@ or go to [[step_4.wiki|step 4]]
end
--| note:
--| 1) Source of the parameter, we could have used
--| req.query_parameter ("user") to search only in the query string
--| req.form_parameter ("user") to search only in the form parameters
--| request.query_parameter ("user") to search only in the query string
--| request.form_parameter ("user") to search only in the form parameters
--| 2) response type
--| it could also have used WSF_PAGE_REPONSE, and build the html in the code
--|

View File

@@ -15,7 +15,7 @@
<precompile name="precomp_wsf-mt" location="..\..\..\..\precomp\wsf-mt-safe.ecf"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="wsf" location="..\..\..\..\library\server\wsf\wsf-safe.ecf"/>
<library name="default_nino" location="..\..\..\..\library\server\wsf\default\nino-safe.ecf"/>
<library name="default_standalone" location="..\..\..\..\library\server\wsf\default\standalone-safe.ecf"/>
<cluster name="src" location=".\src" recursive="true"/>
</target>

View File

@@ -1,10 +1,9 @@
note
description: "[
This class implements the `Hello World' service.
This class launch the HELLO_EXECUTION service.
It inherits from WSF_DEFAULT_RESPONSE_SERVICE to get default EWF connector ready
only `response' needs to be implemented.
In this example, it is redefined and specialized to be WSF_PAGE_RESPONSE
It inherits from WSF_DEFAULT_SERVICE to get default EWF connector ready
only `HELLO_EXECUTION' needs to be implemented.
`initialize' can be redefine to provide custom options if needed.
@@ -14,7 +13,7 @@ class
HELLO_APPLICATION
inherit
WSF_DEFAULT_RESPONSE_SERVICE
WSF_DEFAULT_SERVICE [HELLO_EXECUTION]
redefine
initialize
end
@@ -22,44 +21,6 @@ inherit
create
make_and_launch
feature {NONE} -- Execution
response (req: WSF_REQUEST): WSF_HTML_PAGE_RESPONSE
-- Computed response message.
do
--| It is now returning a WSF_HTML_PAGE_RESPONSE
--| Since it is easier for building html page
create Result.make
Result.set_title ("EWF tutorial / Hello World!")
--| Check if the request contains a parameter named "user"
--| this could be a query, or a form parameter
if attached req.string_item ("user") as l_user then
--| If yes, say hello world #name
Result.set_body ("Hello " + l_user + "!")
--| We should html encode this name
--| but to keep the example simple, we don't do that for now.
else
--| Otherwise, ask for name
Result.set_body ("[
<form action="/" method="POST">
<p>Hello, what is your name?</p>
<input type="text" name="user"/>
<input type="submit" value="Validate"/>
</form>
]"
)
end
--| note:
--| 1) Source of the parameter, we could have used
--| req.query_parameter ("user") to search only in the query string
--| req.form_parameter ("user") to search only in the form parameters
--| 2) response type
--| it could also have used WSF_PAGE_REPONSE, and build the html in the code
--|
end
feature {NONE} -- Initialization
initialize

View File

@@ -0,0 +1,53 @@
note
description: "Implementation of Hello world with form."
date: "$Date$"
revision: "$Revision$"
class
HELLO_EXECUTION
inherit
WSF_MESSAGE_EXECUTION
create
make
feature {NONE} -- Execution
message: WSF_HTML_PAGE_RESPONSE
-- Computed response message.
do
--| It is now returning a WSF_HTML_PAGE_RESPONSE
--| Since it is easier for building html page
create Result.make
Result.set_title ("EWF tutorial / Hello World!")
--| Check if the request contains a parameter named "user"
--| this could be a query, or a form parameter
if attached request.string_item ("user") as l_user then
--| If yes, say hello world #name
Result.set_body ("Hello " + l_user + "!")
--| We should html encode this name
--| but to keep the example simple, we don't do that for now.
else
--| Otherwise, ask for name
Result.set_body ("[
<form action="/" method="POST">
<p>Hello, what is your name?</p>
<input type="text" name="user"/>
<input type="submit" value="Validate"/>
</form>
]"
)
end
--| note:
--| 1) Source of the parameter, we could have used
--| request.query_parameter ("user") to search only in the query string
--| request.form_parameter ("user") to search only in the form parameters
--| 2) response type
--| it could also have used WSF_PAGE_REPONSE, and build the html in the code
--|
end
end

View File

@@ -11,30 +11,30 @@ or go to the [[README.wiki|index]]
== "hello" project ==
* Let's start from the "hello" project
* you will learn how to use the req: WSF_ROUTER component
* you will learn how to use the WSF_ROUTER component
* See the hello project from [[step_4|step #4]] folder
* You can find code in [[step_4]] folder :
To get a routed service based on URI Template, your service application class should inherit from WSF_URI_TEMPLATE_ROUTED_SERVICE
then you need to implement "setup_router", the following code is from the step_4 example
To get a routed execution based on URI Template, your execution class should inherit from WSF_URI_TEMPLATE_ROUTED_EXECUTION
then you need to implement "setup_router". In addition you can inherit from WSF_ROUTED_URI_HELPER and WSF_ROUTED_URI_TEMPLATE_HELPER, in order to call user-friendly routine provided to work easily with uri, or uri-template mapping. the following code is from the step_4 example
setup_router
do
router.map_agent ("/hello", agent execute_hello)
map_uri_agent ("/hello", agent execute_hello, Void)
router.map_with_request_methods ("/users/{user}/message/{mesgid}", create {USER_MESSAGE_HANDLER}, <<"GET", "POST">>)
router.map_with_request_methods ("/users/{user}/message/", create {USER_MESSAGE_HANDLER}, <<"GET", "POST">>)
map_uri_template ("/users/{user}/message/{mesgid}", create {USER_MESSAGE_HANDLER}, <<"GET", "POST">>)
map_uri_template ("/users/{user}/message/", create {USER_MESSAGE_HANDLER}, <<"GET", "POST">>)
router.map_agent_response_with_request_methods ("/users/{user}/{?op}", agent response_user, <<"GET">>)
map_uri_template_response_agent ("/users/{user}/{?op}", agent response_user, <<"GET">>)
end
* map_agent is used to handle the url /hello with the feature "execute_hello"
* map_agent_response_with_request_methods is similar but you precise the accepted request methods
* map and map_with_request_method are similar to previous "agent" variant, but it is using a descendant of WSF_HANDLER to handle the related url.
* map_agent_response is similar but you precise the accepted request methods
* map is similar to previous "agent" variant, but it is using a descendant of WSF_HANDLER to handle the related request.
* In this example, we use the URI Template router, this allows to define the route using resource like /user/{user} , and then you get access to the "user" data from the WSF_REQUEST.path_parameter or using the context argument passed for the execute or response handler.
* In this example, we use the URI-Template router, this allows to define the route using resource like /user/{user} , and then you get access to the "user" data from the WSF_REQUEST.path_parameter or using the context argument passed for the execute or response handler.
* The example also includes basic notions of url, html encoding, check the hello.ecf to see the added libraries (http to get easy access to the http status code, encoder for simple encoding components)
----

View File

@@ -12,7 +12,7 @@
</option>
<setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="default_nino" location="..\..\..\..\library\server\wsf\default\nino-safe.ecf"/>
<library name="default_standalone" location="..\..\..\..\library\server\wsf\default\standalone-safe.ecf"/>
<library name="encoder" location="..\..\..\..\library\text\encoder\encoder-safe.ecf" readonly="false"/>
<library name="wsf" location="..\..\..\..\library\server\wsf\wsf-safe.ecf" readonly="false"/>
<library name="http" location="../../../../library/network/protocol/http/http-safe.ecf" readonly="false"/>

View File

@@ -3,7 +3,6 @@
This class implements the `Hello World' service.
It inherits from WSF_DEFAULT_SERVICE to get default EWF connector ready
And from WSF_URI_TEMPLATE_ROUTED_SERVICE to use the router service
`initialize' can be redefine to provide custom options if needed.
@@ -13,9 +12,7 @@ class
HELLO_APPLICATION
inherit
WSF_ROUTED_SERVICE
WSF_DEFAULT_SERVICE
WSF_DEFAULT_SERVICE [HELLO_EXECUTION]
redefine
initialize
end
@@ -23,136 +20,6 @@ inherit
create
make_and_launch
feature {NONE} -- Initialization
setup_router
do
-- router.map (create {WSF_URI_MAPPING}.make ("/hello", create {WSF_AGENT_URI_HANDLER}.make (agent execute_hello)))
map_agent_uri ("/hello", agent execute_hello, Void)
-- router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make ("/users/{user}/message/{mesgid}", create {USER_MESSAGE_HANDLER}), router.methods_HEAD_GET_POST)
map_uri_template ("/users/{user}/message/{mesgid}", create {USER_MESSAGE_HANDLER}, router.methods_HEAD_GET_POST)
-- router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make ("/users/{user}/message/", create {USER_MESSAGE_HANDLER}), router.methods_GET_POST)
map_uri_template ("/users/{user}/message/", create {USER_MESSAGE_HANDLER}, router.methods_GET_POST)
-- router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make ("/users/{user}/{?op}", create {WSF_AGENT_URI_TEMPLATE_RESPONSE_HANDLER}.make (agent response_user)), router.methods_GET)
map_agent_uri_template_response ("/users/{user}/{?op}", agent response_user, 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
map_uri_template (a_tpl: READABLE_STRING_8; a_handler: WSF_URI_TEMPLATE_HANDLER; rqst_methods: detachable WSF_REQUEST_METHODS)
do
router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make (a_tpl, a_handler), rqst_methods)
end
map_agent_uri_template_response (a_tpl: READABLE_STRING_8; a_action: like {WSF_URI_TEMPLATE_RESPONSE_AGENT_HANDLER}.action; rqst_methods: detachable WSF_REQUEST_METHODS)
do
router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make (a_tpl, create {WSF_URI_TEMPLATE_RESPONSE_AGENT_HANDLER}.make (a_action)), rqst_methods)
end
feature -- Execution
execute_hello (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Computed response message.
local
mesg: WSF_HTML_PAGE_RESPONSE
s: STRING_8
l_user_name: READABLE_STRING_32
do
--| It is now returning a WSF_HTML_PAGE_RESPONSE
--| Since it is easier for building html page
create mesg.make
mesg.set_title ("EWF tutorial / Hello World!")
--| Check if the request contains a parameter named "user"
--| this could be a query, or a form parameter
if attached {WSF_STRING} req.item ("user") as u then
--| If yes, say hello world #name
l_user_name := (create {HTML_ENCODER}).decoded_string (u.value)
s := "<p>Hello " + mesg.html_encoded_string (l_user_name) + "!</p>"
s.append ("Display a <a href=%"/users/" + u.url_encoded_value + "/message/%">message</a></p>")
s.append ("<p>Click <a href=%"/users/" + u.url_encoded_value + "/?op=quit%">here</a> to quit.</p>")
mesg.set_body (s)
--| We should html encode this name
--| but to keep the example simple, we don't do that for now.
else
--| Otherwise, ask for name
s := (create {HTML_ENCODER}).encoded_string ({STRING_32} "Hello / ahoj / नमस्ते / Ciào / مرحبا / Hola / 你好 / Hallo / Selam / Bonjour ")
s.append ("[
<form action="/hello" method="GET">
What is your name?</p>
<input type="text" name="user"/>
<input type="submit" value="Validate"/>
</form>
]"
)
mesg.set_body (s)
end
--| note:
--| 1) Source of the parameter, we could have used
--| req.query_parameter ("user") to search only in the query string
--| req.form_parameter ("user") to search only in the form parameters
--| 2) response type
--| it could also have used WSF_PAGE_REPONSE, and build the html in the code
--|
res.send (mesg)
end
response_user (req: WSF_REQUEST): WSF_RESPONSE_MESSAGE
-- Computed response message.
local
html: WSF_HTML_PAGE_RESPONSE
redir: WSF_HTML_DELAYED_REDIRECTION_RESPONSE
s: STRING_8
l_username: STRING_32
do
if attached {WSF_STRING} req.path_parameter ("user") as u then
l_username := (create {HTML_ENCODER}).general_decoded_string (u.value)
if
attached {WSF_STRING} req.query_parameter ("op") as l_op
then
if l_op.is_case_insensitive_equal ("quit") then
create redir.make (req.script_url ("/hello"), 3)
create html.make
redir.set_title ("Bye " + html.html_encoded_string (l_username))
redir.set_body ("Bye " + html.html_encoded_string (l_username) + ",<br/> see you soon.<p>You will be redirected to " +
redir.url_location + " in " + redir.delay.out + " second(s) ...</p>"
)
Result := redir
else
create html.make
html.set_title ("Bad request")
html.set_body ("Bad request: unknown operation '" + l_op.url_encoded_value + "'.")
Result := html
end
else
create html.make
s := "<p>User <em>'" + html.html_encoded_string (l_username) + "'</em>!</p>"
s.append ("Display a <a href=%"/users/" + u.url_encoded_value + "/message/%">message</a></p>")
s.append ("<p>Click <a href=%"/users/" + u.url_encoded_value + "/?op=quit%">here</a> to quit.</p>")
html.set_title ("User '" + u.url_encoded_value + "'")
html.set_body (s)
Result := html
end
else
create html.make
html.set_title ("Bad request")
html.set_body ("Bad request: missing user parameter")
Result := html
end
end
feature {NONE} -- Initialization
initialize
@@ -163,8 +30,6 @@ feature {NONE} -- Initialization
--| If you don't need any custom options, you are not obliged to redefine `initialize'
Precursor
--| Initialize router
initialize_router
end

View File

@@ -0,0 +1,135 @@
note
description: "[
This class implements the `Hello World' execution service.
It inherits from WSF_ROUTED_EXECUTION to use the router service
and from WSF_ROUTED_URI_TEMPLATE_HELPER to use help feature to map
uri-template routes
]"
class
HELLO_EXECUTION
inherit
WSF_ROUTED_EXECUTION
WSF_ROUTED_URI_HELPER
WSF_ROUTED_URI_TEMPLATE_HELPER
create
make
feature {NONE} -- Initialization
setup_router
do
-- router.map (create {WSF_URI_MAPPING}.make ("/hello", create {WSF_AGENT_URI_HANDLER}.make (agent execute_hello)))
map_uri_agent ("/hello", agent execute_hello)
-- router.map (create {WSF_URI_TEMPLATE_MAPPING}.make ("/users/{user}/message/{mesgid}", create {USER_MESSAGE_HANDLER}), router.methods_HEAD_GET_POST)
map_uri_template ("/users/{user}/message/{mesgid}", create {USER_MESSAGE_HANDLER}, router.methods_HEAD_GET_POST)
-- router.map (create {WSF_URI_TEMPLATE_MAPPING}.make ("/users/{user}/message/", create {USER_MESSAGE_HANDLER}), router.methods_GET_POST)
map_uri_template ("/users/{user}/message/", create {USER_MESSAGE_HANDLER}, router.methods_GET_POST)
-- router.map (create {WSF_URI_TEMPLATE_MAPPING}.make ("/users/{user}/{?op}", create {WSF_AGENT_URI_TEMPLATE_RESPONSE_HANDLER}.make (agent response_user)), router.methods_GET)
map_uri_template_response_agent ("/users/{user}/{?op}", agent response_user, router.methods_GET)
end
feature -- Execution
execute_hello (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Computed response message.
local
mesg: WSF_HTML_PAGE_RESPONSE
s: STRING_8
l_user_name: READABLE_STRING_32
do
--| It is now returning a WSF_HTML_PAGE_RESPONSE
--| Since it is easier for building html page
create mesg.make
mesg.set_title ("EWF tutorial / Hello World!")
--| Check if the request contains a parameter named "user"
--| this could be a query, or a form parameter
if attached {WSF_STRING} req.item ("user") as u then
--| If yes, say hello world #name
l_user_name := (create {HTML_ENCODER}).decoded_string (u.value)
s := "<p>Hello " + mesg.html_encoded_string (l_user_name) + "!</p>"
s.append ("Display a <a href=%"/users/" + u.url_encoded_value + "/message/%">message</a></p>")
s.append ("<p>Click <a href=%"/users/" + u.url_encoded_value + "/?op=quit%">here</a> to quit.</p>")
mesg.set_body (s)
--| We should html encode this name
--| but to keep the example simple, we don't do that for now.
else
--| Otherwise, ask for name
s := (create {HTML_ENCODER}).encoded_string ({STRING_32} "Hello / ahoj / नमस्ते / Ciào / مرحبا / Hola / 你好 / Hallo / Selam / Bonjour ")
s.append ("[
<form action="/hello" method="GET">
What is your name?</p>
<input type="text" name="user"/>
<input type="submit" value="Validate"/>
</form>
]"
)
mesg.set_body (s)
end
--| note:
--| 1) Source of the parameter, we could have used
--| req.query_parameter ("user") to search only in the query string
--| req.form_parameter ("user") to search only in the form parameters
--| 2) response type
--| it could also have used WSF_PAGE_REPONSE, and build the html in the code
--|
res.send (mesg)
end
response_user (req: WSF_REQUEST): WSF_RESPONSE_MESSAGE
-- Computed response message.
local
html: WSF_HTML_PAGE_RESPONSE
redir: WSF_HTML_DELAYED_REDIRECTION_RESPONSE
s: STRING_8
l_username: STRING_32
do
if attached {WSF_STRING} req.path_parameter ("user") as u then
l_username := (create {HTML_ENCODER}).general_decoded_string (u.value)
if
attached {WSF_STRING} req.query_parameter ("op") as l_op
then
if l_op.is_case_insensitive_equal ("quit") then
create redir.make (req.script_url ("/hello"), 3)
create html.make
redir.set_title ("Bye " + html.html_encoded_string (l_username))
redir.set_body ("Bye " + html.html_encoded_string (l_username) + ",<br/> see you soon.<p>You will be redirected to " +
redir.url_location + " in " + redir.delay.out + " second(s) ...</p>"
)
Result := redir
else
create html.make
html.set_title ("Bad request")
html.set_body ("Bad request: unknown operation '" + l_op.url_encoded_value + "'.")
Result := html
end
else
create html.make
s := "<p>User <em>'" + html.html_encoded_string (l_username) + "'</em>!</p>"
s.append ("Display a <a href=%"/users/" + u.url_encoded_value + "/message/%">message</a></p>")
s.append ("<p>Click <a href=%"/users/" + u.url_encoded_value + "/?op=quit%">here</a> to quit.</p>")
html.set_title ("User '" + u.url_encoded_value + "'")
html.set_body (s)
Result := html
end
else
create html.make
html.set_title ("Bad request")
html.set_body ("Bad request: missing user parameter")
Result := html
end
end
end