diff --git a/doc/workbook/basics/APPLICATION_EXECUTION.png b/doc/workbook/basics/APPLICATION_EXECUTION.png
deleted file mode 100644
index 270c78aa..00000000
Binary files a/doc/workbook/basics/APPLICATION_EXECUTION.png and /dev/null differ
diff --git a/doc/workbook/basics/Launcher Hierarchy.png b/doc/workbook/basics/Launcher Hierarchy.png
deleted file mode 100644
index d7c04723..00000000
Binary files a/doc/workbook/basics/Launcher Hierarchy.png and /dev/null differ
diff --git a/doc/workbook/basics/WSF_SERVICE_LAUNCHER_CGI.png b/doc/workbook/basics/WSF_SERVICE_LAUNCHER_CGI.png
deleted file mode 100644
index ba484064..00000000
Binary files a/doc/workbook/basics/WSF_SERVICE_LAUNCHER_CGI.png and /dev/null differ
diff --git a/doc/workbook/basics/WSF_SERVICE_LAUNCHER_FCGI.png b/doc/workbook/basics/WSF_SERVICE_LAUNCHER_FCGI.png
deleted file mode 100644
index b42d4b96..00000000
Binary files a/doc/workbook/basics/WSF_SERVICE_LAUNCHER_FCGI.png and /dev/null differ
diff --git a/doc/workbook/basics/WSF_SERVICE_LAUNCHER_NINO.png b/doc/workbook/basics/WSF_SERVICE_LAUNCHER_NINO.png
deleted file mode 100644
index ecca100e..00000000
Binary files a/doc/workbook/basics/WSF_SERVICE_LAUNCHER_NINO.png and /dev/null differ
diff --git a/doc/workbook/basics/WSF_SERVICE_LAUNCHER_STANDALONE.png b/doc/workbook/basics/WSF_SERVICE_LAUNCHER_STANDALONE.png
deleted file mode 100644
index c3eea2fb..00000000
Binary files a/doc/workbook/basics/WSF_SERVICE_LAUNCHER_STANDALONE.png and /dev/null differ
diff --git a/doc/workbook/basics/basics.md b/doc/workbook/basics/basics.md
deleted file mode 100644
index 2fc0e40f..00000000
--- a/doc/workbook/basics/basics.md
+++ /dev/null
@@ -1,214 +0,0 @@
-Nav: [Workbook](../workbook.md) :: [Handling Requests: Form/Query Parameter](../handling_request/form.md)
-
-
-## EWF basic service
-
-##### Table of Contents
-- [Basic Structure](#structure)
-- [Service to Generate Plain Text](#text)
- - [Source code](#source_1)
-- [Service to Generate HTML](#html)
- - [Source code](#source_2)
-
-
-
-
-## EWF service structure
-
-The following code describes the basic structure of an EWF basic service that handles HTTP requests. We will need to define a `Service Launcher` and a `Request Execution` implementation.
-
-```eiffel
-class
- APPLICATION
-
-inherit
- WSF_DEFAULT_SERVICE [APPLICATION_EXECUTION]
-
-create
- make_and_launch
-
-end
-```
-
-The class ```APPLICATION``` inherit from
-```WSF_DEFAULT_SERVICE [G ->WSF_EXECUTION create make end]``` it will be responsible to launch the service and set optional options.
-
-The class ```APPLICATION_EXECUTION``` is an implementation of ```WSF_EXECUTION``` interface, which is instantiated for each incoming request.
-
-```eiffel
-class
- APPLICATION_EXECUTION
-
-inherit
- WSF_EXECUTION
-
-create
- make
-
-feature -- Basic operations
-
- execute (req: WSF_REQUEST; res: WSF_RESPONSE)
- do
- -- To read incoming HTTP request, we need to use `req'
-
- -- May require talking to databases or other services.
-
- -- To send a response we need to setup, the status code and
- -- the response headers and the content we want to send out our client
- end
-end
-```
-
-When using the "standalone" connector (or the deprecated "nino" connector), by default the service listens on port 80, but often this port is already used by other applications, so it is recommended to use another port.
-To define another port, redefine the feature `initialize` and set up a new port number using the service options (see below).
-
-
-```eiffel
-class
- APPLICATION
-
-inherit
- WSF_DEFAULT_SERVICE [APPLICATION_EXECUTION]
- redefine
- initialize
- end
-
-create
- make_and_launch
-
-feature {NONE} -- Initialization
-
- initialize
- -- Initialize current service.
- do
- set_service_option ("port", 9090)
- end
-end
-```
-
-The **WSF_REQUEST** gives access to the incoming data; the class provides features to get information such as request method, form data, query parameters, uploaded files, HTTP request headers, and hostname of the client among others.
-
-The **WSF_RESPONSE** provides features to define the response with information such as HTTP status codes (10x,20x, 30x, 40x, and 50x), response headers (Content-Type, Content-Length, etc.) and obviously the body of the message itself.
-
-**APPLICATION** is the root class of our example, it launches the application, using the corresponding connector, Which connector? this depends how do you want to run it `cgi`, `fcgi`, `standalone`. For development is recommended to use a standalone web server written in Eiffel, and run the execution within the EiffelStudio debugger. For production fcgi (or cgi) using Apache or another popular web server.
-
-
-
-**WS_LAUNCHABLE_SERVICE** inherit from **WS_SERVICE** class, which is a marker interface in EWF. And also provides a way to launch our application using different kind of connectors. The class **WSF_DEFAULT_SERVICE_I**, inherit from **WS_LAUNCHABLE_SERVICE** and has a formal generic that should conform to **WSF_SERVICE_LAUNCHER [WSF_EXECUTION]**. Below a [BON diagram](http://www.bon-method.com/index_normal.htm) showing one of the possible options.
-
-
-Other connectors:
-
-**WSF_STANDALONE_SERVICE_LAUNCHER**
-**WSF_CGI_SERVICE_LAUNCHER**
-**WSF_LIBFCGI_SERVICE_LAUNCHER**
-
-A basic EWF service inherits from **WSF_DEFAULT_SERVICE**, which has a formal generic that should conform to **WSF_EXECUTION** class with a `make` creation procedure, in our case the class **APPLICATION_EXECUTION**.
-
-The **APPLICATION_EXECUTION** class inherits from **WSF_EXECUTION** interface, which is instantiated for each incoming request. **WSF_EXECUTION** inherit from **WGI_EXECUTION** which is the low level entry point in EWF, handling each incoming request with a single procedure ```execute (req: WSF_REQUEST; res: WSF_RESPONSE) ...```.
-
-In the **APPLICATION_EXECUTION** class class you will need to implement the **execute** feature, get data from the request *req* and write the response in *res*.
-
-
-
-The WSF_EXECUTION instance, in this case ```APPLICATION_EXECUTION``` is created per request, with two main attributes request: ```WSF_REQUEST``` and response: ```WSF_RESPONSE```.
-
-
-
-## A simple Service to Generate Plain Text.
-
-Before to continue, it is recommended to review the getting started guided. In the example we will only shows the implementation of the WSF_EXECUTION interface.
-
-```eiffel
-class
- APPLICATION_EXECUTION
-
-inherit
- WSF_EXECUTION
-
-create
- make
-
-feature -- Basic operations
-
- execute
- -- Execute the incomming request
- do
- -- To send a response we need to setup, the status code and
- -- the response headers.
- response.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/plain"], ["Content-Length", "11"]>>)
- response.put_string ("Hello World")
- end
-end
-
-```
-
-
-### Source code
-The source code is available on Github. You can get it by running the command:
-
-```git clone https://github.com/EiffelWebFramework/ewf.git```
-
-The example of simple service that generate plain text response is located in the directory $PATH/ewf/doc/workbook/basics/simple, where $PATH is where you run ```git clone``` .
-Just double click on the simple.ecf file and select the simple_standalone target or if you prefer the command line, run the command:
-
-```estudio -config simple.ecf -target simple_standalone```
-
-
-
-## A Service to Generate HTML.
-To generate HTML, it's needed
-
-1. Change the Content-Type : "text/html"
-2. Build an HTML page
-
-```eiffel
-class
- APPLICATION_EXECUTION
-
-inherit
- WSF_EXECUTION
-
-create
- make
-
-feature -- Basic operations
-
- execute
- -- Execute the incomming request
- do
- -- To send a response we need to setup, the status code and
- -- the response headers.
- response.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", web_page.count.out]>>)
- response.put_string (web_page)
- end
-
- web_page: STRING = "[
-
-
-
- Resume
-
-
- Hello World
-
-
-]"
-
-end
-```
-
-
-
-### Source code
-The source code is available on Github. You can get it by running the command:
-
-```git clone https://github.com/EiffelWebFramework/ewf.git```
-
-The example of the service that generates HTML is located in the directory $PATH/ewf/doc/workbook/basics/simple_html, where $PATH is where you run ```git clone``` .
-Just double click on the simple_html.ecf file and select the simple_html_standalone target or if you prefer the command line, run the command:
-
-```estudio -config simple_html.ecf -target simple_html_standalone```
-
-Nav: [Workbook](../workbook.md) :: [Handling Requests: Form/Query Parameter](../handling_request/form.md)
-
diff --git a/doc/workbook/basics/simple/application.e b/doc/workbook/basics/simple/application.e
deleted file mode 100644
index cf939f60..00000000
--- a/doc/workbook/basics/simple/application.e
+++ /dev/null
@@ -1,24 +0,0 @@
-note
- description: "Basic Service launcher"
-
-class
- APPLICATION
-
-inherit
- WSF_DEFAULT_SERVICE [APPLICATION_EXECUTION]
- redefine
- initialize
- end
-
-create
- make_and_launch
-
-feature {NONE} -- Initialization
-
- initialize
- -- Initialize current service.
- do
- set_service_option ("port", 9090)
- end
-
-end
diff --git a/doc/workbook/basics/simple/application_execution.e b/doc/workbook/basics/simple/application_execution.e
deleted file mode 100644
index 58917ef8..00000000
--- a/doc/workbook/basics/simple/application_execution.e
+++ /dev/null
@@ -1,25 +0,0 @@
-note
- description : "Basic Service that Generates Plain Text"
- date : "$Date$"
- revision : "$Revision$"
-
-class
- APPLICATION_EXECUTION
-
-inherit
- WSF_EXECUTION
-
-create
- make
-
-feature -- Basic operations
-
- execute
- -- Execute the incomming request
- do
- -- To send a response we need to setup, the status code and
- -- the response headers.
- response.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/plain"], ["Content-Length", "11"]>>)
- response.put_string ("Hello World")
- end
-end
diff --git a/doc/workbook/basics/simple/simple.ecf b/doc/workbook/basics/simple/simple.ecf
deleted file mode 100644
index e4ff832f..00000000
--- a/doc/workbook/basics/simple/simple.ecf
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
- /.svn$
- /CVS$
- /EIFGENs$
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/workbook/basics/simple_html/apache_config/Readme.md b/doc/workbook/basics/simple_html/apache_config/Readme.md
deleted file mode 100644
index c2fd0777..00000000
--- a/doc/workbook/basics/simple_html/apache_config/Readme.md
+++ /dev/null
@@ -1,61 +0,0 @@
-Nav: [Workbook](../../../workbook.md) :: [Basic concepts](../../../basics/basics.md)
-
-## Run simple_html example on Apache with FCGI on Windows.
-
-
-#### Prerequisites
-
-* This tutorial was written for people working under Windows environment, and using Apache Server with FCGI connector
-* Compile the ewf application from command line.
-* Assuming you have installed Apache Server under `C:/home/server/Apache24`.
-* Assuming you have placed your current project under `C:/home/server/Apache24/fcgi-bin`.
-* Assuming you have setted the Listen to `8888`, the defautl value is `80` .
-
-
-
-#### FCGI module
-If you don't have the FCGI module installed, you can get it from https://www.apachelounge.com/download/, download the module based on your platform [modules-2.4-win64-VC11.zip](https://www.apachelounge.com/download/VC11/modules/modules-2.4-win64-VC11.zip) or [modules-2.4-win32-VC11.zip](https://www.apachelounge.com/download/VC11/modules/modules-2.4-win32-VC11.zip), uncompress it
-and copy the _mod_fcgid.so_ to `C:/home/server/Apache24/modules`
-
-#### Compile the project simple_html using the fcgi connector.
-
- ec -config simple_html.ecf -target simple_html_fcgi -finalize -c_compile -project_path .
-
-Copy the genereted exe to `C:/home/server/Apache24/fcgi-bin` folder.
-
-Check if you have _libfcgi.dll_ in your PATH.
-
-
-#### Apache configuration
-Add to httpd.conf the content, you can get the configuration file [here](config.conf)
-
-```
-LoadModule fcgid_module modules/mod_fcgid.so
-
-
-
- SetHandler fcgid-script
- Options +ExecCGI +Includes +FollowSymLinks -Indexes
- AllowOverride All
- Require all granted
-
- ScriptAlias /simple "C:/home/server/Apache24/fcgi-bin/simple_html.exe"
-
-```
-
-Test if your httpd.conf is ok
-```
-> httpd -t
-```
-
-Launch the server
-```
-> httpd
-```
-
-Check the application
-```
-> http://localhost:8888/simple
-```
-
-Nav: [Workbook](../../../workbook.md) :: [Basic concepts](../../../basics/basics.md)
diff --git a/doc/workbook/basics/simple_html/apache_config/config.conf b/doc/workbook/basics/simple_html/apache_config/config.conf
deleted file mode 100644
index f41212d2..00000000
--- a/doc/workbook/basics/simple_html/apache_config/config.conf
+++ /dev/null
@@ -1,12 +0,0 @@
-LoadModule fcgid_module modules/mod_fcgid.so
-
-
-
- SetHandler fcgid-script
- Options +ExecCGI +Includes +FollowSymLinks -Indexes
- AllowOverride All
- Require all granted
-
- ScriptAlias /simple "C:/home/server/Apache24/fcgi-bin/simple_html.exe"
-
-
diff --git a/doc/workbook/basics/simple_html/application.e b/doc/workbook/basics/simple_html/application.e
deleted file mode 100644
index cf939f60..00000000
--- a/doc/workbook/basics/simple_html/application.e
+++ /dev/null
@@ -1,24 +0,0 @@
-note
- description: "Basic Service launcher"
-
-class
- APPLICATION
-
-inherit
- WSF_DEFAULT_SERVICE [APPLICATION_EXECUTION]
- redefine
- initialize
- end
-
-create
- make_and_launch
-
-feature {NONE} -- Initialization
-
- initialize
- -- Initialize current service.
- do
- set_service_option ("port", 9090)
- end
-
-end
diff --git a/doc/workbook/basics/simple_html/application_execution.e b/doc/workbook/basics/simple_html/application_execution.e
deleted file mode 100644
index 63204435..00000000
--- a/doc/workbook/basics/simple_html/application_execution.e
+++ /dev/null
@@ -1,66 +0,0 @@
-note
- description : "Basic Service that Generate HTML"
- date : "$Date$"
- revision : "$Revision$"
-
-class
- APPLICATION_EXECUTION
-
-inherit
- WSF_EXECUTION
-
-create
- make
-
-feature -- Basic operations
-
- execute
- -- Execute the incomming request
- do
- -- To send a response we need to setup, the status code and
- -- the response headers.
- response.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", web_page.count.out]>>)
- response.put_string (web_page)
- end
-
-
- web_page: STRING = "[
-
-
-
- Resume
-
-
-
Junior Developer, Software Company (2010 - Present)
-
-
Designed and implemented end-user features for Flagship Product
-
Wrote third-party JavaScript and Eiffel libraries
-
-
Skills
-
Languages: C#, JavaScript, Python, Ruby, Eiffel
-
Frameworks: .NET, Node.js, Django, Ruby on Rails, EWF
-
Education
-
BS, Economics, My University
-
-
Award for best senior thesis
-
GPA: 3.8
-
-
-
-
-
-]"
-
-
-end
diff --git a/doc/workbook/basics/simple_html/simple_html.ecf b/doc/workbook/basics/simple_html/simple_html.ecf
deleted file mode 100644
index 5712125d..00000000
--- a/doc/workbook/basics/simple_html/simple_html.ecf
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
- /.svn$
- /CVS$
- /EIFGENs$
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/workbook/deployment/readme.md b/doc/workbook/deployment/readme.md
deleted file mode 100644
index 8e8afd6a..00000000
--- a/doc/workbook/deployment/readme.md
+++ /dev/null
@@ -1,198 +0,0 @@
-Nav: [Workbook](../workbook.md)
-
-EWF Deployment
-==============
-
-# Apache on Windows#
-
-1. Apache Install
-2. Deploying EWF CGI
-3. CGI overview
- 1. Build EWF application
- 2. Copy the generated exe file and the www content .htaccess CGI
-4. Deploying EWF FCGI
-5. FCGI overview
- 1. Build EWF application
- 2. Copy the generated exe file and the www content.htaccess CGI
-
-
-
-## Apache on Windows
-
-### Apache Install
-
->Check the correct version (Win 32 or Win64)
->Apache Version: Apache 2.4.4
->Windows: http://www.apachelounge.com/download/
-
-note: on linux (debian), use
-> sudo apt-get install apache2
-
-#### Deploying EWF CGI
-
-#### CGI overview
->A new process is started for each HTTP request. So if there are N requests to the same
->CGI program, the code of the CGI program is loaded into memory N times.
->When a CGI program finishes handling a request, the program terminates.
-
-* Build EWF application
-
-```ec -config [app.ecf] -target [app_cgi] -finalize -c_compile -project_path```
-
-
->Note: change app.ecf and target app_cgi based on your own configuration.
-
-* Copy the generated exe file and the www content
-
-Copy the app.exe and the folder _www_ into a folder served by apache2, for example under.
-
-
-```
- /htdocs.
-
- = path to your apache installation
-
- Edit httpd.conf under c://conf
-
- DocumentRoot "c://htdocs"
-
- /htdocs">
- AllowOverride All --
- Require all granted -- this is required in Apache 2.4.4
-
-```
-
-Check that you have the following modules enabled
-
-```
- LoadModule cgi_module modules/mod_cgi.so
- LoadModule rewrite_module modules/mod_rewrite.so
-```
-
-#### Tip:
->To check the syntax of your httpd.conf file. From command line run the following
-
- $>httpd - t
-
-
->.htaccess CGI
- http://perishablepress.com/stupid-htaccess-tricks/
-
-#### .htaccess
-
-```
- Options +ExecCGI +Includes +FollowSymLinks -Indexes
- AddHandler cgi-script exe
-
-
- RewriteEngine on
-
- RewriteRule ^$ $service [L]
-
- RewriteCond %{REQUEST_FILENAME} !-f
- RewriteCond %{REQUEST_FILENAME} !-d
- RewriteCond %{REQUEST_URI} !$service
- RewriteRule ^(.*)$ $service/$1
-
- RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
-
-```
-
->Replace $service with the name of your executable service, for example app_service.exe
-
-
-#### Deploying EWF FCGI
->To deploy FCGI you will need to download the mod_fcgi module.
->You can get it from here http://www.apachelounge.com/download/
-
-note: on linux (debian), use
-> sudo apt-get install libapache2-mod-fastcgi
-
-#### FCGI overview
->FastCGI allows a single, long-running process to handle more than one user request while keeping close to the CGI programming model, retaining the simplicity while eliminating the overhead of creating a new process for each request. Unlike converting an application to a web server plug-in, FastCGI applications remain independent of the web server.
-
-* Build EWF application
-
-``` ec -config [app.ecf] -target [app_fcgi] -finalize -c_compile -project_path .```
-
->Note: change app.ecf and target app_fcgi based on your own configuration.
-
-* Copy the generated exe file and the www content
-
-Copy the app.exe and the folder "www" into a folder served by apache2, for example under
-
-```
- /htdocs.
-
- = path to your apache installation
-
- Edit httpd.conf under c://conf
-
- DocumentRoot "c://htdocs"
-
- /htdocs">
- AllowOverride All --
- Require all granted -- this is required in Apache 2.4.4
-
-```
-
->Check that you have the following modules enabled
-
- LoadModule rewrite_module modules/mod_rewrite.so
- LoadModule fcgid_module modules/mod_fcgid.so
-
->NOTE: By default Apache does not come with fcgid module, so you will need to download it, and put the module under Apache2/modules
-
-It is also possible to set various parameters in the apache site configuration file such as:
-```
-
- # FcgidIdleTimeout 600
- # FcgidBusyScanInterval 120
- # FcgidProcessLifeTime 3600
- # FcgidMaxProcesses 5
- # FcgidMaxProcessesPerClass 100
- # FcgidMinProcessesPerClass 100
- # FcgidConnectTimeout 8
- # FcgidIOTimeout 60
- # FcgidBusyTimeout 1200
-
-```
-See https://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html for more information.
-
-# .htaccess FCGI
-
-```
-http://perishablepress.com/stupid-htaccess-tricks/
-```
-
-#### .htaccess
-```
- Options +ExecCGI +Includes +FollowSymLinks -Indexes
-
-
- AddHandler fcgid-script .ews
- FcgidWrapper $FULL_PATH/$service .ews
-
-
-
-
- RewriteEngine on
-
- RewriteBase /
- RewriteRule ^$ service.ews [L]
-
- RewriteCond %{REQUEST_FILENAME} !-f
- RewriteCond %{REQUEST_FILENAME} !-d
- RewriteCond %{REQUEST_URI} !=/favicon.ico
- RewriteCond %{REQUEST_URI} !service.ews
- RewriteRule ^(.*)$ service.ews/$1
-
-
- RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
-
-```
-
-Replace $service with the name of your executable $service, for example app_service.exe
-You will need to create an service.ews file, this file will be located at the same place where you copy your app service executable.
-
-Nav: [Workbook](../workbook.md)
diff --git a/doc/workbook/generating_response/exel/application.e b/doc/workbook/generating_response/exel/application.e
deleted file mode 100644
index cf939f60..00000000
--- a/doc/workbook/generating_response/exel/application.e
+++ /dev/null
@@ -1,24 +0,0 @@
-note
- description: "Basic Service launcher"
-
-class
- APPLICATION
-
-inherit
- WSF_DEFAULT_SERVICE [APPLICATION_EXECUTION]
- redefine
- initialize
- end
-
-create
- make_and_launch
-
-feature {NONE} -- Initialization
-
- initialize
- -- Initialize current service.
- do
- set_service_option ("port", 9090)
- end
-
-end
diff --git a/doc/workbook/generating_response/exel/application_execution.e b/doc/workbook/generating_response/exel/application_execution.e
deleted file mode 100644
index 3c93fb5a..00000000
--- a/doc/workbook/generating_response/exel/application_execution.e
+++ /dev/null
@@ -1,36 +0,0 @@
-note
- description : "Basic Service that show how to use common Status Code"
- date : "$Date$"
- revision : "$Revision$"
-
-class
- APPLICATION_EXECUTION
-
-inherit
- WSF_EXECUTION
-
-create
- make
-
-feature -- Basic operations
-
- execute
- -- Execute the incomming request
- do
- -- To send a response we need to setup, the status code and
- -- the response headers.
- response.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/csv"],["Content-Disposition","attachment;filename=Report.xls"],["Content-Length", sheet.count.out]>>)
- response.put_string (sheet)
- end
-
- -- ,["Content-Disposition","attachment;filename=Report.xls"]
-
-
- sheet: STRING ="[
- Q1 Q2 Q3 Q4 Total
-Cherries 78 87 92 29 =SUM(B2:E2)
-Grapes 77 86 93 30 =SUM(B3:E3)
- ]"
-
-
-end
diff --git a/doc/workbook/generating_response/exel/exel.ecf b/doc/workbook/generating_response/exel/exel.ecf
deleted file mode 100644
index e16eb9f7..00000000
--- a/doc/workbook/generating_response/exel/exel.ecf
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
- /.svn$
- /CVS$
- /EIFGENs$
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/workbook/generating_response/generating_response.md b/doc/workbook/generating_response/generating_response.md
deleted file mode 100644
index c6d4fcd4..00000000
--- a/doc/workbook/generating_response/generating_response.md
+++ /dev/null
@@ -1,1007 +0,0 @@
-
-Nav: [Workbook](../workbook.md) :: [Handling Requests: Header Fields](../handling_request/headers.md) :: [Handling Cookies](../handling_cookies/handling_cookies.md)
-
-
-## EWF Generating Response
-
-##### Table of Contents
-- [Format of the HTTP response](#format)
-- [How to set status code](#status_set)
-- [How to redirect to a particular location.](#redirect)
-- [HTTP Status codes](#status)
-- [Example Staus Codes](#example_1)
-- [Generic Search Engine](#example_2)
-- [Response Header Fields](#header_fields)
-
-
-
-
-## Format of the HTTP response
-
-As we saw in the previous documents, a request from a user-agent (browser or other client) consists of an HTTP command (usually GET or POST), zero or more request headers (one or more in HTTP 1.1, since Host is required), a blank line, and only in the case of POST/PUT requests, payload data. A typical request looks like the following.
-
-```
- GET /url[query_string] HTTP/1.1
- Host: ...
- Header2: ...
- ...
- HeaderN:
- (Blank Line)
-```
-
-When a Web server responds to a request, the response typically consists of a status line, some response headers, a blank line, and the document. A typical response
-looks like this:
-
-```
- HTTP/1.1 200 OK
- Content-Type: text/html
- Header2: ...
- ...
- HeaderN: ...
- (Blank Line)
-
-
- ...
-
- ...
-
-
-```
-
-The status line consists of the HTTP version (HTTP/1.1 in the preceding example), a status code (an integer 200 in the example), and a very short message corresponding to the status code (OK in the example). In most cases, the headers are optional except for Content-Type, which specifies the MIME type of the document that follows. Although most responses contain a document, some don’t. For example, responses to HEAD requests should never include a document, and various status codes essentially indicate failure or redirection (and thus either don’t include a document or include only a short error-message document).
-
-
-
-## How to set the status code
-
-If you need to set an arbitrary status code, you can use the ```WSF_RESPONSE.put_header``` feature or the ```WSF_RESPONSE.set_status_code``` feature. An status code of 200 is a default value. See below examples using the mentioned features.
-
-### Using the WSF_RESPONSE.put_header feature.
-In this case you provide the status code with a collection of headers.
-
-```eiffel
- put_header (a_status_code: INTEGER_32; a_headers: detachable ARRAY [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]])
- -- Put headers with status `a_status', and headers from `a_headers'
- require
- a_status_code_valid: a_status_code > 0
- status_not_committed: not status_committed
- header_not_committed: not header_committed
- ensure
- status_code_set: status_code = a_status_code
- status_set: status_is_set
- message_writable: message_writable
-
-Example
- res.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", output_size]>>)
- res.put_string (web_page)
-```
-
-### Using the WSF_RESPONSE.set_status code
-
-```eiffel
- custom_response (req: WSF_REQUEST; res: WSF_RESPONSE; output: STRING)
- local
- h: HTTP_HEADER
- l_msg: STRING
- do
- create h.make
- create l_msg.make_from_string (output)
- h.put_content_type_text_html
- h.put_content_length (l_msg.count)
- h.put_current_date
- res.set_status_code ({HTTP_STATUS_CODE}.ok)
- res.put_header_text (h.string)
- res.put_string (l_msg)
- end
-```
-Both features takes an INTEGER (the status code) as an formal argument, you can use 200, 300, 500 etc directly, but instead of using explicit numbers, it's recommended to use the constants defined in the class `HTTP_STATUS_CODE`. The name of each constant is based from the standard [HTTP 1.1](https://httpwg.github.io/).
-
-
-
-## How to redirect to a particular location.
-To redirect the response to a new location, we need to send a 302 status code, to do that we use ```{HTTP_STATUS_CODE}.found```
-
-> The 302 (Found) status code indicates that the target resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client ought to continue to use the effective request URI for future requests.
-
-Another way to do redirection is with 303 status code
-
-> The 303 (See Other) status code indicates that the server is redirecting the user agent to a different resource, as indicated by a URI in the Location header field, which is intended to provide an indirect response to the original request.
-
-The next code show a custom feature to write a redirection, you can use found or see_other based on your particular requirements.
-
-```eiffel
- send_redirect (req: WSF_REQUEST; res: WSF_RESPONSE; a_location: READABLE_STRING_32)
- -- Redirect to `a_location'
- local
- h: HTTP_HEADER
- do
- create h.make
- h.put_content_type_text_html
- h.put_current_date
- h.put_location (a_location)
- res.set_status_code ({HTTP_STATUS_CODE}.found)
- res.put_header_text (h.string)
- end
-```
-
-The class `WSF_RESPONSE` provide features to work with redirection
-
-```eiffel
- redirect_now (a_url: READABLE_STRING_8)
- -- Redirect to the given url `a_url'
- require
- header_not_committed: not header_committed
-
- redirect_now_custom (a_url: READABLE_STRING_8; a_status_code: INTEGER_32; a_header: detachable HTTP_HEADER; a_content: detachable TUPLE [body: READABLE_STRING_8; type: READABLE_STRING_8])
- -- Redirect to the given url `a_url' and precise custom `a_status_code', custom header and content
- -- Please see http://www.faqs.org/rfcs/rfc2616 to use proper status code.
- -- if `a_status_code' is 0, use the default {HTTP_STATUS_CODE}.temp_redirect
- require
- header_not_committed: not header_committed
-
- redirect_now_with_content (a_url: READABLE_STRING_8; a_content: READABLE_STRING_8; a_content_type: READABLE_STRING_8)
- -- Redirect to the given url `a_url'
-```
-
-The ```WSF_RESPONSE.redirect_now``` feature use the status code ```{HTTP_STATUS_CODE}.found```,the other redirect features enable customize the status code and content based on your requirements.
-
-
-Using a similar approach we can build features to answer a bad request (400), internal server error (500), etc. We will build a simple example showing the most common HTTP status codes.
-
-
-
-## [HTTP 1.1 Status Codes](https://httpwg.github.io/specs/rfc7231.html#status.codes)
-The status-code element is a three-digit integer code giving the result of the attempt to understand and satisfy the request. The first digit of the status-code defines the class of response.
-
-General categories:
-* [1xx](https://httpwg.github.io/specs/rfc7231.html#status.1xx) Informational: The 1xx series of response codes are used only in negotiations with the HTTP server.
-* [2xx](https://httpwg.github.io/specs/rfc7231.html#status.2xx) Sucessful: The 2xx error codes indicate that an operation was successful.
-* [3xx](https://httpwg.github.io/specs/rfc7231.html#status.3xx) Redirection: The 3xx status codes indicate that the client needs to do some extra work to get what it wants.
-* [4xx](https://httpwg.github.io/specs/rfc7231.html#status.4xx) Client Error: These status codes indicate that something is wrong on the client side.
-* [5xx](https://httpwg.github.io/specs/rfc7231.html#status.5xx) Server Error: These status codes indicate that something is wrong on the server side.
-
-Note: use ```res.set_status_code({HTTP_STATUS_CODE}.bad_request)``` rather than ```res.set_status_code(400)```.
-
-
-
-
-### Example Staus Codes
-Basic Service that builds a simple web page to show the most common status codes
-```eiffel
-class
- APPLICATION_EXECUTION
-
-inherit
- WSF_EXECUTION
-
-create
- make
-
-feature -- Basic operations
-
- execute (req: WSF_REQUEST; res: WSF_RESPONSE)
- -- Execute the incomming request
- local
- l_message: STRING
- do
- -- To send a response we need to setup, the status code and
- -- the response headers.
- if req.is_get_request_method then
- if req.path_info.same_string ("/") then
- res.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", web_page.count.out]>>)
- res.put_string (web_page)
- elseif req.path_info.same_string ("/redirect") then
- send_redirect (req, res, "https://httpwg.github.io/")
- -- res.redirect_now (l_engine_url)
- elseif req.path_info.same_string ("/bad_request") then
- -- Here you can do some logic for example log, send emails to register the error, before to send the response.
- create l_message.make_from_string (message_template)
- l_message.replace_substring_all ("$title", "Bad Request")
- l_message.replace_substring_all ("$status", "Bad Request 400")
- res.put_header ({HTTP_STATUS_CODE}.bad_request, <<["Content-Type", "text/html"], ["Content-Length", l_message.count.out]>>)
- res.put_string (l_message)
- elseif req.path_info.same_string ("/internal_error") then
- -- Here you can do some logic for example log, send emails to register the error, before to send the response.
- create l_message.make_from_string (message_template)
- l_message.replace_substring_all ("$title", "Internal Server Error")
- l_message.replace_substring_all ("$status", "Internal Server Error 500")
- res.put_header ({HTTP_STATUS_CODE}.internal_server_error, <<["Content-Type", "text/html"], ["Content-Length", l_message.count.out]>>)
- res.put_string (l_message)
- else
- create l_message.make_from_string (message_template)
- l_message.replace_substring_all ("$title", "Resource not found")
- l_message.replace_substring_all ("$status", "Resource not found 400")
- res.put_header ({HTTP_STATUS_CODE}.not_found, <<["Content-Type", "text/html"], ["Content-Length", l_message.count.out]>>)
- res.put_string (l_message)
- end
- else
- create l_message.make_from_string (message_template)
- l_message.replace_substring_all ("$title", "Method Not Allowed")
- l_message.replace_substring_all ("$status", "Method Not Allowed 405")
- -- Method not allowed
- res.put_header ({HTTP_STATUS_CODE}.method_not_allowed, <<["Content-Type", "text/html"], ["Content-Length", l_message.count.out]>>)
- res.put_string (l_message)
- end
- end
-
-
-feature -- Home Page
-
- send_redirect (req: WSF_REQUEST; res: WSF_RESPONSE; a_location: READABLE_STRING_32)
- -- Redirect to `a_location'
- local
- h: HTTP_HEADER
- do
- create h.make
- h.put_content_type_text_html
- h.put_current_date
- h.put_location (a_location)
- res.set_status_code ({HTTP_STATUS_CODE}.see_other)
- res.put_header_text (h.string)
- end
-
- web_page: STRING = "[
-
-
-
- Example showing common status codes
-
-
-
-
Use a tool to see the request and header details, for example (Developers tools in Chrome or Firebugs in Firefox)
-
-
-
-
This page is an example of Status Code 200
-
-
Redirect Example
-
Click on the following link will redirect you to the HTTP Specifcation, we can do the redirect from the HTML directly but
- here we want to show you an exmaple, where you can do something before to send a redirect Redirect
-
-
Bad Request
-
Click on the following link, the server will answer with a 400 error, check the status code Bad Request
-
-
Internal Server Error
-
Click on the following link, the server will answer with a 500 error, check the status code Internal Error
-
-
Resource not found
-
Click on the following link or add to the end of the url something like /1030303 the server will answer with a 404 error, check the status code Not found
Use a tool to see the request and header details, for example (Developers tools in Chrome or Firebugs in Firefox)
-
-
-
-
This page is an example of $status
-
-
-
-
-]"
-end
-
-```
-
-
-
-
-
-### Example Generic Search Engine
-The following example shows a basic EWF service that builds a generic front end for the most used search engines. This example shows how
-redirection works, and we will use a tools to play with the API to show differents responses.
-
-```eiffel
-note
- description : "Basic Service that build a generic front end for the most used search engines."
- date : "$Date$"
- revision : "$Revision$"
-
-class
- APPLICATION_EXECUTION
-
-inherit
- WSF_EXECUTION
-
-create
- make
-
-feature -- Basic operations
-
- execute (req: WSF_REQUEST; res: WSF_RESPONSE)
- -- Execute the incomming request
- local
- l_message: STRING
- do
- -- To send a response we need to setup, the status code and
- -- the response headers.
- if req.is_get_request_method then
- if req.path_info.same_string ("/") then
- res.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", web_page.count.out]>>)
- res.put_string (web_page)
- else
- send_resouce_not_found (req, res)
- end
- elseif req.is_post_request_method then
- if req.path_info.same_string ("/search") then
- if attached {WSF_STRING} req.form_parameter ("query") as l_query then
- if attached {WSF_STRING} req.form_parameter ("engine") as l_engine then
- if attached {STRING} map.at (l_engine.value) as l_engine_url then
- l_engine_url.append (l_query.value)
- send_redirect (req, res, l_engine_url)
- else
- send_bad_request (req, res, " search engine: " + l_engine.value + " not supported, try with Google or Bing")
- end
- else
- send_bad_request (req, res, " search engine not selected")
- end
- else
- send_bad_request (req, res, " form_parameter query is not present")
- end
- else
- send_resouce_not_found (req, res)
- end
- else
- create l_message.make_from_string (message_template)
- l_message.replace_substring_all ("$title", "Method Not Allowed")
- l_message.replace_substring_all ("$status", "Method Not Allowed 405")
- -- Method not allowed
- res.put_header ({HTTP_STATUS_CODE}.method_not_allowed, <<["Content-Type", "text/html"], ["Content-Length", l_message.count.out]>>)
- res.put_string (l_message)
- end
- end
-
-
-feature -- Engine Map
-
- map : STRING_TABLE[STRING]
- do
- create Result.make (2)
- Result.put ("http://www.google.com/search?q=", "Google")
- Result.put ("http://www.bing.com/search?q=", "Bing")
- end
-
-feature -- Redirect
-
- send_redirect (req: WSF_REQUEST; res: WSF_RESPONSE; a_location: READABLE_STRING_32)
- -- Redirect to `a_location'
- local
- h: HTTP_HEADER
- do
- create h.make
- h.put_content_type_text_html
- h.put_current_date
- h.put_location (a_location)
- res.set_status_code ({HTTP_STATUS_CODE}.see_other)
- res.put_header_text (h.string)
- end
-
-feature -- Bad Request
-
- send_bad_request (req: WSF_REQUEST; res: WSF_RESPONSE; description: STRING)
- local
- l_message: STRING
- do
- create l_message.make_from_string (message_template)
- l_message.replace_substring_all ("$title", "Bad Request")
- l_message.replace_substring_all ("$status", "Bad Request" + description)
- res.put_header ({HTTP_STATUS_CODE}.bad_request, <<["Content-Type", "text/html"], ["Content-Length", l_message.count.out]>>)
- res.put_string (l_message)
- end
-
-feature -- Resource not found
-
- send_resouce_not_found (req: WSF_REQUEST; res: WSF_RESPONSE)
- local
- l_message: STRING
- do
- create l_message.make_from_string (message_template)
- l_message.replace_substring_all ("$title", "Resource not found")
- l_message.replace_substring_all ("$status", "Resource" + req.request_uri + "not found 404")
- res.put_header ({HTTP_STATUS_CODE}.not_found, <<["Content-Type", "text/html"], ["Content-Length", l_message.count.out]>>)
- res.put_string (l_message)
- end
-
-feature -- Home Page
-
- web_page: STRING = "[
-
-
-
- Generic Search Engine
-
-
-
Use a tool to see the request and header details, for example (Developers tools in Chrome or Firebugs in Firefox)
-
-
-
-
This page is an example of $status
-
-
-
-
-]"
-
-end
-
-```
-
-Using cURL to test the application
----
-
-In the first call we use the ```res.redirect_now (l_engine_url)``` feature
-```
-#>curl -i -H -v -X POST -d "query=Eiffel&engine=Google" http://localhost:9090/search
-HTTP/1.1 302 Found
-Location: http://www.google.com/search?q=Eiffel
-Content-Length: 0
-Connection: close
-```
-
-Here we use our custom send_redirect feature call.
-
-```
-#>curl -i -H -v -X POST -d "query=Eiffel&engine=Google" http://localhost:9090/search
-HTTP/1.1 303 See Other
-Content-Type: text/html
-Date: Fri, 06 Mar 2015 14:37:33 GMT
-Location: http://www.google.com/search?q=Eiffel
-Connection: close
-```
-
-#### Engine Ask Not supported
-
-```
-#>curl -i -H -v -X POST -d "query=Eiffel&engine=Ask" http://localhost:9090/search
-HTTP/1.1 400 Bad Request
-Content-Type: text/html
-Content-Length: 503
-Connection: close
-
-
-
-
- Bad Request
-
-
-
-
Use a tool to see the request and header details, for example (Developers tools in Chrome or Firebugs in Firefox)
-
-
-
-
This page is an example of Bad Request search engine: Ask not supported, try with Google or Bing
-
-
-
-
-```
-
-
-#### Missing query form parameter
-
-```
-#>curl -i -H -v -X POST -d "engine=Google" http://localhost:9090/search
-HTTP/1.1 400 Bad Request
-Content-Type: text/html
-Content-Length: 477
-Connection: close
-
-
-
-
- Bad Request
-
-
-
-
Use a tool to see the request and header details, for example (Developers tools in Chrome or Firebugs in Firefox)
-
-
-
-
This page is an example of Bad Request form_parameter query is not present
-
-
-
-
-```
-
-#### Resource searchs not found
-
-```
-#>curl -i -H -v -X POST -d "query=Eiffel&engine=Google" http://localhost:9090/searchs
-HTTP/1.1 404 Not Found
-Content-Type: text/html
-Content-Length: 449
-Connection: close
-
-
-
-
- Resource not found
-
-
-
-
Use a tool to see the request and header details, for example (Developers tools in Chrome or Firebugs in Firefox)
-
-
-
-
This page is an example of Resource /searchs not found 404
-
-
-
-
-```
-
-
-
-## [Response Header Fields](https://httpwg.github.io/specs/rfc7231.html#response.header.fields)
-
-The response header fields allow the server to pass additional information about the response beyond what is placed in the status-line. These header fields give information about the server, about further access to the target resource, or about related resources. We can specify cookies, page modification date (for caching), reload a page after a designated period of time, size of the document.
-
-
-
-### How to set response headers.
-
-HTTP allows multiple occurrences of the same header name, the features ```put_XYZ``` replace existing headers with the same name and
-features ```add_XYZ``` add headers that can lead to duplicated entries.
-
-
-```eiffel
- add_header_line (h: READABLE_STRING_8)
- -- Add header `h'
- -- This can lead to duplicated header entries
- require
- header_not_committed: not header_committed
-
- add_header_text (a_text: READABLE_STRING_8)
- -- Add the multiline header `a_text'
- -- Does not replace existing header with same name
- -- This could leads to multiple header with the same name
- require
- header_not_committed: not header_committed
- a_text_ends_with_single_crlf: a_text.count > 2 implies not a_text.substring (a_text.count - 2, a_text.count).same_string ("%R%N")
- a_text_does_not_end_with_double_crlf: a_text.count > 4 implies not a_text.substring (a_text.count - 4, a_text.count).same_string ("%R%N%R%N")
- ensure
- status_set: status_is_set
- message_writable: message_writable
-
- put_header_line (h: READABLE_STRING_8)
- -- Put header `h'
- -- Replace any existing value
- require
- header_not_committed: not header_committed
-
- put_header_text (a_text: READABLE_STRING_8)
- -- Put the multiline header `a_text'
- -- Overwite potential existing header
- require
- header_not_committed: not header_committed
- a_text_ends_with_single_crlf: a_text.count > 2 implies not a_text.substring (a_text.count - 2, a_text.count).same_string ("%R%N")
- a_text_does_not_end_with_double_crlf: a_text.count > 4 implies not a_text.substring (a_text.count - 4, a_text.count).same_string ("%R%N%R%N")
- ensure
- message_writable: message_writable
-
-helpers
-
- add_header (a_status_code: INTEGER_32; a_headers: detachable ARRAY [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]])
- -- Put headers with status `a_status', and headers from `a_headers'
- require
- a_status_code_valid: a_status_code > 0
- status_not_committed: not status_committed
- header_not_committed: not header_committed
- ensure
- status_code_set: status_code = a_status_code
- status_set: status_is_set
- message_writable: message_writable
-
- add_header_lines (a_lines: ITERABLE [READABLE_STRING_8])
- -- Add headers from `a_lines'
- require
- header_not_committed: not header_committed
-
- put_header (a_status_code: INTEGER_32; a_headers: detachable ARRAY [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]])
- -- Put headers with status `a_status', and headers from `a_headers'
- require
- a_status_code_valid: a_status_code > 0
- status_not_committed: not status_committed
- header_not_committed: not header_committed
- ensure
- status_code_set: status_code = a_status_code
- status_set: status_is_set
- message_writable: message_writable
-
- put_header_lines (a_lines: ITERABLE [READABLE_STRING_8])
- -- Put headers from `a_lines'
- require
- header_not_committed: not header_committed
-
-```
-
-The other way to build headers is using the class `HTTP_HEADER`, that provide routines to build a header. It's recomended to
-take a look at constants classes such as `HTTP_MIME_TYPES`,`HTTP_HEADER_NAMES`,`HTTP_STATUS_CODE`,`HTTP_REQUEST_METHODS`, or
-`HTTP_CONSTANTS` which groups them for convenience.
-
-
-```eiffel
- custom_answer (req: WSF_REQUEST; res: WSF_RESPONSE; output: STRING)
- local
- h: HTTP_HEADER
- l_msg: STRING
- do
- create h.make
- create l_msg.make_from_string (output)
- h.put_content_type_text_html
- h.put_content_length (l_msg.count)
- h.put_current_date
- res.set_status_code ({HTTP_STATUS_CODE}.bad_gateway)
- res.put_header_text (h.string)
- res.put_string (l_msg)
- end
-```
-The class `HTTP_HEADER` also supplies a number of convenience routines for specifying common headers, in fact the features are inherited from the class `HTTP_HEADER_MODIFIER`.
-
-
-```eiffel
-deferred class interface
- HTTP_HEADER_MODIFIER
-
-feature -- Access
-
- date_to_rfc1123_http_date_format (dt: DATE_TIME): STRING_8
- -- String representation of `dt' using the RFC 1123
-
- item alias "[]" (a_header_name: READABLE_STRING_8): detachable READABLE_STRING_8 assign force
- -- First header item found for `a_name' if any
-
-feature -- Status report
-
- has (a_name: READABLE_STRING_8): BOOLEAN
- -- Has header item for `n'?
- -- Was declared in HTTP_HEADER_MODIFIER as synonym of has_header_named.
-
- has_content_length: BOOLEAN
- -- Has header "Content-Length"
-
- has_content_type: BOOLEAN
- -- Has header "Content-Type"
-
- has_header_named (a_name: READABLE_STRING_8): BOOLEAN
- -- Has header item for `n'?
- -- Was declared in HTTP_HEADER_MODIFIER as synonym of has.
-
- has_transfer_encoding_chunked: BOOLEAN
- -- Has "Transfer-Encoding: chunked" header
-
-feature -- Access: deferred
-
- new_cursor: INDEXABLE_ITERATION_CURSOR [READABLE_STRING_8]
- -- Fresh cursor associated with current structure.
-
-feature -- Authorization
-
- put_authorization (a_authorization: READABLE_STRING_8)
- -- Put `a_authorization' with "Authorization" header
- -- The Authorization header is constructed as follows:
- -- 1. Username and password are combined into a string "username:password".
- -- 2. The resulting string literal is then encoded using Base64.
- -- 3. The authorization method and a space, i.e. "Basic " is then put before the encoded string.
- -- ex: Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
-
-feature -- Content related header
-
- add_content_type (a_content_type: READABLE_STRING_8)
- -- same as put_content_type, but allow multiple definition of "Content-Type"
-
- add_content_type_with_charset (a_content_type: READABLE_STRING_8; a_charset: READABLE_STRING_8)
- -- Same as put_content_type_with_charset, but allow multiple definition of "Content-Type".
-
- add_content_type_with_name (a_content_type: READABLE_STRING_8; a_name: READABLE_STRING_8)
- -- same as put_content_type_with_name, but allow multiple definition of "Content-Type"
-
- add_content_type_with_parameters (a_content_type: READABLE_STRING_8; a_params: detachable ARRAY [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]])
- -- Add header line "Content-Type:" + type `a_content_type' and extra paramaters `a_params'.
-
- put_content_disposition (a_type: READABLE_STRING_8; a_params: detachable READABLE_STRING_8)
- -- Put "Content-Disposition" header
-
- put_content_encoding (a_encoding: READABLE_STRING_8)
- -- Put "Content-Encoding" header of value `a_encoding'.
-
- put_content_language (a_lang: READABLE_STRING_8)
- -- Put "Content-Language" header of value `a_lang'.
-
- put_content_length (a_length: INTEGER_32)
- -- Put "Content-Length:" + length `a_length'.
-
- put_content_transfer_encoding (a_mechanism: READABLE_STRING_8)
- -- Put "Content-Transfer-Encoding" header with `a_mechanism'
-
- put_content_type (a_content_type: READABLE_STRING_8)
- -- Put header line "Content-Type:" + type `a_content_type'
-
- put_content_type_with_charset (a_content_type: READABLE_STRING_8; a_charset: READABLE_STRING_8)
- -- Put content type `a_content_type' with `a_charset' as "charset" parameter.
-
- put_content_type_with_name (a_content_type: READABLE_STRING_8; a_name: READABLE_STRING_8)
- -- Put content type `a_content_type' with `a_name' as "name" parameter.
-
- put_content_type_with_parameters (a_content_type: READABLE_STRING_8; a_params: detachable ARRAY [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]])
- -- Put header line "Content-Type:" + type `a_content_type' and extra paramaters `a_params'
-
- put_transfer_encoding (a_encoding: READABLE_STRING_8)
- -- Put "Transfer-Encoding" header with `a_encoding' value.
-
- put_transfer_encoding_binary
- -- Put "Transfer-Encoding: binary" header
-
- put_transfer_encoding_chunked
- -- Put "Transfer-Encoding: chunked" header
-
-feature -- Content-type helpers
-
- put_content_type_application_javascript
-
- put_content_type_application_json
-
- put_content_type_application_pdf
-
- put_content_type_application_x_www_form_encoded
-
- put_content_type_application_zip
-
- put_content_type_image_gif
-
- put_content_type_image_jpg
-
- put_content_type_image_png
-
- put_content_type_image_svg_xml
-
- put_content_type_message_http
-
- put_content_type_multipart_alternative
-
- put_content_type_multipart_encrypted
-
- put_content_type_multipart_form_data
-
- put_content_type_multipart_mixed
-
- put_content_type_multipart_related
-
- put_content_type_multipart_signed
-
- put_content_type_text_css
-
- put_content_type_text_csv
-
- put_content_type_text_html
-
- put_content_type_text_javascript
-
- put_content_type_text_json
-
- put_content_type_text_plain
-
- put_content_type_text_xml
-
- put_content_type_utf_8_text_plain
-
-feature -- Cookie
-
- put_cookie (key, value: READABLE_STRING_8; expiration, path, domain: detachable READABLE_STRING_8; secure, http_only: BOOLEAN)
- -- Set a cookie on the client's machine
- -- with key 'key' and value 'value'.
- -- Note: you should avoid using "localhost" as `domain' for local cookies
- -- since they are not always handled by browser (for instance Chrome)
- require
- make_sense: (key /= Void and value /= Void) and then (not key.is_empty and not value.is_empty)
- domain_without_port_info: domain /= Void implies domain.index_of (':', 1) = 0
-
- put_cookie_with_expiration_date (key, value: READABLE_STRING_8; expiration: DATE_TIME; path, domain: detachable READABLE_STRING_8; secure, http_only: BOOLEAN)
- -- Set a cookie on the client's machine
- -- with key 'key' and value 'value'.
- require
- make_sense: (key /= Void and value /= Void) and then (not key.is_empty and not value.is_empty)
-
-feature -- Cross-Origin Resource Sharing
-
- put_access_control_allow_all_origin
- -- Put "Access-Control-Allow-Origin: *" header.
-
- put_access_control_allow_credentials (b: BOOLEAN)
- -- Indicates whether or not the response to the request can be exposed when the credentials flag is true.
- -- When used as part of a response to a preflight request, this indicates whether or not the actual request can be made using credentials.
- -- Note that simple GET requests are not preflighted, and so if a request is made for a resource with credentials,
- -- if this header is not returned with the resource, the response is ignored by the browser and not returned to web content.
- -- ex: Access-Control-Allow-Credentials: true | false
-
- put_access_control_allow_headers (a_headers: READABLE_STRING_8)
- -- Put "Access-Control-Allow-Headers" header. with value `a_headers'
- -- Used in response to a preflight request to indicate which HTTP headers can be used when making the actual request.
- -- ex: Access-Control-Allow-Headers: [, ]*
-
- put_access_control_allow_iterable_headers (a_fields: ITERABLE [READABLE_STRING_8])
- -- Put "Access-Control-Allow-Headers" header. with value `a_headers'
- -- Used in response to a preflight request to indicate which HTTP headers can be used when making the actual request.
- -- ex: Access-Control-Allow-Headers: [, ]*
-
- put_access_control_allow_methods (a_methods: ITERABLE [READABLE_STRING_8])
- -- If `a_methods' is not empty, put `Access-Control-Allow-Methods' header with list `a_methods' of methods
- -- `a_methods' specifies the method or methods allowed when accessing the resource.
- -- This is used in response to a preflight request.
- -- ex: Access-Control-Allow-Methods: [, ]*
-
- put_access_control_allow_origin (a_origin: READABLE_STRING_8)
- -- Put "Access-Control-Allow-Origin: " + `a_origin' header.
- -- `a_origin' specifies a URI that may access the resource
-
-feature -- Date
-
- put_current_date
- -- Put current date time with "Date" header
-
- put_date (a_date: READABLE_STRING_8)
- -- Put "Date: " header
-
- put_last_modified (a_utc_date: DATE_TIME)
- -- Put UTC date time `dt' with "Last-Modified" header
-
- put_utc_date (a_utc_date: DATE_TIME)
- -- Put UTC date time `a_utc_date' with "Date" header
- -- using RFC1123 date formating.
-
-feature -- Header change: deferred
-
- add_header (h: READABLE_STRING_8)
- -- Add header `h'
- -- if it already exists, there will be multiple header with same name
- -- which can also be valid
- require
- h_not_empty: h /= Void and then not h.is_empty
-
- put_header (h: READABLE_STRING_8)
- -- Add header `h' or replace existing header of same header name
- require
- h_not_empty: h /= Void and then not h.is_empty
-
-feature -- Header change: general
-
- add_header_key_value (a_header_name, a_value: READABLE_STRING_8)
- -- Add header `a_header_name:a_value'.
- -- If it already exists, there will be multiple header with same name
- -- which can also be valid
- ensure
- added: has_header_named (a_header_name)
-
- force (a_value: detachable READABLE_STRING_8; a_header_name: READABLE_STRING_8)
- -- Put header `a_header_name:a_value' or replace existing header of name `a_header_name'.
-
- put_header_key_value (a_header_name, a_value: READABLE_STRING_8)
- -- Add header `a_header_name:a_value', or replace existing header of same header name/key
- ensure
- added: has_header_named (a_header_name)
-
- put_header_key_values (a_header_name: READABLE_STRING_8; a_values: ITERABLE [READABLE_STRING_8]; a_separator: detachable READABLE_STRING_8)
- -- Add header `a_header_name: a_values', or replace existing header of same header values/key.
- -- Use Comma_space as default separator if `a_separator' is Void or empty.
- ensure
- added: has_header_named (a_header_name)
-
-feature -- Method related
-
- put_allow (a_methods: ITERABLE [READABLE_STRING_8])
- -- If `a_methods' is not empty, put `Allow' header with list `a_methods' of methods
-
-feature -- Others
-
- put_cache_control (a_cache_control: READABLE_STRING_8)
- -- Put "Cache-Control" header with value `a_cache_control'
-
- put_expires (a_seconds: INTEGER_32)
- -- Put "Expires" header to `a_seconds' seconds
-
- put_expires_date (a_utc_date: DATE_TIME)
- -- Put "Expires" header with UTC date time value
- -- formatted following RFC1123 specification.
-
- put_expires_string (a_expires: STRING_8)
- -- Put "Expires" header with `a_expires' string value
-
- put_pragma (a_pragma: READABLE_STRING_8)
- -- Put "Pragma" header with value `a_pragma'
-
- put_pragma_no_cache
- -- Put "Pragma" header with "no-cache" a_pragma
-
-feature -- Redirection
-
- put_location (a_uri: READABLE_STRING_8)
- -- Tell the client the new location `a_uri'
- -- using "Location" header.
- require
- a_uri_valid: not a_uri.is_empty
-
- put_refresh (a_uri: READABLE_STRING_8; a_timeout_in_seconds: INTEGER_32)
- -- Tell the client to refresh page with `a_uri' after `a_timeout_in_seconds' in seconds
- -- using "Refresh" header.
- require
- a_uri_valid: not a_uri.is_empty
-
-end -- class HTTP_HEADER_MODIFIER
-```
-
-
-
-## HTTP 1.1 Response Headers
-
-There are four categories for response header fields:
- - [Control Data](https://httpwg.github.io/specs/rfc7231.html#response.control.data) : Supply control data that supplements the status code, directs caching, or instructs the client where to go next.
- - Age,Cache-Control,Expires,Date,Location,Retry-After,Vary,Warning.
- - [Validator](https://httpwg.github.io/specs/rfc7231.html#response.validator): Validator header fields convey metadata about the selected representation. In responses to safe requests, validator fields describe the selected representation chosen by the origin server while handling the response.
- - [Authentication Challenges](https://httpwg.github.io/specs/rfc7231.html#response.auth): Indicate what mechanisms are available for the client to provide authentication credentials in future requests.
- - [Response Context](https://httpwg.github.io/specs/rfc7231.html#response.context): Provide more information about the target resource for potential use in later requests.
-
-
-
-Nav: [Workbook](../workbook.md) :: [Handling Requests: Header Fields](../handling_request/headers.md) :: [Handling Cookies](../handling_cookies/handling_cookies.md)
diff --git a/doc/workbook/generating_response/headers/application.e b/doc/workbook/generating_response/headers/application.e
deleted file mode 100644
index cf939f60..00000000
--- a/doc/workbook/generating_response/headers/application.e
+++ /dev/null
@@ -1,24 +0,0 @@
-note
- description: "Basic Service launcher"
-
-class
- APPLICATION
-
-inherit
- WSF_DEFAULT_SERVICE [APPLICATION_EXECUTION]
- redefine
- initialize
- end
-
-create
- make_and_launch
-
-feature {NONE} -- Initialization
-
- initialize
- -- Initialize current service.
- do
- set_service_option ("port", 9090)
- end
-
-end
diff --git a/doc/workbook/generating_response/headers/application_execution.e b/doc/workbook/generating_response/headers/application_execution.e
deleted file mode 100644
index 5b042d53..00000000
--- a/doc/workbook/generating_response/headers/application_execution.e
+++ /dev/null
@@ -1,57 +0,0 @@
-note
- description : "Basic Service that build a generic front end for the most used search engines."
- date : "$Date$"
- revision : "$Revision$"
-
-class
- APPLICATION_EXECUTION
-
-inherit
- WSF_EXECUTION
-
-create
- make
-
-feature -- Basic operations
-
- execute
- -- Execute the incomming request
- local
- l_message: STRING
- do
- -- (1) To send a response we need to setup, the status code and the response headers.
--- response.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", web_page.count.out]>>)
--- response.put_string (web_page)
-
- -- (2) Using put_header_line
--- response.set_status_code ({HTTP_STATUS_CODE}.ok)
--- response.put_header_line ("Content-Type:text/html")
- response.put_header_line ("Content-Length:"+ web_page.count.out)
- response.put_header_line ("Content-Type:text/plain")
-
- response.put_string (web_page)
- end
-
-
-
-feature -- Home Page
-
- web_page: STRING = "[
-
-
-
- EWF Headers Responses
-
-
-
-
Example Header Response
-
Response headers
-
-
-
-
-
-]"
-end
diff --git a/doc/workbook/generating_response/headers/headers.ecf b/doc/workbook/generating_response/headers/headers.ecf
deleted file mode 100644
index 797eb842..00000000
--- a/doc/workbook/generating_response/headers/headers.ecf
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
- /EIFGENs$
- /CVS$
- /.svn$
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/workbook/generating_response/search/application.e b/doc/workbook/generating_response/search/application.e
deleted file mode 100644
index cf939f60..00000000
--- a/doc/workbook/generating_response/search/application.e
+++ /dev/null
@@ -1,24 +0,0 @@
-note
- description: "Basic Service launcher"
-
-class
- APPLICATION
-
-inherit
- WSF_DEFAULT_SERVICE [APPLICATION_EXECUTION]
- redefine
- initialize
- end
-
-create
- make_and_launch
-
-feature {NONE} -- Initialization
-
- initialize
- -- Initialize current service.
- do
- set_service_option ("port", 9090)
- end
-
-end
diff --git a/doc/workbook/generating_response/search/application_execution.e b/doc/workbook/generating_response/search/application_execution.e
deleted file mode 100644
index 1e3ebe08..00000000
--- a/doc/workbook/generating_response/search/application_execution.e
+++ /dev/null
@@ -1,172 +0,0 @@
-note
- description : "Basic Service that build a generic front end for the most used search engines."
- date : "$Date$"
- revision : "$Revision$"
-
-class
- APPLICATION_EXECUTION
-
-inherit
- WSF_EXECUTION
-
-create
- make
-
-feature -- Basic operations
-
- execute
- -- Execute the incomming request
- local
- l_message: STRING
- do
- -- To send a response we need to setup, the status code and
- -- the response headers.
- if request.is_get_request_method then
- if request.path_info.same_string ("/") then
- response.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", web_page.count.out]>>)
- response.put_string (web_page)
- else
- send_resouce_not_found (request, response)
- end
- elseif request.is_post_request_method then
- if request.path_info.same_string ("/search") then
- if attached {WSF_STRING} request.form_parameter ("query") as l_query then
- if attached {WSF_STRING} request.form_parameter ("engine") as l_engine then
- if attached {STRING} map.at (l_engine.value) as l_engine_url then
- l_engine_url.append (l_query.value)
- send_redirect (request, response, l_engine_url)
- -- response.redirect_now (l_engine_url)
- else
- send_bad_request (request, response, " search engine: " + l_engine.value + " not supported, try with Google or Bing")
- end
- else
- send_bad_request (request, response, " search engine not selected")
- end
- else
- send_bad_request (request, response, " form_parameter query is not present")
- end
- else
- send_resouce_not_found (request, response)
- end
- else
- create l_message.make_from_string (message_template)
- l_message.replace_substring_all ("$title", "Method Not Allowed")
- l_message.replace_substring_all ("$status", "Method Not Allowed 405")
- -- Method not allowed
- response.put_header ({HTTP_STATUS_CODE}.method_not_allowed, <<["Content-Type", "text/html"], ["Content-Length", l_message.count.out]>>)
- response.put_string (l_message)
- end
- end
-
-
-feature -- Engine Map
-
- map : STRING_TABLE[STRING]
- do
- create Result.make (2)
- Result.put ("http://www.google.com/search?q=", "Google")
- Result.put ("http://www.bing.com/search?q=", "Bing")
- end
-
-feature -- Redirect
-
- send_redirect (req: WSF_REQUEST; res: WSF_RESPONSE; a_location: READABLE_STRING_32)
- -- Redirect to `a_location'
- local
- h: HTTP_HEADER
- do
- create h.make
- h.put_content_type_text_html
- h.put_current_date
- h.put_location (a_location)
- res.set_status_code ({HTTP_STATUS_CODE}.see_other)
- res.put_header_text (h.string)
- end
-
-feature -- Bad Request
-
- send_bad_request (req: WSF_REQUEST; res: WSF_RESPONSE; description: STRING)
- local
- l_message: STRING
- do
- create l_message.make_from_string (message_template)
- l_message.replace_substring_all ("$title", "Bad Request")
- l_message.replace_substring_all ("$status", "Bad Request" + description)
- res.put_header ({HTTP_STATUS_CODE}.bad_request, <<["Content-Type", "text/html"], ["Content-Length", l_message.count.out]>>)
- res.put_string (l_message)
- end
-
-feature -- Resource not found
-
- send_resouce_not_found (req: WSF_REQUEST; res: WSF_RESPONSE)
- local
- l_message: STRING
- do
- create l_message.make_from_string (message_template)
- l_message.replace_substring_all ("$title", "Resource not found")
- l_message.replace_substring_all ("$status", "Resource " + req.request_uri + " not found 404")
- res.put_header ({HTTP_STATUS_CODE}.not_found, <<["Content-Type", "text/html"], ["Content-Length", l_message.count.out]>>)
- res.put_string (l_message)
- end
-
-feature -- Home Page
-
- web_page: STRING = "[
-
-
-
- Generic Search Engine
-
-
-
Use a tool to see the request and header details, for example (Developers tools in Chrome or Firebugs in Firefox)
-
-
-
-
This page is an example of $status
-
-
-
-
-]"
-
-
-
-
-end
diff --git a/doc/workbook/generating_response/search/search.ecf b/doc/workbook/generating_response/search/search.ecf
deleted file mode 100644
index 7c42d50b..00000000
--- a/doc/workbook/generating_response/search/search.ecf
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
- /.svn$
- /CVS$
- /EIFGENs$
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/workbook/generating_response/status/application.e b/doc/workbook/generating_response/status/application.e
deleted file mode 100644
index cf939f60..00000000
--- a/doc/workbook/generating_response/status/application.e
+++ /dev/null
@@ -1,24 +0,0 @@
-note
- description: "Basic Service launcher"
-
-class
- APPLICATION
-
-inherit
- WSF_DEFAULT_SERVICE [APPLICATION_EXECUTION]
- redefine
- initialize
- end
-
-create
- make_and_launch
-
-feature {NONE} -- Initialization
-
- initialize
- -- Initialize current service.
- do
- set_service_option ("port", 9090)
- end
-
-end
diff --git a/doc/workbook/generating_response/status/application_execution.e b/doc/workbook/generating_response/status/application_execution.e
deleted file mode 100644
index 691513b6..00000000
--- a/doc/workbook/generating_response/status/application_execution.e
+++ /dev/null
@@ -1,138 +0,0 @@
-note
- description : "Basic Service that a simple web page to show the most common status codes"
- date : "$Date$"
- revision : "$Revision$"
-
-class
- APPLICATION_EXECUTION
-
-inherit
- WSF_EXECUTION
-
-create
- make
-
-feature -- Basic operations
-
- execute
- -- Execute the incomming request
- local
- l_message: STRING
- do
- -- To send a response we need to setup, the status code and
- -- the response headers.
- if request.is_get_request_method then
- if request.path_info.same_string ("/") then
- response.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", web_page.count.out]>>)
- response.put_string (web_page)
- elseif request.path_info.same_string ("/redirect") then
- send_redirect (request, response, "https://httpwg.github.io/")
- elseif request.path_info.same_string ("/bad_request") then
- -- Here you can do some logic for example log, send emails to register the error, before to send the response.
- create l_message.make_from_string (message_template)
- l_message.replace_substring_all ("$title", "Bad Request")
- l_message.replace_substring_all ("$status", "Bad Request 400")
- response.put_header ({HTTP_STATUS_CODE}.bad_request, <<["Content-Type", "text/html"], ["Content-Length", l_message.count.out]>>)
- response.put_string (l_message)
- elseif request.path_info.same_string ("/internal_error") then
- -- Here you can do some logic for example log, send emails to register the error, before to send the response.
- create l_message.make_from_string (message_template)
- l_message.replace_substring_all ("$title", "Internal Server Error")
- l_message.replace_substring_all ("$status", "Internal Server Error 500")
- response.put_header ({HTTP_STATUS_CODE}.internal_server_error, <<["Content-Type", "text/html"], ["Content-Length", l_message.count.out]>>)
- response.put_string (l_message)
- else
- create l_message.make_from_string (message_template)
- l_message.replace_substring_all ("$title", "Resource not found")
- l_message.replace_substring_all ("$status", "Resource not found 400")
- response.put_header ({HTTP_STATUS_CODE}.not_found, <<["Content-Type", "text/html"], ["Content-Length", l_message.count.out]>>)
- response.put_string (l_message)
- end
- else
- create l_message.make_from_string (message_template)
- l_message.replace_substring_all ("$title", "Method Not Allowed")
- l_message.replace_substring_all ("$status", "Method Not Allowed 405")
- -- Method not allowed
- response.put_header ({HTTP_STATUS_CODE}.method_not_allowed, <<["Content-Type", "text/html"], ["Content-Length", l_message.count.out]>>)
- response.put_string (l_message)
- end
- end
-
-
-feature -- Home Page
-
- send_redirect (req: WSF_REQUEST; res: WSF_RESPONSE; a_location: READABLE_STRING_32)
- -- Redirect to `a_location'
- local
- h: HTTP_HEADER
- do
- create h.make
- h.put_content_type_text_html
- h.put_current_date
- h.put_location (a_location)
- res.set_status_code ({HTTP_STATUS_CODE}.see_other)
- res.put_header_text (h.string)
- end
-
- web_page: STRING = "[
-
-
-
- Example showing common status codes
-
-
-
-
Use a tool to see the request and header details, for example (Developers tools in Chrome or Firebugs in Firefox)
-
-
-
-
This page is an example of Status Code 200
-
-
Redirect Example
-
Click on the following link will redirect you to the HTTP Specifcation, we can do the redirect from the HTML directly but
- here we want to show you an exmaple, where you can do something before to send a redirect Redirect
-
-
Bad Request
-
Click on the following link, the server will answer with a 400 error, check the status code Bad Request
-
-
Internal Server Error
-
Click on the following link, the server will answer with a 500 error, check the status code Internal Error
-
-
Resource not found
-
Click on the following link or add to the end of the url something like /1030303 the server will answer with a 404 error, check the status code Not found
-
-
-
-
-]"
-
-end
diff --git a/doc/workbook/handling_cookies/example/example.ecf b/doc/workbook/handling_cookies/example/example.ecf
deleted file mode 100644
index dea25001..00000000
--- a/doc/workbook/handling_cookies/example/example.ecf
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
- /.svn$
- /CVS$
- /EIFGENs$
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/doc/workbook/handling_cookies/handling_cookies.md b/doc/workbook/handling_cookies/handling_cookies.md
deleted file mode 100644
index d30ee90f..00000000
--- a/doc/workbook/handling_cookies/handling_cookies.md
+++ /dev/null
@@ -1,294 +0,0 @@
-Nav: [Workbook](../workbook.md) :: [Generating Responses](../generating_response/generating_response.md)
-
-# Handling Cookies
-
-- [Cookie](#cookie)
- - [Cookie Porperties](#properties)
-- [Write and Read Cookies](#set_get)
- - [How to set a cookie](#set_cookie)
- - [How to read a cookie](#read_cookie)
-- [Examples](#examples)
-
-
-
-## Cookie
-A [cookie](http://httpwg.github.io/specs/rfc6265.html) is a piece of data that can be stored in a browser's cache. If you visit a web site and then revisit it, the cookie data can be used to identify you as a return visitor. Cookies enable state information, such as an online shopping cart, to be remembered. A cookie can be short term, holding data for a single web session, that is, until you close the browser, or a cookie can be longer term, holding data for a week or a year.
-
-Cookies are used a lot in web client-server communication.
-
-- HTTP State Management With Cookies
-
-- Personalized response to the client based on their preference, for example we can set background color as cookie in client browser and then use it to customize response background color, image etc.
-
-Server send cookies to the client
-
->Set-Cookie: _Framework=EWF; Path=/; Expires=Tue, 10 Mar 2015 13:28:10 GMT; HttpOnly%R
-
-
-Client send cookies to server
-
->Cookie: _Framework=EWF
-
-
-
-
-
-### Cookie properties
-
- - Comment: describe the purpose of the cookie. Note that server doesn’t receive this information when client sends cookie in request header.
- - Domain: domain name for the cookie.
- - Expiration/MaxAge: Expiration time of the cookie, we could also set it in seconds. (At the moment Max-Age attribute is not supported)
- - Name: name of the cookie.
- - Path: path on the server to which the browser returns this cookie. Path instruct the browser to send cookie to a particular resource.
- - Secure: True, if the browser is sending cookies only over a secure protocol, False in other case.
- - Value: Value of th cookie as string.
- - HttpOnly: Checks whether this Cookie has been marked as HttpOnly.
- - Version:
-
-
-
-## Write and Read Cookies.
-
-To send a cookie to the client we should use the **HTTP_HEADER** class, and call ```h.put_cookie``` feature or
-```h.put_cookie_with_expiration_date``` feature, see `How to set Cookies` to learn the details, and the set it to response object **WSF_RESPONSE** as we saw previously.
-
-We will show an example.
-
-To Read incomming cookies we can read all the cookies with
-
-```
-cookies: ITERABLE [WSF_VALUE]
- -- All cookies.
-```
-which return an interable of WSF_VALUE objects corresponding to the cookies the browser has associated with the web site.
-We can also check if a particular cookie by name using
-
-```
-WSF_REQUEST.cookie (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
- -- Field for name `a_name'.
-```
-feature.
-
-
-
-
-### How to set Cookies
-Here we have the feature definitions to set cookies
-
-```eiffel
-deferred class interface
- HTTP_HEADER_MODIFIER
-
-feature -- Cookie
-
- put_cookie (key, value: READABLE_STRING_8; expiration, path, domain: detachable READABLE_STRING_8; secure, http_only: BOOLEAN)
- -- Set a cookie on the client's machine
- -- with key 'key' and value 'value'.
- -- Note: you should avoid using "localhost" as `domain' for local cookies
- -- since they are not always handled by browser (for instance Chrome)
- require
- make_sense: (key /= Void and value /= Void) and then (not key.is_empty and not value.is_empty)
- domain_without_port_info: domain /= Void implies domain.index_of (':', 1) = 0
-
- put_cookie_with_expiration_date (key, value: READABLE_STRING_8; expiration: DATE_TIME; path, domain: detachable READABLE_STRING_8; secure, http_only: BOOLEAN)
- -- Set a cookie on the client's machine
- -- with key 'key' and value 'value'.
- require
- make_sense: (key /= Void and value /= Void) and then (not key.is_empty and not value.is_empty)
-```
-
-Example of use:
-
-```eiffel
- response_with_cookies (res: WSF_RESPONSE)
- local
- l_message: STRING
- l_header: HTTP_HEADER
- l_time: HTTP_DATE
- do
- create l_header.make
- create l_time.make_now_utc
- l_time.date_time.day_add (40)
- l_header.put_content_type_text_html
- l_header.put_cookie_with_expiration_date ("EWFCookie", "EXAMPLE",l_time.date_time, "/", Void, False, True)
- res.put_header_text (l_header.string)
- res.put_string (web_page)
- end
-```
-
-
-### How to read Cookies
-
-Reading a particular cookie
-```eiffel
- if req.cookie ("EWFCookie") = Void then
- do_something
- end
-````
-
-Reading all the cookies
-
-```Eiffel
- across req.cookies as ic loop
- print (ic.item.name)
- end
-```
-
-
-
-
-### Example
-The following EWF service shows a basic use of cookies.
- 1. It display a message to first-time visitors.
- 2. Display a welcome back message if a visitor return.
- 3. A visitor page, counting the number of visits to the page (track user access counts).
- 4. A cookie with an expiration of 120 seconds.
- 5. A cookie with an session level, valid in browser session.
-
-```eiffel
-note
- description : "Basic Service that build a generic front to demonstrate the use of Cookies"
- date : "$Date$"
- revision : "$Revision$"
-
-class
- APPLICATION_EXECUTION
-
-inherit
- WSF_EXECUTION
-
-create
- make
-
-feature -- Basic operations
-
- execute (req: WSF_REQUEST; res: WSF_RESPONSE)
- -- Execute the incomming request
- local
- l_message: STRING
- l_header: HTTP_HEADER
- l_time: HTTP_DATE
- l_cookies: STRING
- l_answer: STRING
- do
- -- all the cookies
- create l_cookies.make_empty
- across req.cookies as ic loop
- l_cookies.append (ic.item.name)
- l_cookies.append(" ")
- end
-
- if req.path_info.same_string ("/") then
- create l_header.make
- create l_answer.make_from_string (web_page)
- if req.cookie ("_EWF_Cookie") = Void then
- -- First access the the home page, find a cookie with specific name `_EWF_Cookie'
- l_answer.replace_substring_all ("$header_title", "Hey, thanks for access our cool site, this is your first acess")
- l_answer.replace_substring_all ("$cookies", l_cookies)
- create l_time.make_now_utc
- l_time.date_time.day_add (40)
- l_header.put_cookie_with_expiration_date ("_EWF_Cookie", "EXAMPLE",l_time.date_time, "", Void, False, True)
- else
- -- No a new access
- l_answer.replace_substring_all ("$header_title", "Welcome back, please check all the new things we have!!!")
- l_answer.replace_substring_all ("$cookies", l_cookies)
- end
- l_header.put_content_type_text_html
- l_header.put_content_length (l_answer.count)
- res.put_header_text (l_header.string)
- res.put_string (l_answer)
-
- elseif req.path_info.same_string ("/visitors") then
- create l_header.make
- create l_answer.make_from_string (visit_page)
- if req.cookie ("_visits") = Void then
- -- First access the the visit page, find a cookie with specific name `_visits'
- l_answer.replace_substring_all ("$visit", "1")
- l_answer.replace_substring_all ("$cookies", l_cookies)
- create l_time.make_now_utc
- l_time.date_time.day_add (40)
- l_header.put_cookie_with_expiration_date ("_visits", "1",l_time.date_time, "/visitors", Void, False, True)
-
- else
- if attached {WSF_STRING} req.cookie ("_visits") as l_visit then
- create l_time.make_now_utc
- l_time.date_time.day_add (40)
- l_answer.replace_substring_all ("$visit", (l_visit.value.to_integer + 1).out )
- l_answer.replace_substring_all ("$cookies", l_cookies)
- l_header.put_cookie_with_expiration_date ("_visits", (l_visit.value.to_integer + 1).out,l_time.date_time, "/visitors", Void, False, True)
- end
- end
- create l_time.make_now_utc
- l_time.date_time.second_add (120)
- l_header.put_content_type_text_html
- -- This cookie expires in 120 seconds, its valid for 120 seconds
- l_header.put_cookie_with_expiration_date ("_Framework", "EWF",l_time.date_time, "/", Void, False, True)
- -- This is a session cookie, valid only to the current browsing session.
- l_header.put_cookie ("Session", "Cookie",Void, "/", Void, False, True)
- l_header.put_content_length (l_answer.count)
- res.add_header_text (l_header.string)
- res.put_string (l_answer)
- end
-
- end
-
-feature -- Home Page
-
- web_page: STRING = "[
-
-
-
- EWF Handling Cookies
-
-
-
-
-
-
-
-]"
-
-end
-
-```
-
-
-Nav: [Workbook](../workbook.md) :: [Generating Responses](../generating_response/generating_response.md)
diff --git a/doc/workbook/handling_request/form.md b/doc/workbook/handling_request/form.md
deleted file mode 100644
index 6cdf2416..00000000
--- a/doc/workbook/handling_request/form.md
+++ /dev/null
@@ -1,323 +0,0 @@
-Nav: [Workbook](../workbook.md) :: [Basic Concepts](../basics/basics.md) :: [Handling Requests: Header Fields](./headers.md)
-
-# Handling Requests: Form/Query Data
-
-##### Table of Contents
-- [Reading Form Data](#read)
- - [Query Parameters](#query)
- - [Form Parameters](#form_parameters)
- - [Uniform Read](#uniform)
-- [Reading Parameters and Values](#reading_pv)
- - [How to read all parameters names](#all_names)
- - [How to read single values](#single_values)
- - [How to read multiple values](#multiple_values)
- - [How to read table values](#table_values)
-- [Reading raw data](#raw_data)
-- [Upload Files](#upload)
-- [Examples](#examples)
-
-
-An HTML Form can handle `GET` and `POST` requests.
-When we use a form with method `GET`, the data is attached at the end of the url for example:
-
->http://wwww.example.com/?key1=value1&...keyn=valuen
-
-If we use the method `POST`, the data is sent to the server in a different line.
-
-Extracting form data from the server side is one of the most tedious parts. If you do it by hand, you will need
-to parse the input, you'll have to URL-decode the value.
-
-Here we will show you how to read input submitted by a user using a Form (`GET` and `POST`).
- * How to handle missing values:
- * client side validattion, server side validations, set default if it's a valid option.
- * How to populate Eiffel objects from the request data.
-
-
-
-## Reading Form Data
-EWF `WSF_REQUEST` class, provides features to handling this form parsing automatically.
-
-
-
-### Query Parameters
-
-```eiffel
- WSF_REQUEST.query_parameters: ITERABLE [WSF_VALUE]
- -- All query parameters
-
- WSF_REQUEST.query_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
- -- Query parameter for name `a_name'.
-```
-
-
-
-### Form Parameters
-
-```eiffel
- WSF_REQUEST.form_parameters: ITERABLE [WSF_VALUE]
- -- All form parameters sent by a POST
-
- WSF_REQUEST.form_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
- -- Field for name `a_name'.
-```
-
-The values supplied to `form_parameter` and `query_parameter` are _case_ _sensitive_.
-
-
-
-### Read Data
-The previous features, let you read the data one way for `GET` request and a different way for `POST` request. **WSF_REQUEST** provide a feature to read all the data in a uniform way.
-
-```eiffel
- WSF_REQUEST.item (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
- -- Variable named `a_name' from any of the variables container
- -- and following a specific order: form_, query_ and path_ parameters
-```
-
-So, you can use **WSF_REQUEST.item** feature exactly the same way for `GET` and `POST` request.
-
->Note: if a query parameter has the same name as a form paramenter req.item will retrieve the form paramenter. Remember the precedence: `form` > `query` > `path`
-
-
-
-
-## Reading Parameters and Values
-
-Suppose we have the following HTML5 form using method `POST`. This HTML5 form has client side form validation using the new HTML5 `attribute`, you can do the same using Javascript. So in this case if the user does not fill the fields as expected the form will not be submitted to the server.
-
->Note: it is recommended to validate client side input on the server side (as a double check) because you can protect against the malicious user, who can easily bypass your JavaScript and submit dangerous input to the server.
-
-```
-
EWF Handling Client Request: Form example
-
-```
-
-
-### How to read all parameter names
-To read all the parameters names we simple call **WSF_REQUEST.form_parameters**.
-
-```eiffel
- req: WSF_REQUEST
- across req.form_parameters as ic loop show_parameter_name (ic.item.key) end
-```
-
-
-### How to read single values
-To read a particular parameter, a single value, for example `given-name`, we simple call **WSF_REQUEST.form_parameter (a_name)** and we check if it's attached to **WSF_STRING** (represents a String parameter)
-```eiffel
- req: WSF_REQUEST
- if attached {WSF_STRING} req.form_paramenter ('given-name') as l_given_name then
- -- Work with the given parameter, for example populate an USER object
- -- the argument is case sensitive
- else
- -- Value missing, check the name against the HTML form
- end
-```
-
-
-### How to read multiple values
-
-To read multiple values, for example in the case of `languages`, we simple call **WSF_REQUEST.form_parameter (a_name)** and we check if it's attached to **WSF_MULTIPLE_STRING** (represents a String parameter)
-
-```eiffel
- req: WSF_REQUEST
- idioms: LIST[STRING]
- -- the argument is case sensitive
- if attached {WSF_MULTIPLE_STRING} req.form_paramenter ('languages') as l_languages then
- -- Work with the given parameter, for example populate an USER object
- -- Get all the associated values
- create {ARRAYED_LIST[STRING]} idioms.make (2)
- across l_languages as ic loop idioms.force (ic.item.value) end
- elseif attached {WSF_STRING} req.form_paramenter ('languages') as l_language then
- -- Value missing, check the name against the HTML form
- create {ARRAYED_LIST[STRING]} idioms.make (1)
- idioms.force (l_language.value)
- else
- -- Value missing
- end
-```
-In this case we are handling strings values, but in some cases you will need to do a conversion, between the strings that came from the request to map them to your domain model.
-
-
-
-### How to read table values
-This is particularly useful when you have a request with the following format
-
-``````
-
-To read table values, for example in the case of `tab`, we simple call **WSF_REQUEST.form_parameter (a_name)** and we check if it's attached to **WSF_TABLE**.
-
-```eiffel
-if attached {WSF_TABLE} req.query_parameter ("tab") as l_tab then
- l_parameter_names.append (" ")
- l_parameter_names.append (l_tab.name)
- from
- l_tab.values.start
- until
- l_tab.values.after
- loop
- l_parameter_names.append (" ")
- l_parameter_names.append (l_tab.values.key_for_iteration)
- if attached {WSF_STRING} l_tab.value (l_tab.values.key_for_iteration) as l_value then
- l_parameter_names.append ("=")
- l_parameter_names.append (l_value.value)
- end
- l_tab.values.forth
- end
-end
-```
-
-
-
-## Reading Raw Data
-You can also access the data in raw format, it means you will need to parse and url-decode it, and also you will not be able to use the previous features, by default, to enable that, you will need to call `req.set_raw_input_data_recorded (True)`. This feature (reading raw data) is useful if you are reading `POST` data with JSON or XML formats, but it's not convinient for HTML forms.
-
-To read raw data you need to do this
-
-```eiffel
- l_raw_data:STRING
-
- req.set_raw_input_data_recorded (True)
- create l_raw_data.make_empty
- req.read_input_data_into (l_raw_data)
-```
-
-> given-name=testr&family-name=test&dob=1976-08-26&email=test%40gmail.com&url=http%3A%2F%2Fwww.eiffelroom.com&phone=455555555555&languages=Spanish&languages=English
-
-
-
-## Upload Files
-How can we read data when the date come from an uploaded file/s?.
-HTML supports a form element `````` to upload a single file and ``` ``` to upload multiple files.
-
-So supose we have the following form
-
-```
-
-
-
- EWF Handling Client Request: File Upload Example
-
-
-