Compare commits

...

9 Commits

Author SHA1 Message Date
b5d6a75155 Fixed table item output by appending html attribute for WSF widget table item. 2015-12-28 17:40:59 +01:00
4fc4b02449 Made WSF_TABLE a TABLE_ITERABLE. 2015-12-28 17:40:20 +01:00
5276bd1479 Fixed URI mapping with regard to trailing slash handling. 2015-12-28 17:39:54 +01:00
Javier Velilla
81ab31b19a Updated workbook
Added EWF Deployment title
2015-12-22 11:44:21 -03:00
Javier Velilla
e21e30ff74 Updated workbook
Added deployment document
2015-12-22 11:43:17 -03:00
Javier Velilla
3a9ba75717 Initial commit Deployment file 2015-12-22 11:37:25 -03:00
7d94413297 removed non void-safe tests.ecf for feeds library 2015-11-05 21:48:17 +01:00
35855941e6 Comment and code cleaning. 2015-11-05 21:37:44 +01:00
50ba8ca703 Fixed various unicode issue related to query and form parameters.
(Especially for the multipart/form-data encoding.)
Factorized code related to smart parameters computing (handling list , table, ...) in WSF_VALUE_UTILITIES.
Fixed an issue with percent_encoded_path_info computation from request_uri.
Fixed issue with cookie addition having same cookie name.
Fixed unicode support for uploaded file.
WSF_STRING is reusing WSF_PERCENT_ENCODER.
Use unicode output for WSF_DEBUG_HANDLER.
Code cleaning
2015-11-05 21:32:24 +01:00
19 changed files with 513 additions and 389 deletions

163
doc/workbook/deployment.md Normal file
View File

@@ -0,0 +1,163 @@
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/
####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.
<APACHE_PATH>/htdocs.
<APACHE_PATH> = path to your apache installation
Edit httpd.conf under c:/<APACHE_PATH>/conf
DocumentRoot "c:/<APACHE_PATH>/htdocs"
<Directory "c:/<APACHE_PATH>/htdocs">
AllowOverride All --
Require all granted -- this is required in Apache 2.4.4
</Directory>
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
<IfModule mod_rewrite.c>
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]
</IfModule
>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/
####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
<APACHE_PATH>/htdocs.
<APACHE_PATH> = path to your apache installation
Edit httpd.conf under c:/<APACHE_PATH>/conf
DocumentRoot "c:/<APACHE_PATH>/htdocs"
<Directory "c:/<APACHE_PATH>/htdocs">
AllowOverride All --
Require all granted -- this is required in Apache 2.4.4
</Directory>
>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
#.htaccess FCGI
>http://perishablepress.com/stupid-htaccess-tricks/
####.htaccess
Options +ExecCGI +Includes +FollowSymLinks -Indexes
<IfModule mod_fcgid.c>
AddHandler fcgid-script .ews
FcgidWrapper $FULL_PATH/$service .ews
</IfModule>
<IfModule mod_rewrite.c>
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]
</IfModule>
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.

View File

@@ -5,9 +5,9 @@
* [EWF Introduction](#introduction)
* [Handling Requests: Form/Query Parameter](#form_query_parameters)
* [Handling Requests: Header Fields](#header_fields)
* [Generating Responses](/workbook/generating_response/generating_response.md)
* [Handling Cookies](/workbook/handling_cookies/handling_cookies.md)
*
* [Generating Responses](#generating responses)
* [Handling Cookies](#handling_cookies)
* [EWF Deployment](#deployment)
<a name="core"></a>
# EWF Core
@@ -29,10 +29,14 @@ Before reading (or walking throught) the workbook, to get a quick overview of EW
## Handling Requests: Header Fields
[Handling Requests: Header Fields](/doc/workbook/handling_request/headers.md).
<a name="header_fields"></a>
<a name="generating_responses"></a>
## Generating Response
[Generating Responses](/doc/workbook/generating_response/generating_response.md)
<a name="handling_cookies"></a>
## Handling Cookies
[Handling Cookies](/doc/workbook/handling_cookies/handling_cookies.md)
<a name="deployment"/>
## EWF Deployment
[EWF Deployment](/doc/workbook/deployment.md)

View File

@@ -59,6 +59,7 @@ feature -- Access
create dbg.make
dbg.set_is_verbose (True)
dbg.set_unicode_output_enabled (True)
dbg.append_cgi_variables_to (req, res, s)
dbg.append_information_to (req, res, s)

View File

@@ -42,6 +42,9 @@ feature -- Settings
is_verbose: BOOLEAN
-- Has verbose output (default: True)?
unicode_output_enabled: BOOLEAN
-- Display names and values as unicode.
feature -- Settings change
set_is_verbose (b: BOOLEAN)
@@ -50,6 +53,12 @@ feature -- Settings change
is_verbose := b
end
set_unicode_output_enabled (b: BOOLEAN)
-- if `b' then enable unicode output, otherwise disable.
do
unicode_output_enabled := b
end
feature -- Execution
append_connector_informations_to (req: WSF_REQUEST; res: WSF_RESPONSE; a_output: STRING)
@@ -232,7 +241,7 @@ feature {NONE} -- Implementation
it as c
loop
s.append (" - ")
s.append (utf.escaped_utf_32_string_to_utf_8_string_8 (c.key))
append_unicode (c.key, s)
s.append_character (' ')
if attached c.item as l_item then
s.append_character ('{')
@@ -302,7 +311,11 @@ feature {NONE} -- Implementation
it as c
loop
a_output.append (" - ")
a_output.append (c.item.url_encoded_name)
if unicode_output_enabled then
append_unicode (c.item.name, a_output)
else
a_output.append (c.item.url_encoded_name)
end
t := c.item.generating_type
if t.same_string ("WSF_STRING") then
else
@@ -313,15 +326,15 @@ feature {NONE} -- Implementation
end
a_output.append_character ('=')
if attached {WSF_STRING} c.item as l_str then
s := l_str.url_encoded_value
if unicode_output_enabled then
s := l_str.value
else
s := l_str.url_encoded_value
end
else
s := c.item.string_representation
end
if s.is_valid_as_string_8 then
v := s.as_string_8
else
v := utf.escaped_utf_32_string_to_utf_8_string_8 (s)
end
v := utf.utf_32_string_to_utf_8_string_8 (s)
if v.has ('%N') then
a_output.append (eol)
across
@@ -349,7 +362,6 @@ feature {NONE} -- Implementation
local
n: INTEGER
v: READABLE_STRING_8
utf: UTF_CONVERTER
do
if is_verbose then
a_output.append (a_title)
@@ -368,11 +380,7 @@ feature {NONE} -- Implementation
it as c
loop
a_output.append (" - ")
if c.key.is_valid_as_string_8 then
a_output.append (c.key.as_string_8)
else
a_output.append (utf.utf_32_string_to_utf_8_string_8 (c.key))
end
append_unicode (c.key, a_output)
a_output.append_character ('=')
v := c.item
if v.has ('%N') then
@@ -398,6 +406,13 @@ feature {NONE} -- Implementation
end
end
append_unicode (s: READABLE_STRING_GENERAL; a_output: STRING)
local
utf: UTF_CONVERTER
do
a_output.append (utf.utf_32_string_to_utf_8_string_8 (s))
end
feature -- Constants
eol: STRING = "%N"

View File

@@ -58,13 +58,15 @@ feature -- Status
do
p := a_path
l_uri := based_uri (uri, a_router)
if l_uri.ends_with ("/") then
if not p.ends_with ("/") then
p := p + "/"
end
else
if p.ends_with ("/") then
p := p.substring (1, p.count - 1)
if trailing_slash_ignored then
if l_uri.ends_with ("/") then
if not p.ends_with ("/") then
p := p + "/"
end
else
if p.ends_with ("/") then
p := p.substring (1, p.count - 1)
end
end
end
if p.same_string (l_uri) then

View File

@@ -1,6 +1,5 @@
note
description: "Summary description for {WSF_APPLICATION_X_WWW_FORM_URLENCODED_HANDLER}."
author: ""
date: "$Date$"
revision: "$Revision$"
@@ -12,6 +11,11 @@ inherit
WSF_MIME_HANDLER_HELPER
WSF_VALUE_UTILITIES
export
{NONE} all
end
feature -- Status report
valid_content_type (a_content_type: HTTP_CONTENT_TYPE): BOOLEAN
@@ -54,7 +58,7 @@ feature -- Execution
if j > 0 then
l_name := s.substring (1, j - 1)
l_value := s.substring (j + 1, s.count)
add_string_value_to_table (l_name, l_value, a_vars)
add_percent_encoded_string_value_to_table (l_name, l_value, a_vars)
end
end
end
@@ -62,7 +66,7 @@ feature -- Execution
end
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -1,6 +1,5 @@
note
description: "Summary description for {WSF_MULTIPART_FORM_DATA_HANDLER}."
author: ""
date: "$Date$"
revision: "$Revision$"
@@ -139,10 +138,12 @@ feature {NONE} -- Implementation: Form analyzer
local
n, i,p, b,e: INTEGER
l_name, l_filename, l_content_type: detachable STRING_8
l_unicode_name: READABLE_STRING_32
l_header: detachable STRING_8
l_content: detachable STRING_8
l_line: detachable STRING_8
l_up_file: WSF_UPLOADED_FILE
utf: UTF_CONVERTER
do
from
p := 1
@@ -235,12 +236,13 @@ feature {NONE} -- Implementation: Form analyzer
if l_content_type = Void then
l_content_type := default_content_type
end
create l_up_file.make (l_name, l_filename, l_content_type, l_content.count)
add_value_to_table (l_name, l_up_file, vars)
l_unicode_name := utf.utf_8_string_8_to_string_32 (l_name)
create l_up_file.make (l_unicode_name, utf.utf_8_string_8_to_escaped_string_32 (l_filename), l_content_type, l_content.count)
add_value_to_table (l_unicode_name, l_up_file, vars)
--| `l_up_file' might have a new name
req.save_uploaded_file (l_up_file, l_content)
else
add_string_value_to_table (l_name, l_content, vars)
add_utf_8_string_value_to_table (l_name, l_content, vars)
end
else
req.error_handler.add_custom_error (0, "unamed multipart entry", Void)
@@ -254,7 +256,7 @@ feature {NONE} -- Implementation: Form analyzer
-- Default content type
note
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -34,10 +34,10 @@ feature -- Access
feature -- Element change
change_name (a_name: like name)
-- <Precursor>
do
name := url_decoded_string (a_name)
ensure then
a_name.same_string (url_encoded_name)
name := a_name
url_encoded_name := url_encoded_string (a_name)
end
feature -- Status report
@@ -71,7 +71,7 @@ feature -- Visitor
end
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -89,10 +89,9 @@ feature -- Access
feature -- Element change
change_name (a_name: like name)
-- <Precursor>
do
name := a_name
ensure then
a_name.same_string (name)
end
feature -- Status report
@@ -180,7 +179,7 @@ invariant
string_values_not_empty: values.count >= 1
note
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -16,17 +16,24 @@ inherit
end
create
make
make,
make_with_percent_encoded_values
convert
string_representation: {READABLE_STRING_32, STRING_32}
feature {NONE} -- Initialization
make (a_name: READABLE_STRING_8; a_string: READABLE_STRING_8)
make (a_name: READABLE_STRING_GENERAL; a_string: READABLE_STRING_GENERAL)
do
url_encoded_name := utf_8_percent_encoded_string (a_name)
url_encoded_value := utf_8_percent_encoded_string (a_string)
url_encoded_name := url_encoded_string (a_name)
url_encoded_value := url_encoded_string (a_string)
end
make_with_percent_encoded_values (a_encoded_name: READABLE_STRING_8; a_encoded_value: READABLE_STRING_8)
do
url_encoded_name := a_encoded_name
url_encoded_value := a_encoded_value
end
feature -- Access
@@ -105,11 +112,10 @@ feature -- Status report
feature -- Element change
change_name (a_name: like name)
-- <Precursor>
do
internal_name := Void
url_encoded_name := a_name
ensure then
a_name.same_string (url_encoded_name)
internal_name := a_name
url_encoded_name := url_encoded_string (a_name)
end
feature -- Helper
@@ -147,89 +153,8 @@ feature -- Visitor
vis.process_string (Current)
end
feature {NONE} -- Implementation
utf_8_percent_encoded_string (s: READABLE_STRING_8): READABLE_STRING_8
-- Percent-encode the UTF-8 sequence characters from UTF-8 encoded `s' and
-- return the Result.
local
s8: STRING_8
i, n, nb: INTEGER
do
-- First check if there are such UTF-8 character
-- If it has, convert them and return a new object as Result
-- otherwise return `s' directly to avoid creating a new object
from
i := 1
n := s.count
nb := 0
until
i > n
loop
if s.code (i) > 0x7F then -- >= 128
nb := nb + 1
end
i := i + 1
end
if nb > 0 then
create s8.make (s.count + nb * 3)
utf_8_string_8_into_percent_encoded_string_8 (s, s8)
Result := s8
else
Result := s
end
end
utf_8_string_8_into_percent_encoded_string_8 (s: READABLE_STRING_8; a_result: STRING_8)
-- Copy STRING_32 corresponding to UTF-8 sequence `s' appended into `a_result'.
local
i: INTEGER
n: INTEGER
c: NATURAL_32
do
from
n := s.count
a_result.grow (a_result.count + n)
until
i >= n
loop
i := i + 1
c := s.code (i)
if c <= 0x7F then
-- 0xxxxxxx
a_result.append_code (c)
elseif c <= 0xDF then
-- 110xxxxx 10xxxxxx
url_encoder.append_percent_encoded_character_code_to (c, a_result)
i := i + 1
if i <= n then
url_encoder.append_percent_encoded_character_code_to (s.code (i), a_result)
end
elseif c <= 0xEF then
-- 1110xxxx 10xxxxxx 10xxxxxx
url_encoder.append_percent_encoded_character_code_to (s.code (i), a_result)
i := i + 2
if i <= n then
url_encoder.append_percent_encoded_character_code_to (s.code (i - 1), a_result)
url_encoder.append_percent_encoded_character_code_to (s.code (i), a_result)
end
elseif c <= 0xF7 then
-- 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
url_encoder.append_percent_encoded_character_code_to (s.code (i), a_result)
i := i + 3
if i <= n then
url_encoder.append_percent_encoded_character_code_to (s.code (i - 2), a_result)
url_encoder.append_percent_encoded_character_code_to (s.code (i - 1), a_result)
url_encoder.append_percent_encoded_character_code_to (s.code (i), a_result)
end
else
a_result.append_code (c)
end
end
end
note
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -2,8 +2,8 @@ note
description: "[
Table which can contain value indexed by a key
]"
date: "$Date$"
revision: "$Revision$"
date: "$Date: 2015-11-05 21:52:56 +0100 (jeu., 05 nov. 2015) $"
revision: "$Revision: 98081 $"
class
WSF_TABLE
@@ -14,26 +14,37 @@ inherit
as_string
end
ITERABLE [WSF_VALUE]
TABLE_ITERABLE [WSF_VALUE, READABLE_STRING_32]
create
make
make,
make_with_percent_encoded_name
feature {NONE} -- Initialization
make (a_name: READABLE_STRING_8)
make (a_name: READABLE_STRING_GENERAL)
do
name := url_decoded_string (a_name)
url_encoded_name := a_name
create values.make (5)
name := a_name.as_string_32
url_encoded_name := url_encoded_string (a_name)
create values.make (3)
end
make_with_percent_encoded_name (a_encoded_name: READABLE_STRING_8)
do
url_encoded_name := a_encoded_name
name := url_decoded_string (a_encoded_name)
create values.make (3)
end
feature -- Access
name: READABLE_STRING_32
-- Parameter name
-- <Precursor>
--| Note that the value might be html encoded as well
--| this is the application responsibility to html decode it
url_encoded_name: READABLE_STRING_8
-- URL encoded string of `name'.
first_value: detachable WSF_VALUE
-- First value if any.
@@ -59,13 +70,16 @@ feature -- Access
end
values: HASH_TABLE [WSF_VALUE, STRING_32]
-- Associated items values, indexed by unicode name.
value (k: READABLE_STRING_GENERAL): detachable WSF_VALUE
-- Value associated with name `k'.
do
Result := values.item (k.to_string_32)
end
count: INTEGER
-- Number of values.
do
Result := values.count
end
@@ -77,14 +91,15 @@ feature -- Access
Result := first_name
end
feature -- Element change
feature -- Element change
change_name (a_name: like name)
-- <Precursor>
do
name := url_decoded_string (a_name)
url_encoded_name := a_name
ensure then
a_name.same_string (url_encoded_name)
name := a_name
url_encoded_name := url_encoded_string (a_name)
end
feature -- Status report
@@ -178,7 +193,7 @@ feature -- Element change
feature -- Traversing
new_cursor: ITERATION_CURSOR [WSF_VALUE]
new_cursor: TABLE_ITERATION_CURSOR [WSF_VALUE, READABLE_STRING_32]
do
Result := values.new_cursor
end
@@ -217,7 +232,7 @@ feature -- Visitor
end
note
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -15,17 +15,27 @@ inherit
end
create
make
make,
make_with_percent_encoded_values
feature {NONE} -- Initialization
make (a_name: READABLE_STRING_8; n: like filename; t: like content_type; s: like size)
make (a_name: READABLE_STRING_GENERAL; a_filename: READABLE_STRING_GENERAL; a_content_type: like content_type; a_size: like size)
do
name := url_decoded_string (a_name)
url_encoded_name := a_name
filename := n
content_type := t
size := s
name := a_name.as_string_32
url_encoded_name := url_encoded_string (a_name)
filename := a_filename.as_string_32
content_type := a_content_type
size := a_size
end
make_with_percent_encoded_values (a_encoded_name: READABLE_STRING_8; a_filename: READABLE_STRING_GENERAL; a_content_type: like content_type; a_size: like size)
do
name := url_decoded_string (a_encoded_name)
url_encoded_name := a_encoded_name
filename := a_filename.as_string_32
content_type := a_content_type
size := a_size
end
feature -- Access
@@ -65,11 +75,10 @@ feature -- Status report
feature -- Element change
change_name (a_name: like name)
-- <Precursor>
do
name := url_decoded_string (a_name)
url_encoded_name := a_name
ensure then
a_name.same_string (url_encoded_name)
name := a_name
url_encoded_name := url_encoded_string (a_name)
end
feature -- Status report
@@ -99,7 +108,7 @@ feature -- Visitor
feature -- Access: Uploaded File
filename: STRING
filename: STRING_32
-- original filename
safe_filename: STRING
@@ -241,7 +250,7 @@ feature -- Element change
end
note
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -36,8 +36,10 @@ feature -- Access
feature -- Element change
change_name (a_name: like name)
-- Change parameter name
-- Change parameter `name'.
deferred
ensure
name_changed: a_name.same_string (name)
end
feature -- Status report
@@ -128,7 +130,7 @@ feature -- Visitor
end
note
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -7,122 +7,25 @@ note
deferred class
WSF_MIME_HANDLER_HELPER
inherit
ANY
WSF_VALUE_UTILITIES
export
{NONE} all
end
feature {NONE} -- Implementation
full_input_data (req: WSF_REQUEST): STRING_8
-- Read or reused full input data from `req'.
do
create Result.make (0)
req.read_input_data_into (Result)
end
add_string_value_to_table (a_name: READABLE_STRING_8; a_value: READABLE_STRING_8; a_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_GENERAL])
do
add_value_to_table (a_name, new_string_value (a_name, a_value), a_table)
end
add_value_to_table (a_name: READABLE_STRING_8; a_value: WSF_VALUE; a_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_GENERAL])
local
l_decoded_name: STRING_32
v: detachable WSF_VALUE
n,k,r: STRING_32
-- k32: STRING_32
p,q: INTEGER
tb,ptb: detachable WSF_TABLE
do
--| Check if this is a list format such as choice[] or choice[a] or even choice[a][] or choice[a][b][c]...
l_decoded_name := url_encoder.decoded_string (a_name)
p := l_decoded_name.index_of ({CHARACTER_32}'[', 1)
if p > 0 then
q := l_decoded_name.index_of ({CHARACTER_32}']', p + 1)
if q > p then
n := l_decoded_name.substring (1, p - 1)
r := l_decoded_name.substring (q + 1, l_decoded_name.count)
r.left_adjust; r.right_adjust
create tb.make (n)
if a_table.has_key (tb.name) and then attached {WSF_TABLE} a_table.found_item as l_existing_table then
tb := l_existing_table
end
k := l_decoded_name.substring (p + 1, q - 1)
k.left_adjust; k.right_adjust
if k.is_empty then
k.append_integer (tb.count + 1)
end
v := tb
n.append_character ({CHARACTER_32}'[')
n.append (k)
n.append_character ({CHARACTER_32}']')
from
until
r.is_empty
loop
ptb := tb
p := r.index_of ({CHARACTER_32} '[', 1)
if p > 0 then
q := r.index_of ({CHARACTER_32} ']', p + 1)
if q > p then
if attached {WSF_TABLE} ptb.value (k) as l_tb_value then
tb := l_tb_value
else
create tb.make (n)
ptb.add_value (tb, k)
end
k := r.substring (p + 1, q - 1)
r := r.substring (q + 1, r.count)
r.left_adjust; r.right_adjust
if k.is_empty then
k.append_integer (tb.count + 1)
end
n.append_character ('[')
n.append (k)
n.append_character (']')
end
else
r.wipe_out
--| Ignore bad value
end
end
a_value.change_name (n)
tb.add_value (a_value, k)
else
--| Missing end bracket
end
end
if v = Void then
a_value.change_name (a_name)
v := a_value
end
if a_table.has_key (v.name) and then attached a_table.found_item as l_existing_value then
if tb /= Void then
--| Already done in previous part
elseif attached {WSF_MULTIPLE_STRING} l_existing_value as l_multi then
l_multi.add_value (v)
else
a_table.force (create {WSF_MULTIPLE_STRING}.make_with_array (<<l_existing_value, v>>), v.name)
check replaced: a_table.found and then a_table.found_item ~ l_existing_value end
end
else
a_table.force (v, v.name)
end
end
new_string_value (a_name: READABLE_STRING_8; a_value: READABLE_STRING_8): WSF_STRING
do
create Result.make (a_name, a_value)
end
feature {NONE} -- Implementation
url_encoder: URL_ENCODER
once
create {UTF8_URL_ENCODER} Result
end
note
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -0,0 +1,163 @@
note
description: "[
Utility routines to handle parameters and convert them as string, list or table values.
]"
date: "$Date$"
revision: "$Revision$"
class
WSF_VALUE_UTILITIES
inherit
ANY
SHARED_WSF_PERCENT_ENCODER
rename
percent_encoder as url_encoder
export
{NONE} all
end
feature -- Smart parameter identification
add_utf_8_string_value_to_table (a_utf_8_name: READABLE_STRING_8; a_utf_8_value: READABLE_STRING_8; a_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_GENERAL])
-- Add a utf-8 string value `a_utf_8_value' associated with name `a_utf_8_name' to `a_table'.
local
utf: UTF_CONVERTER
n,v: READABLE_STRING_32
do
n := utf.utf_8_string_8_to_string_32 (a_utf_8_name)
v := utf.utf_8_string_8_to_string_32 (a_utf_8_value)
add_value_to_table (n, new_string_value (n, v), a_table)
end
add_percent_encoded_string_value_to_table (a_encoded_name: READABLE_STRING_8; a_encoded_value: READABLE_STRING_8; a_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_GENERAL])
-- Add a percent-encoded string value `a_encoded_value' associated with name `a_encoded_name' to `a_table'.
local
v: WSF_STRING
do
v := new_string_value_with_percent_encoded_values (a_encoded_name, a_encoded_value)
add_value_to_table (v.name, v, a_table)
end
add_value_to_table (a_name: READABLE_STRING_GENERAL; a_value: WSF_VALUE; a_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_GENERAL])
-- Add value `a_value' associated with unicode name `a_name' to `a_table'.
local
l_decoded_name: STRING_32
l_encoded_name: READABLE_STRING_8
v: detachable WSF_VALUE
n,k,r,vn: STRING_32
p,q: INTEGER
tb,ptb: detachable WSF_TABLE
do
--| Check if this is a list format such as choice[] or choice[a] or even choice[a][] or choice[a][b][c]...
l_decoded_name := a_name.as_string_32
l_encoded_name := a_value.url_encoded_name
p := l_decoded_name.index_of ({CHARACTER_32}'[', 1)
n := l_decoded_name
if p > 0 then
q := l_decoded_name.index_of ({CHARACTER_32}']', p + 1)
if q > p then
n := l_decoded_name.substring (1, p - 1)
r := l_decoded_name.substring (q + 1, l_decoded_name.count)
r.left_adjust; r.right_adjust
create tb.make (n)
if attached {WSF_TABLE} a_table.item (tb.name) as l_existing_table then
tb := l_existing_table
end
k := l_decoded_name.substring (p + 1, q - 1)
k.left_adjust; k.right_adjust
if k.is_empty then
k.append_integer (tb.count + 1)
end
v := tb
create vn.make_from_string (n)
vn.append_character ({CHARACTER_32}'[')
vn.append (k)
vn.append_character ({CHARACTER_32}']')
from
until
r.is_empty
loop
ptb := tb
p := r.index_of ({CHARACTER_32} '[', 1)
if p > 0 then
q := r.index_of ({CHARACTER_32} ']', p + 1)
if q > p then
if attached {WSF_TABLE} ptb.value (k) as l_tb_value then
tb := l_tb_value
else
create tb.make (n)
ptb.add_value (tb, k)
end
k := r.substring (p + 1, q - 1)
r := r.substring (q + 1, r.count)
r.left_adjust; r.right_adjust
if k.is_empty then
k.append_integer (tb.count + 1)
end
vn.append_character ('[')
vn.append (k)
vn.append_character (']')
end
else
r.wipe_out
--| Ignore bad value
end
end
a_value.change_name (vn)
tb.add_value (a_value, k)
else
--| Missing end bracket
end
end
if v = Void then
a_value.change_name (l_decoded_name)
v := a_value
end
if attached a_table.item (n) as l_existing_value then
if tb /= Void then
--| Already done in previous part
elseif attached {WSF_MULTIPLE_STRING} l_existing_value as l_multi then
l_multi.add_value (v)
elseif attached {WSF_TABLE} l_existing_value as l_table then
-- Keep previous values (most likely we have table[1]=foo, table[2]=bar ..and table=/foo/bar
-- Anyway for this case, we keep the previous version, and ignore this "conflict"
else
a_table.force (create {WSF_MULTIPLE_STRING}.make_with_array (<<l_existing_value, v>>), v.name)
check replaced: a_table.found and then a_table.found_item ~ l_existing_value end
end
else
a_table.force (v, n)
end
end
feature -- Factory
new_string_value (a_name: READABLE_STRING_GENERAL; a_value: READABLE_STRING_GENERAL): WSF_STRING
-- New WSF_STRING value built from unicode `a_name' and `a_value'.
do
create Result.make (a_name, a_value)
end
new_string_value_with_percent_encoded_values (a_encoded_name: READABLE_STRING_8; a_encoded_value: READABLE_STRING_8): WSF_STRING
-- New WSF_STRING value built from utf8+percent encoded `a_encoded_name' and `a_encoded_value'.
do
create Result.make_with_percent_encoded_values (a_encoded_name, a_encoded_value)
end
note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -20,8 +20,8 @@ note
About https support: `is_https' indicates if the request is made through an https connection or not.
]"
date: "$Date: 2014-05-14 16:52:42 +0200 (mer., 14 mai 2014) $"
revision: "$Revision: 95057 $"
date: "$Date$"
revision: "$Revision$"
class
WSF_REQUEST
@@ -41,6 +41,11 @@ inherit
{NONE} all
end
WSF_VALUE_UTILITIES
export
{NONE} all
end
create {WSF_EXECUTION, WGI_EXPORTER}
make_from_wgi
@@ -846,7 +851,7 @@ feature -- Access: CGI meta parameters - 1.1
local
l_result: like internal_percent_encoded_path_info
r: READABLE_STRING_8
i: INTEGER
i,m,n,spos: INTEGER
do
l_result := internal_percent_encoded_path_info
if l_result = Void then
@@ -860,6 +865,28 @@ feature -- Access: CGI meta parameters - 1.1
if attached script_name as s then
if l_result.starts_with (s) then
l_result := l_result.substring (s.count + 1, l_result.count)
else
--| Handle Rewrite url engine, to have clean path
from
i := 1
m := l_result.count
n := s.count
until
i > m or i > n or l_result[i] /= s[i]
loop
if l_result[i] = '/' then
spos := i
end
i := i + 1
end
if i > 1 then
if l_result[i-1] = '/' then
i := i -1
elseif spos > 0 then
i := spos
end
l_result := l_result.substring (i, m)
end
end
end
internal_percent_encoded_path_info := l_result
@@ -1399,7 +1426,7 @@ feature {NONE} -- Cookies
k.left_adjust
k.right_adjust
if not k.is_empty then
add_value_to_table (k, v, l_cookies)
add_percent_encoded_string_value_to_table (k, v, l_cookies)
end
end
end
@@ -1463,7 +1490,7 @@ feature {WSF_REQUEST_PATH_PARAMETERS_SOURCE} -- Path parameters: Element change
across
lst as c
loop
add_value_to_table (c.key, c.item, l_table)
add_percent_encoded_string_value_to_table (c.key, c.item, l_table)
end
src.update_path_parameters (l_table)
end
@@ -1494,7 +1521,7 @@ feature {NONE} -- Query parameters: implementation
vars: like internal_query_parameters_table
p,e: INTEGER
rq_uri: like request_uri
s: detachable STRING
s: detachable READABLE_STRING_8
do
vars := internal_query_parameters_table
if vars = Void then
@@ -1556,7 +1583,7 @@ feature {NONE} -- Query parameters: implementation
l_name := s
l_value := empty_string_8
end
add_value_to_table (l_name, l_value, Result)
add_percent_encoded_string_value_to_table (l_name, l_value, Result)
end
end
end
@@ -1715,100 +1742,6 @@ feature {NONE} -- Form fields and related
Result := vars
end
feature {NONE} -- Implementation: smart parameter identification
add_value_to_table (a_name: READABLE_STRING_8; a_value: READABLE_STRING_8; a_table: STRING_TABLE [WSF_VALUE])
-- Add urlencoded parameter `a_name'=`a_value' to `a_table'
-- following smart computation such as handling the "..[..]" as table
local
v: detachable WSF_VALUE
n, k, r: STRING_8
k32: STRING_32
p, q: INTEGER
tb, ptb: detachable WSF_TABLE
do
--| Check if this is a list format such as choice[] or choice[a] or even choice[a][] or choice[a][b][c]...
p := a_name.index_of ('[', 1)
if p > 0 then
q := a_name.index_of (']', p + 1)
if q > p then
n := a_name.substring (1, p - 1)
r := a_name.substring (q + 1, a_name.count)
r.left_adjust; r.right_adjust
create tb.make (n)
if a_table.has_key (tb.name) and then attached {WSF_TABLE} a_table.found_item as l_existing_table then
tb := l_existing_table
end
k := a_name.substring (p + 1, q - 1)
k.left_adjust; k.right_adjust
if k.is_empty then
k.append_integer (tb.count + 1)
end
v := tb
create n.make_from_string (n)
n.append_character ('[')
n.append (k)
n.append_character (']')
from
until
r.is_empty
loop
ptb := tb
p := r.index_of ({CHARACTER_8} '[', 1)
if p > 0 then
q := r.index_of ({CHARACTER_8} ']', p + 1)
if q > p then
k32 := url_decoded_string (k)
if attached {WSF_TABLE} ptb.value (k32) as l_tb_value then
tb := l_tb_value
else
create tb.make (n)
ptb.add_value (tb, k32)
end
k := r.substring (p + 1, q - 1)
r := r.substring (q + 1, r.count)
r.left_adjust; r.right_adjust
if k.is_empty then
k.append_integer (tb.count + 1)
end
n.append_character ('[')
n.append (k)
n.append_character (']')
end
else
r.wipe_out
--| Ignore bad value
end
end
tb.add_value (new_string_value (n, a_value), k)
else
--| Missing end bracket
end
end
if v = Void then
v := new_string_value (a_name, a_value)
end
if a_table.has_key (v.name) and then attached a_table.found_item as l_existing_value then
if tb /= Void then
--| Already done in previous part
elseif attached {WSF_MULTIPLE_STRING} l_existing_value as l_multi then
l_multi.add_value (v)
elseif attached {WSF_TABLE} l_existing_value as l_table then
-- Keep previous values (most likely we have table[1]=foo, table[2]=bar ..and table=/foo/bar
-- Anyway for this case, we keep the previous version, and ignore this "conflict"
else
a_table.force (create {WSF_MULTIPLE_STRING}.make_with_array (<<l_existing_value, v>>), v.name)
check replaced: a_table.found and then a_table.found_item ~ l_existing_value end
end
else
a_table.force (v, v.name)
end
end
feature -- Uploaded File Handling
is_uploaded_file (a_filename: READABLE_STRING_GENERAL): BOOLEAN
@@ -2133,11 +2066,6 @@ feature {NONE} -- Implementation: utilities
one_starting_slash: Result[1] = '/' and (Result.count = 1 or else Result[2] /= '/')
end
new_string_value (a_name: READABLE_STRING_8; a_value: READABLE_STRING_8): WSF_STRING
do
create Result.make (a_name, a_value)
end
empty_string_32: IMMUTABLE_STRING_32
-- Reusable empty string
once

View File

@@ -564,7 +564,7 @@ feature {NONE} -- Implemenation
loop
j := j + 1
end
if j > n then
if j <= n then
Result := a_cookie_name.same_characters (a_cookie_line, j, i, 1)
end
end

View File

@@ -70,6 +70,7 @@ feature -- Conversion
a_html.append ("<td")
append_css_class_to (a_html, Void)
append_css_style_to (a_html)
append_html_attributes_to (a_html)
a_html.append_character ('>')
content.append_to_html (a_theme, a_html)
a_html.append ("</td>")

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-14-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-14-0 http://www.eiffel.com/developers/xml/configuration-1-14-0.xsd" name="tests" uuid="C68BD5DC-F756-484E-A9FE-F2D1FD432B2A">
<target name="tests">
<root class="ANY" feature="default_create"/>
<setting name="console_application" value="false"/>
<setting name="concurrency" value="none"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="feed" location="..\feed.ecf"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing.ecf"/>
<tests name="src" location=".\" recursive="true"/>
</target>
</system>