diff --git a/examples/tutorial/README.wiki b/examples/tutorial/README.wiki
index 789b4b19..afc57639 100644
--- a/examples/tutorial/README.wiki
+++ b/examples/tutorial/README.wiki
@@ -26,7 +26,7 @@ For now, you just need to know EWF is compliant with EWSGI specification.
Now let's discover the Eiffel Web Framework with this tutorial.
# [[step_1.wiki|Step #1]]: You will learn first, how to get and install EWF.
# [[step_2.wiki|Step #2]]: build a simple Hello World application
-# [[step_3.wiki|Step #3]]: use the query and form parameter to build dynamic service
+# [[step_3.wiki|Step #3]]: use the parameter to build dynamic service
# [[step_4.wiki|Step #4]]: And you will learn how to dispatch URL
diff --git a/examples/tutorial/step_2.wiki b/examples/tutorial/step_2.wiki
index 6810816d..ac597913 100644
--- a/examples/tutorial/step_2.wiki
+++ b/examples/tutorial/step_2.wiki
@@ -7,21 +7,16 @@
** [[step_1.wiki|Previous step]] completed
-== Create "hello" project ==
-=== From the archive ===
-- to be completed
+== "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
-=== From the source ===
-- Requirement: install git on your machine (http://www.git-scm.org/)
-
- git clone --recursive https://github.com/EiffelWebFramework/EWF.git ewf
-
-And that's it for now.
-
-== Install EWF ==
-For now, there is nothing specific to do.
-
-(Note: if you want to use the "http_client" library, you will need to do a few extra steps to eventually compile Eiffel Curl.)
+* 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_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)
----
Previous [[step_1|step 1]] | Go to [[step_3.wiki|step 3]]
diff --git a/examples/tutorial/step_2/hello/alternatives/README.wiki b/examples/tutorial/step_2/hello/alternatives/README.wiki
new file mode 100644
index 00000000..c331a521
--- /dev/null
+++ b/examples/tutorial/step_2/hello/alternatives/README.wiki
@@ -0,0 +1,11 @@
+This folder contains 2 alternatives code
+
+1) "execute" using the WSF_SERVICE interface, i.e
+ execute (req: WSF_REQUEST; res: WSF_RESPONSE)
+ 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
+
diff --git a/examples/tutorial/step_2/hello/alternatives/execute/hello_application.e b/examples/tutorial/step_2/hello/alternatives/execute/hello_application.e
new file mode 100644
index 00000000..016aa2ad
--- /dev/null
+++ b/examples/tutorial/step_2/hello/alternatives/execute/hello_application.e
@@ -0,0 +1,39 @@
+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
diff --git a/examples/tutorial/step_2/hello/alternatives/execute/hello_with_execute.ecf b/examples/tutorial/step_2/hello/alternatives/execute/hello_with_execute.ecf
new file mode 100644
index 00000000..9375f810
--- /dev/null
+++ b/examples/tutorial/step_2/hello/alternatives/execute/hello_with_execute.ecf
@@ -0,0 +1,20 @@
+
+
+
+
+
+ /EIFGENs$
+ /CVS$
+ /.svn$
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/tutorial/step_2/hello/alternatives/execute/hello_with_execute.rc b/examples/tutorial/step_2/hello/alternatives/execute/hello_with_execute.rc
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/examples/tutorial/step_2/hello/alternatives/execute/hello_with_execute.rc
@@ -0,0 +1 @@
+
diff --git a/examples/tutorial/step_2/hello/application.e b/examples/tutorial/step_2/hello/alternatives/launcher/hello_application.e
similarity index 54%
rename from examples/tutorial/step_2/hello/application.e
rename to examples/tutorial/step_2/hello/alternatives/launcher/hello_application.e
index cad43e41..4dac696c 100644
--- a/examples/tutorial/step_2/hello/application.e
+++ b/examples/tutorial/step_2/hello/alternatives/launcher/hello_application.e
@@ -8,23 +8,25 @@ note
]"
class
- APPLICATION
+ HELLO_APPLICATION
inherit
- WSF_DEFAULT_RESPONSE_SERVICE
- redefine
- initialize
- end
+ WSF_RESPONSE_SERVICE
create
make_and_launch
feature {NONE} -- Initialization
- initialize
+ make_and_launch
+ local
+ launcher: WSF_DEFAULT_SERVICE_LAUNCHER
+ opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS
do
- create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} service_options.make_from_file ("ewf.ini")
- Precursor
+ --| 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)
end
feature {NONE} -- Initialization
diff --git a/examples/tutorial/step_2/hello/alternatives/launcher/hello_with_launcher.ecf b/examples/tutorial/step_2/hello/alternatives/launcher/hello_with_launcher.ecf
new file mode 100644
index 00000000..00ef9259
--- /dev/null
+++ b/examples/tutorial/step_2/hello/alternatives/launcher/hello_with_launcher.ecf
@@ -0,0 +1,20 @@
+
+
+
+
+
+ /EIFGENs$
+ /CVS$
+ /.svn$
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/tutorial/step_2/hello/hello.ecf b/examples/tutorial/step_2/hello/hello.ecf
index 92b64bc2..9f85f9ad 100644
--- a/examples/tutorial/step_2/hello/hello.ecf
+++ b/examples/tutorial/step_2/hello/hello.ecf
@@ -7,14 +7,18 @@
/CVS$/.svn$
-
+
-
+
+
+
+
+
diff --git a/examples/tutorial/step_2/hello/src/custom_hello_application.e b/examples/tutorial/step_2/hello/src/custom_hello_application.e
new file mode 100644
index 00000000..701b91b9
--- /dev/null
+++ b/examples/tutorial/step_2/hello/src/custom_hello_application.e
@@ -0,0 +1,53 @@
+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.
+
+ ]"
+
+class
+ CUSTOM_HELLO_APPLICATION
+
+inherit
+ WSF_DEFAULT_RESPONSE_SERVICE
+ redefine
+ initialize
+ end
+
+create
+ make_and_launch
+
+feature {NONE} -- Initialization
+
+ initialize
+ do
+ --| Uncomment the following line, to be able to load options from the file ewf.ini
+-- create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} service_options.make_from_file ("ewf.ini")
+
+ --| 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)
+
+ --| Uncomment next line to have verbose option if available
+-- set_service_option ("verbose", True)
+
+ --| If you don't need any custom options, you are not obliged to redefine `initialize'
+ 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
diff --git a/examples/tutorial/step_2/hello/src/hello_application.e b/examples/tutorial/step_2/hello/src/hello_application.e
new file mode 100644
index 00000000..41f77b0a
--- /dev/null
+++ b/examples/tutorial/step_2/hello/src/hello_application.e
@@ -0,0 +1,31 @@
+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.
+
+ ]"
+
+class
+ HELLO_APPLICATION
+
+inherit
+ WSF_DEFAULT_RESPONSE_SERVICE
+
+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
diff --git a/examples/tutorial/step_3.wiki b/examples/tutorial/step_3.wiki
index d0c5dd9e..12fee144 100644
--- a/examples/tutorial/step_3.wiki
+++ b/examples/tutorial/step_3.wiki
@@ -1,2 +1,15 @@
-= Tutorial Step 3 =
+[[README.wiki|Back to tutorial index]]
+
+= Tutorial Step 3 =
+* '''Goal''': Build Hello $user application using form parameter as input
+* '''Requirements''':
+** know how to compile with Eiffel (EiffelStudio).
+** [[step_2.wiki|Previous step]] completed
+
+== "hello" project ==
+* Let's start from the "hello_custom" project
+* you will learn how to use the req: WSF_REQUEST argument
+
+----
+Previous [[step_2|step 2]] | Go to [[step_4.wiki|step 4]]
diff --git a/examples/tutorial/step_3/hello/ewf.ini b/examples/tutorial/step_3/hello/ewf.ini
new file mode 100644
index 00000000..fad6acb1
--- /dev/null
+++ b/examples/tutorial/step_3/hello/ewf.ini
@@ -0,0 +1,4 @@
+# For nino connector, use port 9999
+port=9999
+
+#verbose=true
diff --git a/examples/tutorial/step_3/hello/hello.ecf b/examples/tutorial/step_3/hello/hello.ecf
new file mode 100644
index 00000000..f91f78dc
--- /dev/null
+++ b/examples/tutorial/step_3/hello/hello.ecf
@@ -0,0 +1,20 @@
+
+
+
+
+
+ /EIFGENs$
+ /CVS$
+ /.svn$
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/tutorial/step_3/hello/src/hello_application.e b/examples/tutorial/step_3/hello/src/hello_application.e
new file mode 100644
index 00000000..01ec67ec
--- /dev/null
+++ b/examples/tutorial/step_3/hello/src/hello_application.e
@@ -0,0 +1,83 @@
+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.
+
+ ]"
+
+class
+ HELLO_APPLICATION
+
+inherit
+ WSF_DEFAULT_RESPONSE_SERVICE
+ redefine
+ initialize
+ end
+
+create
+ make_and_launch
+
+feature {NONE} -- Initialization
+
+ 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 f_user then
+ --| If yes, say hello world #name
+ Result.set_body ("Hello " + f_user.string + "!")
+ --| 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 ("[
+
+ ]"
+ )
+ 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
+ do
+ --| Uncomment the following line, to be able to load options from the file ewf.ini
+ create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} service_options.make_from_file ("ewf.ini")
+
+ --| 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)
+
+ --| Uncomment next line to have verbose option if available
+-- set_service_option ("verbose", True)
+
+ --| If you don't need any custom options, you are not obliged to redefine `initialize'
+ Precursor
+ end
+
+
+end