Merge branch 'master' of github.com:EiffelWebFramework/EWF into widget_integration
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="wsf_all" uuid="223E2E7D-AA90-4ADC-93CB-D304E794E3E6" library_target="wsf_all">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-12-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-12-0 http://www.eiffel.com/developers/xml/configuration-1-12-0.xsd" name="wsf_all" uuid="223E2E7D-AA90-4ADC-93CB-D304E794E3E6" library_target="wsf_all">
|
||||
<target name="wsf_all">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
@@ -10,21 +10,20 @@
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||
<library name="ewsgi" location="../../ewsgi/ewsgi-safe.ecf"/>
|
||||
<library name="wsf" location="../wsf-safe.ecf"/>
|
||||
<library name="connector_cgi" location="../../ewsgi/connectors/cgi/cgi-safe.ecf"/>
|
||||
<library name="connector_libfcgi" location="../../ewsgi/connectors/libfcgi/libfcgi-safe.ecf"/>
|
||||
<library name="connector_nino" location="../../ewsgi/connectors/nino/nino-safe.ecf"/>
|
||||
<library name="connector_cgi" location="..\..\ewsgi\connectors\cgi\cgi-safe.ecf"/>
|
||||
<library name="connector_libfcgi" location="..\..\ewsgi\connectors\libfcgi\libfcgi-safe.ecf"/>
|
||||
<library name="connector_nino" location="..\..\ewsgi\connectors\nino\nino-safe.ecf"/>
|
||||
<library name="encoder" location="..\..\..\text\encoder\encoder-safe.ecf" readonly="false"/>
|
||||
<library name="error" location="..\..\..\utility\general\error\error-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf"/>
|
||||
<library name="http" location="..\..\..\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="nino" location="nino-safe.ecf" readonly="false">
|
||||
<renaming old_name="HTTP_CONSTANTS" new_name="NINO_HTTP_CONSTANTS"/>
|
||||
</library>
|
||||
|
||||
<library name="error" location="../../../utility/general/error/error-safe.ecf"/>
|
||||
<library name="http" location="../../../network/protocol/http/http-safe.ecf"/>
|
||||
<library name="encoder" location="..\..\..\text\encoder\encoder-safe.ecf" readonly="false"/>
|
||||
<cluster name="wsf_nino" location="./nino" recursive="true"/>
|
||||
<cluster name="wsf_cgi" location="./cgi" recursive="true"/>
|
||||
<cluster name="wsf_libfcgi" location="./libfcgi" recursive="true"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||
<library name="wsf" location="..\wsf-safe.ecf"/>
|
||||
<cluster name="wsf_cgi" location=".\cgi\" recursive="true"/>
|
||||
<cluster name="wsf_libfcgi" location=".\libfcgi\" recursive="true"/>
|
||||
<cluster name="wsf_nino" location=".\nino\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-10-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-10-0 http://www.eiffel.com/developers/xml/configuration-1-10-0.xsd" name="wsf_nino" uuid="BACF0220-900B-4409-8CB2-30A09836A650" library_target="wsf_nino">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-12-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-12-0 http://www.eiffel.com/developers/xml/configuration-1-12-0.xsd" name="wsf_nino" uuid="BACF0220-900B-4409-8CB2-30A09836A650" library_target="wsf_nino">
|
||||
<target name="wsf_nino">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="wsf_openshift" uuid="39488429-3940-4360-9A32-FE53298C2CA2" library_target="wsf_openshift">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-12-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-12-0 http://www.eiffel.com/developers/xml/configuration-1-12-0.xsd" name="wsf_openshift" uuid="39488429-3940-4360-9A32-FE53298C2CA2" library_target="wsf_openshift">
|
||||
<target name="wsf_openshift">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
@@ -10,9 +10,9 @@
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="ewsgi" location="../../ewsgi/ewsgi-safe.ecf"/>
|
||||
<library name="wsf" location="../wsf-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf"/>
|
||||
<library name="wsf" location="..\wsf-safe.ecf"/>
|
||||
<library name="wsf_connector_nino" location="nino-safe.ecf"/>
|
||||
<cluster name="wsf_openshift" location="./openshift" recursive="true"/>
|
||||
<cluster name="wsf_openshift" location=".\openshift\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-11-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-11-0 http://www.eiffel.com/developers/xml/configuration-1-11-0.xsd" name="default_cgi" uuid="A9137009-B5BA-4C58-BCD3-7753909918B5" library_target="default_cgi">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-12-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-12-0 http://www.eiffel.com/developers/xml/configuration-1-12-0.xsd" name="default_cgi" uuid="A9137009-B5BA-4C58-BCD3-7753909918B5" library_target="default_cgi">
|
||||
<target name="default_cgi">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-10-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-10-0 http://www.eiffel.com/developers/xml/configuration-1-10-0.xsd" name="default_nino" uuid="ACBEDC97-956C-45F5-97E3-65A6D9987625" library_target="default_nino">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-12-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-12-0 http://www.eiffel.com/developers/xml/configuration-1-12-0.xsd" name="default_nino" uuid="ACBEDC97-956C-45F5-97E3-65A6D9987625" library_target="default_nino">
|
||||
<target name="default_nino">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="default_openshift" uuid="9EDB2BD1-9E1B-4931-ADD2-2724E3A25CBF" library_target="default_openshift">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-12-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-12-0 http://www.eiffel.com/developers/xml/configuration-1-12-0.xsd" name="default_openshift" uuid="9EDB2BD1-9E1B-4931-ADD2-2724E3A25CBF" library_target="default_openshift">
|
||||
<target name="default_openshift">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
@@ -7,10 +7,11 @@
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional"/>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="wsf" location="../wsf-safe.ecf"/>
|
||||
<library name="wsf_openshift" location="../connector/openshift-safe.ecf"/>
|
||||
<cluster name="default_openshift" location="./openshift" recursive="true"/>
|
||||
<library name="wsf" location="..\wsf-safe.ecf"/>
|
||||
<library name="wsf_openshift" location="..\connector\openshift-safe.ecf"/>
|
||||
<cluster name="default_openshift" location=".\openshift\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
117
library/server/wsf/extension/filter/wsf_debug_filter.e
Normal file
117
library/server/wsf/extension/filter/wsf_debug_filter.e
Normal file
@@ -0,0 +1,117 @@
|
||||
note
|
||||
description: "Summary description for {WSF_DEBUG_FILTER}."
|
||||
date: "$Date: 2013-05-23 21:54:29 +0200 (jeu., 23 mai 2013) $"
|
||||
revision: "$Revision: 92585 $"
|
||||
|
||||
class
|
||||
WSF_DEBUG_FILTER
|
||||
|
||||
inherit
|
||||
WSF_FILTER
|
||||
|
||||
create
|
||||
default_create,
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_output: FILE)
|
||||
do
|
||||
output := a_output
|
||||
end
|
||||
|
||||
output: detachable FILE
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute the filter
|
||||
local
|
||||
s: STRING_8
|
||||
do
|
||||
create s.make (2048)
|
||||
if attached req.content_type as l_type then
|
||||
s.append ("[length=")
|
||||
s.append_natural_64 (req.content_length_value)
|
||||
s.append_character (']')
|
||||
s.append_character (' ')
|
||||
s.append (l_type.debug_output)
|
||||
s.append_character ('%N')
|
||||
end
|
||||
|
||||
append_iterable_to ("Path parameters", req.path_parameters, s)
|
||||
append_iterable_to ("Query parameters", req.query_parameters, s)
|
||||
append_iterable_to ("Form parameters", req.form_parameters, s)
|
||||
|
||||
if not s.is_empty then
|
||||
s.prepend ("**DEBUG**%N")
|
||||
if attached output as o then
|
||||
o.put_string (s)
|
||||
else
|
||||
res.put_error (s)
|
||||
end
|
||||
end
|
||||
execute_next (req, res)
|
||||
end
|
||||
|
||||
append_iterable_to (a_title: READABLE_STRING_8; it: detachable ITERABLE [WSF_VALUE]; s: STRING_8)
|
||||
local
|
||||
n: INTEGER
|
||||
do
|
||||
if it /= Void then
|
||||
across it as c loop
|
||||
n := n + 1
|
||||
end
|
||||
if n > 0 then
|
||||
s.append (a_title)
|
||||
s.append_character (':')
|
||||
s.append_character ('%N')
|
||||
across
|
||||
it as c
|
||||
loop
|
||||
s.append (" - ")
|
||||
s.append (c.item.url_encoded_name)
|
||||
s.append_character (' ')
|
||||
s.append_character ('{')
|
||||
s.append (c.item.generating_type)
|
||||
s.append_character ('}')
|
||||
s.append_character ('=')
|
||||
s.append (c.item.debug_output.as_string_8)
|
||||
s.append_character ('%N')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2013, Eiffel Software"
|
||||
license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
|
||||
licensing_options: "http://www.eiffel.com/licensing"
|
||||
copying: "[
|
||||
This file is part of Eiffel Software's Eiffel Development Environment.
|
||||
|
||||
Eiffel Software's Eiffel Development Environment is free
|
||||
software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation, version 2 of the License
|
||||
(available at the URL listed under "license" above).
|
||||
|
||||
Eiffel Software's Eiffel Development Environment is
|
||||
distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with Eiffel Software's Eiffel Development
|
||||
Environment; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
]"
|
||||
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
|
||||
172
library/server/wsf/extension/handler/wsf_debug_handler.e
Normal file
172
library/server/wsf/extension/handler/wsf_debug_handler.e
Normal file
@@ -0,0 +1,172 @@
|
||||
note
|
||||
description: "Summary description for {WSF_DEBUG_HANDLER}."
|
||||
author: ""
|
||||
date: "$Date: 2013-06-28 16:14:02 +0200 (ven., 28 juin 2013) $"
|
||||
revision: "$Revision: 92754 $"
|
||||
|
||||
class
|
||||
WSF_DEBUG_HANDLER
|
||||
|
||||
inherit
|
||||
WSF_STARTS_WITH_HANDLER
|
||||
rename
|
||||
execute as execute_starts_with
|
||||
end
|
||||
|
||||
WSF_SELF_DOCUMENTED_HANDLER
|
||||
|
||||
SHARED_HTML_ENCODER
|
||||
|
||||
SHARED_WSF_PERCENT_ENCODER
|
||||
rename
|
||||
percent_encoder as url_encoder
|
||||
export
|
||||
{NONE} all
|
||||
end
|
||||
|
||||
SHARED_EXECUTION_ENVIRONMENT
|
||||
export
|
||||
{NONE} all
|
||||
end
|
||||
|
||||
create
|
||||
make,
|
||||
make_hidden
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
end
|
||||
|
||||
make_hidden
|
||||
do
|
||||
make
|
||||
is_hidden := True
|
||||
end
|
||||
|
||||
is_hidden: BOOLEAN
|
||||
-- Current mapped handler should be hidden from self documentation
|
||||
|
||||
feature -- Documentation
|
||||
|
||||
mapping_documentation (m: WSF_ROUTER_MAPPING; a_request_methods: detachable WSF_REQUEST_METHODS): WSF_ROUTER_MAPPING_DOCUMENTATION
|
||||
-- <Precursor>
|
||||
do
|
||||
create Result.make (m)
|
||||
Result.set_is_hidden (is_hidden)
|
||||
Result.add_description ("Debug handler (mainly to return request information)")
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
execute_starts_with (a_path: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
s: STRING_8
|
||||
p: WSF_PAGE_RESPONSE
|
||||
v: STRING_8
|
||||
do
|
||||
create s.make (2048)
|
||||
s.append ("**DEBUG**%N")
|
||||
req.set_raw_input_data_recorded (True)
|
||||
|
||||
append_iterable_to ("Meta variables:", req.meta_variables, s)
|
||||
s.append_character ('%N')
|
||||
|
||||
append_iterable_to ("Path parameters", req.path_parameters, s)
|
||||
s.append_character ('%N')
|
||||
|
||||
append_iterable_to ("Query parameters", req.query_parameters, s)
|
||||
s.append_character ('%N')
|
||||
|
||||
append_iterable_to ("Form parameters", req.form_parameters, s)
|
||||
s.append_character ('%N')
|
||||
|
||||
if attached req.content_type as l_type then
|
||||
s.append ("Content: type=" + l_type.debug_output)
|
||||
s.append (" length=")
|
||||
s.append_natural_64 (req.content_length_value)
|
||||
s.append_character ('%N')
|
||||
create v.make (req.content_length_value.to_integer_32)
|
||||
req.read_input_data_into (v)
|
||||
across
|
||||
v.split ('%N') as v_cursor
|
||||
loop
|
||||
s.append (" |")
|
||||
s.append (v_cursor.item)
|
||||
s.append_character ('%N')
|
||||
end
|
||||
end
|
||||
|
||||
create p.make_with_body (s)
|
||||
p.header.put_content_type_text_plain
|
||||
res.send (p)
|
||||
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
append_iterable_to (a_title: READABLE_STRING_8; it: detachable ITERABLE [WSF_VALUE]; s: STRING_8)
|
||||
local
|
||||
n: INTEGER
|
||||
t: READABLE_STRING_8
|
||||
v: READABLE_STRING_8
|
||||
do
|
||||
s.append (a_title)
|
||||
s.append_character (':')
|
||||
if it /= Void then
|
||||
across it as c loop
|
||||
n := n + 1
|
||||
end
|
||||
if n = 0 then
|
||||
s.append (" empty")
|
||||
s.append_character ('%N')
|
||||
else
|
||||
s.append_character ('%N')
|
||||
across
|
||||
it as c
|
||||
loop
|
||||
s.append (" - ")
|
||||
s.append (c.item.url_encoded_name)
|
||||
t := c.item.generating_type
|
||||
if t.same_string ("WSF_STRING") then
|
||||
else
|
||||
s.append_character (' ')
|
||||
s.append_character ('{')
|
||||
s.append (t)
|
||||
s.append_character ('}')
|
||||
end
|
||||
s.append_character ('=')
|
||||
v := c.item.string_representation.as_string_8
|
||||
if v.has ('%N') then
|
||||
s.append_character ('%N')
|
||||
across
|
||||
v.split ('%N') as v_cursor
|
||||
loop
|
||||
s.append (" |")
|
||||
s.append (v_cursor.item)
|
||||
s.append_character ('%N')
|
||||
end
|
||||
else
|
||||
s.append (v)
|
||||
s.append_character ('%N')
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
s.append (" none")
|
||||
s.append_character ('%N')
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, 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
|
||||
@@ -25,14 +25,14 @@ feature {WSF_ROUTER} -- Routes change
|
||||
do
|
||||
l_routes := available_routes
|
||||
if l_routes = Void then
|
||||
create {ARRAYED_LIST [like available_routes.item]} l_routes.make (3)
|
||||
create {ARRAYED_LIST [TUPLE [resource: READABLE_STRING_8; rqst_methods: detachable ARRAY [READABLE_STRING_8]]]} l_routes.make (3)
|
||||
available_routes := l_routes
|
||||
end
|
||||
l_routes.force ([a_resource, a_rqst_methods])
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
@@ -1,5 +1,5 @@
|
||||
${NOTE_KEYWORD}
|
||||
copyright: "2011-${YEAR}, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-${YEAR}, 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
|
||||
|
||||
@@ -13,7 +13,7 @@ inherit
|
||||
WSF_METHOD_HELPER
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
|
||||
send_response (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER; a_header: HTTP_HEADER; a_new_resource: BOOLEAN)
|
||||
-- Write response to deletion of resource named by `req' into `res'.
|
||||
-- Upto four execution variables may be set on `req':
|
||||
@@ -63,4 +63,14 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Colin Adams, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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
|
||||
|
||||
@@ -60,7 +60,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2013, Colin Adams, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -167,12 +167,12 @@ feature -- Content negotiation
|
||||
res_attached: res /= Void
|
||||
a_handler_attached: a_handler /= Void
|
||||
local
|
||||
l_conneg: CONNEG_SERVER_SIDE
|
||||
l_conneg: SERVER_CONTENT_NEGOTIATION
|
||||
h: HTTP_HEADER
|
||||
l_media: MEDIA_TYPE_VARIANT_RESULTS
|
||||
l_lang: LANGUAGE_VARIANT_RESULTS
|
||||
l_charset: CHARACTER_ENCODING_VARIANT_RESULTS
|
||||
l_encoding: COMPRESSION_VARIANT_RESULTS
|
||||
l_media: HTTP_ACCEPT_MEDIA_TYPE_VARIANTS
|
||||
l_lang: HTTP_ACCEPT_LANGUAGE_VARIANTS
|
||||
l_charset: HTTP_ACCEPT_CHARSET_VARIANTS
|
||||
l_encoding: HTTP_ACCEPT_ENCODING_VARIANTS
|
||||
l_mime_types, l_langs, l_charsets, l_encodings: LIST [STRING]
|
||||
l_vary_star: BOOLEAN
|
||||
do
|
||||
@@ -188,7 +188,7 @@ feature -- Content negotiation
|
||||
l_conneg := a_handler.conneg (req)
|
||||
l_mime_types := a_handler.mime_types_supported (req)
|
||||
l_media := l_conneg.media_type_preference (l_mime_types, req.http_accept)
|
||||
if not l_vary_star and l_mime_types.count > 1 and attached l_media.variant_header as l_media_variant then
|
||||
if not l_vary_star and l_mime_types.count > 1 and attached l_media.media_type as l_media_variant then
|
||||
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_media_variant)
|
||||
end
|
||||
if not l_media.is_acceptable then
|
||||
@@ -196,26 +196,26 @@ feature -- Content negotiation
|
||||
else
|
||||
l_langs := a_handler.languages_supported (req)
|
||||
l_lang := l_conneg.language_preference (l_langs, req.http_accept_language)
|
||||
if not l_vary_star and l_langs.count > 1 and attached l_lang.variant_header as l_lang_variant then
|
||||
if not l_vary_star and l_langs.count > 1 and attached l_lang.language as l_lang_variant then
|
||||
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_lang_variant)
|
||||
end
|
||||
if not l_lang.is_acceptable then
|
||||
handle_not_acceptable ("None of the requested languages were acceptable", l_langs, req, res)
|
||||
else
|
||||
if attached l_lang.language_type as l_language_type then
|
||||
if attached l_lang.language as l_language_type then
|
||||
h.put_content_language (l_language_type)
|
||||
req.set_execution_variable (a_handler.Negotiated_language_execution_variable, l_language_type)
|
||||
end
|
||||
l_charsets := a_handler.charsets_supported (req)
|
||||
l_charset := l_conneg.charset_preference (l_charsets, req.http_accept_charset)
|
||||
if not l_vary_star and l_charsets.count > 1 and attached l_charset.variant_header as l_charset_variant then
|
||||
if not l_vary_star and l_charsets.count > 1 and attached l_charset.charset as l_charset_variant then
|
||||
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_charset_variant)
|
||||
end
|
||||
if not l_charset.is_acceptable then
|
||||
handle_not_acceptable ("None of the requested character encodings were acceptable", l_charsets, req, res)
|
||||
else
|
||||
if attached l_media.media_type as l_media_type then
|
||||
if attached l_charset.character_type as l_character_type then
|
||||
if attached l_charset.charset as l_character_type then
|
||||
h.put_content_type (l_media_type + "; charset=" + l_character_type)
|
||||
req.set_execution_variable (a_handler.Negotiated_charset_execution_variable, l_charset)
|
||||
else
|
||||
@@ -225,13 +225,13 @@ feature -- Content negotiation
|
||||
end
|
||||
l_encodings := a_handler.encodings_supported (req)
|
||||
l_encoding := l_conneg.encoding_preference (l_encodings, req.http_accept_encoding)
|
||||
if not l_vary_star and l_encodings.count > 1 and attached l_encoding.variant_header as l_encoding_variant then
|
||||
if not l_vary_star and l_encodings.count > 1 and attached l_encoding.encoding as l_encoding_variant then
|
||||
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_encoding_variant)
|
||||
end
|
||||
if not l_encoding.is_acceptable then
|
||||
handle_not_acceptable ("None of the requested transfer encodings were acceptable", l_encodings, req, res)
|
||||
else
|
||||
if attached l_encoding.compression_type as l_compression_type then
|
||||
if attached l_encoding.encoding as l_compression_type then
|
||||
h.put_content_encoding (l_compression_type)
|
||||
req.set_execution_variable (a_handler.Negotiated_encoding_execution_variable, l_compression_type)
|
||||
end
|
||||
@@ -376,10 +376,11 @@ feature -- Error reporting
|
||||
local
|
||||
h: HTTP_HEADER
|
||||
m: READABLE_STRING_8
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
m := req.error_handler.as_string_representation
|
||||
m := utf.string_32_to_utf_8_string_8 (req.error_handler.as_string_representation)
|
||||
create h.make
|
||||
h.put_content_type_text_plain
|
||||
h.put_content_type_utf_8_text_plain
|
||||
h.put_content_length (m.count)
|
||||
res.set_status_code (req.error_handler.primary_error_code)
|
||||
res.put_header_lines (h)
|
||||
@@ -586,7 +587,7 @@ feature -- Error reporting
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, Colin Adams, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -30,7 +30,7 @@ feature -- Factory
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2013, Colin Adams, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -68,7 +68,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2013, Colin Adams, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -70,7 +70,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2013, Colin Adams, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -89,7 +89,7 @@ feature -- Access
|
||||
deferred
|
||||
end
|
||||
|
||||
conneg (req: WSF_REQUEST): CONNEG_SERVER_SIDE
|
||||
conneg (req: WSF_REQUEST): SERVER_CONTENT_NEGOTIATION
|
||||
-- Content negotiation for `req';
|
||||
-- This would normally be a once object, ignoring `req'.
|
||||
require
|
||||
@@ -103,7 +103,7 @@ feature -- Access
|
||||
req_attached: req /= Void
|
||||
deferred
|
||||
ensure
|
||||
mime_types_supported_includes_default: Result.has (conneg (req).mime_default)
|
||||
mime_types_supported_includes_default: Result.has (conneg (req).default_media_type)
|
||||
end
|
||||
|
||||
languages_supported (req: WSF_REQUEST): LIST [STRING]
|
||||
@@ -112,7 +112,7 @@ feature -- Access
|
||||
req_attached: req /= Void
|
||||
deferred
|
||||
ensure
|
||||
languages_supported_includes_default: Result.has (conneg (req).language_default)
|
||||
languages_supported_includes_default: Result.has (conneg (req).default_language)
|
||||
end
|
||||
|
||||
charsets_supported (req: WSF_REQUEST): LIST [STRING]
|
||||
@@ -121,7 +121,7 @@ feature -- Access
|
||||
req_attached: req /= Void
|
||||
deferred
|
||||
ensure
|
||||
charsets_supported_includes_default: Result.has (conneg (req).charset_default)
|
||||
charsets_supported_includes_default: Result.has (conneg (req).default_charset)
|
||||
end
|
||||
|
||||
encodings_supported (req: WSF_REQUEST): LIST [STRING]
|
||||
@@ -130,7 +130,7 @@ feature -- Access
|
||||
req_attached: req /= Void
|
||||
deferred
|
||||
ensure
|
||||
encodings_supported_includes_default: Result.has (conneg (req).encoding_default)
|
||||
encodings_supported_includes_default: Result.has (conneg (req).default_encoding)
|
||||
end
|
||||
|
||||
additional_variant_headers (req: WSF_REQUEST): detachable LIST [STRING]
|
||||
@@ -484,6 +484,8 @@ feature -- Execution
|
||||
check_resource_exists (req, a_helper)
|
||||
if a_helper.resource_exists then
|
||||
a_helper.execute_existing_resource (req, res, Current)
|
||||
elseif req.error_handler.has_error then
|
||||
a_helper.write_error_response (req, res)
|
||||
else
|
||||
if attached req.http_if_match as l_if_match and then l_if_match.same_string ("*") then
|
||||
a_helper.handle_precondition_failed (req, res)
|
||||
@@ -536,9 +538,8 @@ feature {NONE} -- Implementation
|
||||
body_sent: res.message_committed and then res.transfered_content_length > 0
|
||||
end
|
||||
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2013, Colin Adams, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -98,8 +98,8 @@ feature {WSF_RESPONSE} -- Output
|
||||
local
|
||||
h: HTTP_HEADER
|
||||
l_description: STRING_8
|
||||
l_base_url: STRING_8
|
||||
l_api_resource: detachable STRING_8
|
||||
l_base_url: READABLE_STRING_8
|
||||
l_api_resource: detachable READABLE_STRING_8
|
||||
do
|
||||
create h.make
|
||||
h.put_content_type_text_html
|
||||
@@ -132,7 +132,7 @@ feature {WSF_RESPONSE} -- Output
|
||||
if attached router.base_url as u then
|
||||
l_base_url := u
|
||||
else
|
||||
create l_base_url.make_empty
|
||||
create {STRING_8} l_base_url.make_empty
|
||||
end
|
||||
|
||||
debug
|
||||
@@ -324,7 +324,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
note
|
||||
description: "[
|
||||
Interface defining a self documented handler using a function
|
||||
to build the `mapping_documentation'
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
WSF_SELF_DOCUMENTED_AGENT_HANDLER
|
||||
|
||||
inherit
|
||||
WSF_SELF_DOCUMENTED_HANDLER
|
||||
|
||||
feature -- Access
|
||||
|
||||
is_hidden: BOOLEAN
|
||||
-- Is hidden from self documentation?
|
||||
|
||||
descriptions: detachable ARRAYED_LIST [READABLE_STRING_GENERAL]
|
||||
|
||||
self_documentation_builder: detachable FUNCTION [ANY, TUPLE [WSF_ROUTER_MAPPING, detachable WSF_REQUEST_METHODS], WSF_ROUTER_MAPPING_DOCUMENTATION]
|
||||
-- Function building the `mapping_documentation'.
|
||||
|
||||
feature -- Change
|
||||
|
||||
add_description (d: READABLE_STRING_GENERAL)
|
||||
local
|
||||
lst: like descriptions
|
||||
do
|
||||
lst := descriptions
|
||||
if lst = Void then
|
||||
create lst.make (1)
|
||||
descriptions := lst
|
||||
end
|
||||
lst.force (d)
|
||||
end
|
||||
|
||||
set_self_documentation_builder (fct: like self_documentation_builder)
|
||||
-- Set `self_documentation_builder' to `fct'.
|
||||
do
|
||||
self_documentation_builder := fct
|
||||
end
|
||||
|
||||
feature -- Documentation
|
||||
|
||||
mapping_documentation (m: WSF_ROUTER_MAPPING; a_request_methods: detachable WSF_REQUEST_METHODS): WSF_ROUTER_MAPPING_DOCUMENTATION
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached self_documentation_builder as fct then
|
||||
Result := fct.item ([m, a_request_methods])
|
||||
else
|
||||
create Result.make (m)
|
||||
end
|
||||
if attached descriptions as l_descriptions then
|
||||
across
|
||||
l_descriptions as c
|
||||
loop
|
||||
Result.add_description (c.item)
|
||||
end
|
||||
end
|
||||
if is_hidden then
|
||||
Result.set_is_hidden (True)
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, 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
|
||||
@@ -1,6 +1,10 @@
|
||||
note
|
||||
description: "Summary description for {WSF_SELF_DOCUMENTED_HANDLER}."
|
||||
author: ""
|
||||
description: "[
|
||||
Interface defining a self documented handler
|
||||
|
||||
inherit from this class and define mapping_documentation to generate
|
||||
auto self documentation on demand.
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ feature -- Basic operations
|
||||
do
|
||||
create l_header.make
|
||||
l_header.put_access_control_allow_all_origin
|
||||
res.put_header_text (l_header.string)
|
||||
res.put_header_lines (l_header)
|
||||
execute_next (req, res)
|
||||
end
|
||||
|
||||
|
||||
66
library/server/wsf/router/filter/wsf_custom_header_filter.e
Normal file
66
library/server/wsf/router/filter/wsf_custom_header_filter.e
Normal file
@@ -0,0 +1,66 @@
|
||||
note
|
||||
description: "Summary description for {WSF_CUSTOM_HEADER_FILTER}."
|
||||
date: "$Date: 2013-05-23 21:54:29 +0200 (jeu., 23 mai 2013) $"
|
||||
revision: "$Revision: 92585 $"
|
||||
|
||||
class
|
||||
WSF_CUSTOM_HEADER_FILTER
|
||||
|
||||
inherit
|
||||
WSF_FILTER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (n: INTEGER)
|
||||
do
|
||||
create custom_header.make_with_count (n)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
custom_header: HTTP_HEADER
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute the filter
|
||||
do
|
||||
res.put_header_lines (custom_header)
|
||||
execute_next (req, res)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2013, Eiffel Software"
|
||||
license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
|
||||
licensing_options: "http://www.eiffel.com/licensing"
|
||||
copying: "[
|
||||
This file is part of Eiffel Software's Eiffel Development Environment.
|
||||
|
||||
Eiffel Software's Eiffel Development Environment is free
|
||||
software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation, version 2 of the License
|
||||
(available at the URL listed under "license" above).
|
||||
|
||||
Eiffel Software's Eiffel Development Environment is
|
||||
distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with Eiffel Software's Eiffel Development
|
||||
Environment; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
]"
|
||||
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
|
||||
@@ -61,6 +61,7 @@ feature -- Basic operations
|
||||
create h.make_with_count (1)
|
||||
h.put_content_length (s.count)
|
||||
h.put_content_type_text_plain
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.service_unavailable)
|
||||
res.put_header_lines (h)
|
||||
res.put_string (s)
|
||||
else
|
||||
@@ -69,7 +70,7 @@ feature -- Basic operations
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
@@ -275,7 +275,7 @@ invariant
|
||||
unavailability_duration_xor_unavailable_until: unavailability_duration > 0 implies unavailable_until = Void
|
||||
|
||||
;note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2013, 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
|
||||
|
||||
@@ -125,7 +125,7 @@ feature -- Access
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2013, 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
|
||||
|
||||
@@ -6,7 +6,7 @@ note
|
||||
Users of this policy cannot safely use chunked transfer-encoding, or any
|
||||
HTTP/1.1-specific features. So best used only for examples.
|
||||
]"
|
||||
|
||||
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
@@ -18,7 +18,7 @@ inherit
|
||||
redefine
|
||||
requires_proxy
|
||||
end
|
||||
|
||||
|
||||
feature -- Access
|
||||
|
||||
requires_proxy (req: WSF_REQUEST): BOOLEAN
|
||||
@@ -33,4 +33,14 @@ feature -- Access
|
||||
-- doesn't meet the postcondition, but the precondition is never true.
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, 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
|
||||
|
||||
@@ -34,4 +34,14 @@ feature -- Basic operations
|
||||
res.put_header_text (h.string)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, 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
|
||||
|
||||
@@ -51,7 +51,7 @@ feature -- Access
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2013, 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
|
||||
|
||||
@@ -51,7 +51,7 @@ feature -- Access
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2013, 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
|
||||
|
||||
@@ -15,7 +15,7 @@ note
|
||||
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
|
||||
class WSF_SYSTEM_OPTIONS_ACCESS_POLICY
|
||||
|
||||
feature -- Access
|
||||
@@ -23,7 +23,7 @@ feature -- Access
|
||||
is_system_options_forbidden (req: WSF_REQUEST): BOOLEAN
|
||||
-- Should we return 403 Forbidden in response to OPTIONS * requests?
|
||||
require
|
||||
req_attached: req /= Void
|
||||
req_attached: req /= Void
|
||||
do
|
||||
-- by default, unconditionally no.
|
||||
end
|
||||
@@ -37,4 +37,14 @@ feature -- Access
|
||||
Result := "OPTIONS * is not permitted"
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, 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
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
note
|
||||
description: "Summary description for {WSF_SELF_DOCUMENTED_STARTS_WITH_AGENT_HANDLER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WSF_SELF_DOCUMENTED_STARTS_WITH_AGENT_HANDLER
|
||||
|
||||
inherit
|
||||
WSF_STARTS_WITH_AGENT_HANDLER
|
||||
rename
|
||||
make as make_handler
|
||||
end
|
||||
|
||||
WSF_SELF_DOCUMENTED_AGENT_HANDLER
|
||||
|
||||
create
|
||||
make,
|
||||
make_with_descriptions,
|
||||
make_hidden
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_action: like action; a_self_doc: like self_documentation_builder)
|
||||
-- <Precursor>
|
||||
-- and using `a_self_doc' function to build the `mapping_documentation'.
|
||||
do
|
||||
set_self_documentation_builder (a_self_doc)
|
||||
make_handler (a_action)
|
||||
end
|
||||
|
||||
make_with_descriptions (a_action: like action; a_descriptions: ITERABLE [READABLE_STRING_GENERAL])
|
||||
do
|
||||
across
|
||||
a_descriptions as c
|
||||
loop
|
||||
add_description (c.item)
|
||||
end
|
||||
make_handler (a_action)
|
||||
end
|
||||
|
||||
make_hidden (a_action: like action)
|
||||
-- <Precursor>
|
||||
-- and using `a_self_doc' function to build the `mapping_documentation'
|
||||
-- mark it as `hidden'.
|
||||
do
|
||||
is_hidden := True
|
||||
make (a_action, Void)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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
|
||||
@@ -0,0 +1,62 @@
|
||||
note
|
||||
description: "Summary description for {WSF_SELF_DOCUMENTED_URI_AGENT_HANDLER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WSF_SELF_DOCUMENTED_URI_AGENT_HANDLER
|
||||
|
||||
inherit
|
||||
WSF_URI_AGENT_HANDLER
|
||||
rename
|
||||
make as make_handler
|
||||
end
|
||||
|
||||
WSF_SELF_DOCUMENTED_AGENT_HANDLER
|
||||
|
||||
create
|
||||
make,
|
||||
make_with_descriptions,
|
||||
make_hidden
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_action: like action; a_self_doc: like self_documentation_builder)
|
||||
-- <Precursor>
|
||||
-- and using `a_self_doc' function to build the `mapping_documentation'.
|
||||
do
|
||||
set_self_documentation_builder (a_self_doc)
|
||||
make_handler (a_action)
|
||||
end
|
||||
|
||||
make_with_descriptions (a_action: like action; a_descriptions: ITERABLE [READABLE_STRING_GENERAL])
|
||||
-- Make Current with `a_action' and `a_descriptions'.
|
||||
do
|
||||
across
|
||||
a_descriptions as c
|
||||
loop
|
||||
add_description (c.item)
|
||||
end
|
||||
make_handler (a_action)
|
||||
end
|
||||
|
||||
make_hidden (a_action: like action)
|
||||
-- Make Current with `a_action'
|
||||
-- mark it as `hidden'.
|
||||
do
|
||||
is_hidden := True
|
||||
make (a_action, Void)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, 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
|
||||
@@ -13,6 +13,9 @@ inherit
|
||||
create
|
||||
make
|
||||
|
||||
convert
|
||||
make ({PROCEDURE [ANY, TUPLE [WSF_REQUEST, WSF_RESPONSE]]})
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_action: like action)
|
||||
@@ -32,7 +35,7 @@ feature -- Execution
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2013, 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
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
note
|
||||
description: "Summary description for {WSF_SELF_DOCUMENTED_URI_TEMPLATE_AGENT_HANDLER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WSF_SELF_DOCUMENTED_URI_TEMPLATE_AGENT_HANDLER
|
||||
|
||||
inherit
|
||||
WSF_URI_TEMPLATE_AGENT_HANDLER
|
||||
rename
|
||||
make as make_handler
|
||||
end
|
||||
|
||||
WSF_SELF_DOCUMENTED_AGENT_HANDLER
|
||||
|
||||
create
|
||||
make,
|
||||
make_with_descriptions,
|
||||
make_hidden
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_action: like action; a_self_doc: like self_documentation_builder)
|
||||
-- <Precursor>
|
||||
-- and using `a_self_doc' function to build the `mapping_documentation'.
|
||||
do
|
||||
set_self_documentation_builder (a_self_doc)
|
||||
make_handler (a_action)
|
||||
end
|
||||
|
||||
make_with_descriptions (a_action: like action; a_descriptions: ITERABLE [READABLE_STRING_GENERAL])
|
||||
do
|
||||
across
|
||||
a_descriptions as c
|
||||
loop
|
||||
add_description (c.item)
|
||||
end
|
||||
make_handler (a_action)
|
||||
end
|
||||
|
||||
make_hidden (a_action: like action)
|
||||
-- <Precursor>
|
||||
-- and using `a_self_doc' function to build the `mapping_documentation'
|
||||
-- mark it as `hidden'.
|
||||
do
|
||||
is_hidden := True
|
||||
make (a_action, Void)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, 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
|
||||
@@ -170,6 +170,8 @@ feature -- Status report
|
||||
e := p
|
||||
end
|
||||
if e.is_parent_symbol then
|
||||
elseif e.is_current_symbol then
|
||||
Result := True
|
||||
else
|
||||
n := e.name
|
||||
Result := n.starts_with ({STRING_32} ".")
|
||||
@@ -273,8 +275,8 @@ feature -- Execution
|
||||
|
||||
else
|
||||
n := p.name
|
||||
create pf.make_with_path (p)
|
||||
if pf.is_directory then
|
||||
create pf.make_with_path (dn.extended_path (p))
|
||||
if pf.exists and then pf.is_directory then
|
||||
l_is_dir := True
|
||||
else
|
||||
l_is_dir := False
|
||||
@@ -301,11 +303,13 @@ feature -- Execution
|
||||
|
||||
s.append ("</td>")
|
||||
s.append ("<td>")
|
||||
create httpdate.make_from_date_time (file_date (pf))
|
||||
httpdate.append_to_rfc1123_string (s)
|
||||
if pf.exists then
|
||||
create httpdate.make_from_date_time (file_date (pf))
|
||||
httpdate.append_to_rfc1123_string (s)
|
||||
end
|
||||
s.append ("</td>")
|
||||
s.append ("<td>")
|
||||
if not l_is_dir then
|
||||
if not l_is_dir and pf.exists then
|
||||
s.append_integer (file_size (pf))
|
||||
end
|
||||
s.append ("</td>")
|
||||
@@ -325,7 +329,7 @@ feature -- Execution
|
||||
h.put_content_type_text_html
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.ok)
|
||||
h.put_content_length (s.count)
|
||||
res.put_header_text (h.string)
|
||||
res.put_header_lines (h)
|
||||
if not req.request_method.same_string ({HTTP_REQUEST_METHODS}.method_head) then
|
||||
res.put_string (s)
|
||||
end
|
||||
@@ -391,7 +395,7 @@ feature -- Execution
|
||||
h.put_last_modified (a_utc_date)
|
||||
end
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.not_modified)
|
||||
res.put_header_text (h.string)
|
||||
res.put_header_lines (h)
|
||||
res.flush
|
||||
end
|
||||
|
||||
@@ -409,7 +413,7 @@ feature -- Execution
|
||||
s.append ("Resource %"" + uri + "%" not found%N")
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.not_found)
|
||||
h.put_content_length (s.count)
|
||||
res.put_header_text (h.string)
|
||||
res.put_header_lines (h)
|
||||
res.put_string (s)
|
||||
res.flush
|
||||
end
|
||||
@@ -429,7 +433,7 @@ feature -- Execution
|
||||
s.append ("Resource %"" + uri + "%": Access denied%N")
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.forbidden)
|
||||
h.put_content_length (s.count)
|
||||
res.put_header_text (h.string)
|
||||
res.put_header_lines (h)
|
||||
res.put_string (s)
|
||||
res.flush
|
||||
end
|
||||
@@ -449,7 +453,7 @@ feature -- Execution
|
||||
s.append ("Directory index: Access denied%N")
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.forbidden)
|
||||
h.put_content_length (s.count)
|
||||
res.put_header_text (h.string)
|
||||
res.put_header_lines (h)
|
||||
res.put_string (s)
|
||||
res.flush
|
||||
end
|
||||
@@ -628,7 +632,7 @@ feature {NONE} -- implementation: date time
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2013, 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
|
||||
|
||||
@@ -3,8 +3,8 @@ note
|
||||
Entry of WSF_ROUTER
|
||||
It contains
|
||||
- mapping
|
||||
- request methods
|
||||
|
||||
- request methods
|
||||
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
@@ -40,20 +40,23 @@ feature -- Access
|
||||
|
||||
feature -- Status report
|
||||
|
||||
debug_output: STRING
|
||||
debug_output: READABLE_STRING_GENERAL
|
||||
-- String that should be displayed in debugger to represent `Current'.
|
||||
local
|
||||
s: STRING_32
|
||||
do
|
||||
create Result.make_from_string (mapping.debug_output)
|
||||
create s.make_from_string_general (mapping.debug_output)
|
||||
if attached request_methods as mtds then
|
||||
Result.append_string (" [ ")
|
||||
s.append_string (" [ ")
|
||||
across
|
||||
mtds as c
|
||||
loop
|
||||
Result.append_string (c.item)
|
||||
Result.append_string (" ")
|
||||
s.append_string (c.item)
|
||||
s.append_string (" ")
|
||||
end
|
||||
Result.append_string ("]")
|
||||
s.append_string ("]")
|
||||
end
|
||||
Result := s
|
||||
end
|
||||
|
||||
feature -- Change
|
||||
@@ -68,7 +71,7 @@ invariant
|
||||
mapping_attached: mapping /= Void
|
||||
|
||||
note
|
||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
@@ -48,10 +48,10 @@ feature -- Documentation
|
||||
|
||||
feature -- Status report
|
||||
|
||||
debug_output: STRING
|
||||
debug_output: READABLE_STRING_GENERAL
|
||||
-- String that should be displayed in debugger to represent `Current'.
|
||||
do
|
||||
Result := description.as_string_8 + " : " + associated_resource
|
||||
Result := description + {STRING_32} " : " + associated_resource.to_string_32
|
||||
end
|
||||
|
||||
feature -- Status
|
||||
@@ -88,7 +88,7 @@ feature -- Helper
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
@@ -45,14 +45,14 @@ feature {NONE} -- Execution
|
||||
|
||||
feature -- Status report
|
||||
|
||||
debug_output: STRING
|
||||
debug_output: READABLE_STRING_GENERAL
|
||||
-- String that should be displayed in debugger to represent `Current'.
|
||||
do
|
||||
Result := Precursor + " {" + ({C}).name + "}"
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
@@ -22,14 +22,14 @@ feature -- Access
|
||||
|
||||
feature -- Status report
|
||||
|
||||
debug_output: STRING
|
||||
debug_output: READABLE_STRING_GENERAL
|
||||
-- String that should be displayed in debugger to represent `Current'.
|
||||
do
|
||||
Result := Precursor + " {" + ({C}).name + "}"
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
@@ -60,15 +60,16 @@ feature {NONE} -- Initialization
|
||||
|
||||
feature -- Cookie
|
||||
|
||||
apply_to (h: HTTP_HEADER; a_request: WSF_REQUEST; a_path: detachable READABLE_STRING_8)
|
||||
apply_to (h: HTTP_HEADER_MODIFIER; a_request: WSF_REQUEST; a_path: detachable READABLE_STRING_8)
|
||||
-- <Precursor>
|
||||
local
|
||||
dt: detachable DATE_TIME
|
||||
l_domain: detachable READABLE_STRING_8
|
||||
do
|
||||
l_domain := a_request.server_name
|
||||
if l_domain.same_string ("localhost") then
|
||||
-- Due to limitation of specific handling of local cookies
|
||||
-- it is recommended to use Void or IP instead of "localhost"
|
||||
-- Due to limitation of specific handling of local cookies
|
||||
-- it is recommended to use Void or IP instead of "localhost"
|
||||
l_domain := Void
|
||||
end
|
||||
if is_destroyed then
|
||||
@@ -79,13 +80,18 @@ feature -- Cookie
|
||||
create dt.make_now_utc
|
||||
dt.day_add (40)
|
||||
end
|
||||
h.put_cookie_with_expiration_date (cookie_name, uuid, dt, a_path, l_domain, False, True)
|
||||
h.put_cookie_with_expiration_date (cookie_name, id, dt, a_path, l_domain, False, True)
|
||||
end
|
||||
end
|
||||
|
||||
cookie_name: READABLE_STRING_8
|
||||
|
||||
feature -- Access
|
||||
feature -- Access
|
||||
|
||||
id: READABLE_STRING_8
|
||||
do
|
||||
Result := uuid
|
||||
end
|
||||
|
||||
uuid: READABLE_STRING_8
|
||||
|
||||
@@ -135,8 +141,8 @@ feature {NONE} -- Storage
|
||||
|
||||
load
|
||||
do
|
||||
if manager.session_exists (uuid) then
|
||||
if attached manager.session_data (uuid) as d then
|
||||
if manager.session_exists (id) then
|
||||
if attached manager.session_data (id) as d then
|
||||
data := d
|
||||
set_expiration (data.expiration)
|
||||
else
|
||||
@@ -177,7 +183,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
@@ -30,7 +30,7 @@ feature {NONE} -- Initialization
|
||||
|
||||
feature -- Access
|
||||
|
||||
session_exists (a_session_uuid: like {WSF_SESSION}.uuid): BOOLEAN
|
||||
session_exists (a_session_uuid: READABLE_STRING_8): BOOLEAN
|
||||
local
|
||||
f: RAW_FILE
|
||||
do
|
||||
@@ -38,7 +38,7 @@ feature -- Access
|
||||
Result := f.exists and then f.is_readable
|
||||
end
|
||||
|
||||
session_data (a_session_uuid: like {WSF_SESSION}.uuid): detachable like {WSF_SESSION}.data
|
||||
session_data (a_session_uuid: READABLE_STRING_8): detachable WSF_SESSION_DATA
|
||||
local
|
||||
f: RAW_FILE
|
||||
do
|
||||
@@ -68,7 +68,7 @@ feature -- Persistence
|
||||
delete_session (a_session)
|
||||
else
|
||||
ensure_session_folder_exists
|
||||
create f.make_with_path (file_name (a_session.uuid))
|
||||
create f.make_with_path (file_name (a_session.id))
|
||||
if not f.exists or else f.is_writable then
|
||||
f.create_read_write
|
||||
a_session.data.set_expiration (a_session.expiration)
|
||||
@@ -91,7 +91,7 @@ feature -- Persistence
|
||||
rescued: BOOLEAN
|
||||
do
|
||||
if not rescued then
|
||||
create f.make_with_path (file_name (a_session.uuid))
|
||||
create f.make_with_path (file_name (a_session.id))
|
||||
if f.exists then
|
||||
f.delete
|
||||
end
|
||||
@@ -147,13 +147,13 @@ feature {NONE} -- Implementation
|
||||
Result := d.exists and then d.is_writable
|
||||
end
|
||||
|
||||
file_name (a_uuid: like {WSF_SESSION}.uuid): PATH
|
||||
file_name (a_uuid: READABLE_STRING_GENERAL): PATH
|
||||
do
|
||||
Result := sessions_folder_name.extended (a_uuid.out).appended_with_extension ("session")
|
||||
Result := sessions_folder_name.extended (a_uuid).appended_with_extension ("session")
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
@@ -7,26 +7,43 @@ note
|
||||
deferred class
|
||||
WSF_SESSION
|
||||
|
||||
feature -- Access
|
||||
feature -- Access
|
||||
|
||||
id: READABLE_STRING_8
|
||||
-- Session identifier.
|
||||
deferred
|
||||
end
|
||||
|
||||
uuid: READABLE_STRING_8
|
||||
obsolete
|
||||
"Use `id' which is more general [2014-03]"
|
||||
deferred
|
||||
end
|
||||
|
||||
data: WSF_SESSION_DATA
|
||||
-- Data associated with current session.
|
||||
deferred
|
||||
end
|
||||
|
||||
expiration: detachable DATE_TIME
|
||||
-- Expiration date for current session, if any.
|
||||
deferred
|
||||
end
|
||||
|
||||
expired: BOOLEAN
|
||||
-- Is current session expired now?
|
||||
do
|
||||
Result := expired_at (create {DATE_TIME}.make_now_utc)
|
||||
end
|
||||
|
||||
expired_at (dt: DATE_TIME): BOOLEAN
|
||||
-- Is current session expired at date and time `dt'?
|
||||
do
|
||||
if attached expiration as e then
|
||||
Result := e < (create {DATE_TIME}.make_now_utc)
|
||||
Result := e < (dt)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- status
|
||||
|
||||
is_pending: BOOLEAN
|
||||
@@ -36,27 +53,32 @@ feature -- status
|
||||
end
|
||||
|
||||
is_destroyed: BOOLEAN
|
||||
-- Is current session in destroyed state?
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Entries
|
||||
|
||||
table: TABLE_ITERABLE [detachable ANY, READABLE_STRING_32]
|
||||
table: TABLE_ITERABLE [detachable ANY, READABLE_STRING_GENERAL]
|
||||
-- Table of session data indexed by key
|
||||
do
|
||||
Result := data
|
||||
end
|
||||
|
||||
item (k: READABLE_STRING_GENERAL): detachable ANY
|
||||
item alias "[]" (k: READABLE_STRING_GENERAL): detachable ANY assign remember
|
||||
-- Session value associated with key `k'.
|
||||
do
|
||||
Result := data.item (table_key (k))
|
||||
end
|
||||
|
||||
remember (v: detachable ANY; k: READABLE_STRING_GENERAL)
|
||||
-- Remember value `v' in association with key `k'.
|
||||
do
|
||||
data.force (v, table_key (k))
|
||||
end
|
||||
|
||||
forget (k: READABLE_STRING_GENERAL)
|
||||
-- Forget about value associated with key `k'.
|
||||
do
|
||||
data.remove (table_key (k))
|
||||
end
|
||||
@@ -71,19 +93,30 @@ feature {NONE} -- Implementation
|
||||
feature -- Control
|
||||
|
||||
destroy
|
||||
-- Destroy current session.
|
||||
deferred
|
||||
end
|
||||
|
||||
commit
|
||||
-- Commit current session, including data associated.
|
||||
deferred
|
||||
end
|
||||
|
||||
apply_to (h: HTTP_HEADER; req: WSF_REQUEST; a_path: detachable READABLE_STRING_8)
|
||||
apply_to (h: HTTP_HEADER_MODIFIER; req: WSF_REQUEST; a_path: detachable READABLE_STRING_8)
|
||||
-- Apply current session to header `h' for request `req' and optional path `a_path'.
|
||||
-- note: either use `apply_to' or `apply', not both.
|
||||
deferred
|
||||
end
|
||||
|
||||
apply (req: WSF_REQUEST; res: WSF_RESPONSE; a_path: detachable READABLE_STRING_8)
|
||||
-- Apply current session to response `res' for request `req' and optional path `a_path'.
|
||||
-- note: either use `apply' or `apply_to', not both.
|
||||
do
|
||||
apply_to (res.header, req, a_path)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
@@ -8,7 +8,13 @@ class
|
||||
WSF_SESSION_DATA
|
||||
|
||||
inherit
|
||||
HASH_TABLE [detachable ANY, READABLE_STRING_32]
|
||||
STRING_TABLE [detachable ANY]
|
||||
rename
|
||||
make as old_make,
|
||||
make_caseless as make
|
||||
redefine
|
||||
empty_duplicate
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
@@ -24,4 +30,22 @@ feature -- Element change
|
||||
expiration := dt
|
||||
end
|
||||
|
||||
feature {NONE} -- Duplication
|
||||
|
||||
empty_duplicate (n: INTEGER): like Current
|
||||
-- Create an empty copy of Current that can accommodate `n' items
|
||||
do
|
||||
create Result.make (n)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
@@ -9,11 +9,11 @@ deferred class
|
||||
|
||||
feature -- Access
|
||||
|
||||
session_exists (a_uuid: like {WSF_SESSION}.uuid): BOOLEAN
|
||||
session_exists (a_uuid: READABLE_STRING_8): BOOLEAN
|
||||
deferred
|
||||
end
|
||||
|
||||
session_data (a_uuid: like {WSF_SESSION}.uuid): detachable like {WSF_SESSION}.data
|
||||
session_data (a_uuid: READABLE_STRING_8): detachable WSF_SESSION_DATA
|
||||
deferred
|
||||
end
|
||||
|
||||
@@ -28,7 +28,7 @@ feature -- Persistence
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
@@ -9,509 +9,11 @@ note
|
||||
class
|
||||
WSF_PERCENT_ENCODER
|
||||
|
||||
feature -- Percent encoding
|
||||
|
||||
percent_encoded_string (v: READABLE_STRING_GENERAL): STRING_8
|
||||
-- Return `a_string' percent-encoded
|
||||
do
|
||||
create Result.make (v.count)
|
||||
append_percent_encoded_string_to (v, Result)
|
||||
end
|
||||
|
||||
append_percent_encoded_string_to (s: READABLE_STRING_GENERAL; a_result: STRING_GENERAL)
|
||||
-- Append `a_string' as percent-encoded value to `a_result'
|
||||
local
|
||||
c: NATURAL_32
|
||||
i,n: INTEGER
|
||||
do
|
||||
from
|
||||
i := 1
|
||||
n := s.count
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
c := s.code (i)
|
||||
if
|
||||
--| unreserved ALPHA / DIGIT
|
||||
(48 <= c and c <= 57) -- DIGIT: 0 .. 9
|
||||
or (65 <= c and c <= 90) -- ALPHA: A .. Z
|
||||
or (97 <= c and c <= 122) -- ALPHA: a .. z
|
||||
then
|
||||
a_result.append_code (c)
|
||||
else
|
||||
inspect c
|
||||
when
|
||||
45, 46, 95, 126 -- unreserved characters: -._~
|
||||
then
|
||||
a_result.append_code (c)
|
||||
when
|
||||
58, 64, -- reserved =+ gen-delims: :@
|
||||
33, 36, 38, 39, 40, 41, 42, -- reserved =+ sub-delims: !$&'()*
|
||||
43, 44, 59, 61, -- reserved = sub-delims: +,;=
|
||||
37 -- percent encoding: %
|
||||
then
|
||||
append_percent_encoded_character_code_to (c, a_result)
|
||||
else
|
||||
append_percent_encoded_character_code_to (c, a_result)
|
||||
end
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Percent encoding: character
|
||||
|
||||
append_percent_encoded_character_code_to (a_code: NATURAL_32; a_result: STRING_GENERAL)
|
||||
-- Append character code `a_code' as percent-encoded content into `a_result'
|
||||
do
|
||||
if a_code > 0xFF then
|
||||
-- Unicode
|
||||
append_percent_encoded_unicode_character_code_to (a_code, a_result)
|
||||
elseif a_code > 0x7F then
|
||||
-- Extended ASCII
|
||||
-- This requires percent-encoding on UTF-8 converted character.
|
||||
append_percent_encoded_unicode_character_code_to (a_code, a_result)
|
||||
else
|
||||
-- ASCII
|
||||
append_percent_encoded_ascii_character_code_to (a_code, a_result)
|
||||
end
|
||||
ensure
|
||||
appended: a_result.count > old a_result.count
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: character encoding
|
||||
|
||||
append_percent_encoded_ascii_character_code_to (a_code: NATURAL_32; a_result: STRING_GENERAL)
|
||||
-- Append extended ascii character code `a_code' as percent-encoded content into `a_result'
|
||||
-- Note: it does not UTF-8 convert this extended ASCII.
|
||||
require
|
||||
is_extended_ascii: a_code <= 0xFF
|
||||
local
|
||||
c: INTEGER
|
||||
do
|
||||
if a_code > 0xFF then
|
||||
-- Unicode
|
||||
append_percent_encoded_unicode_character_code_to (a_code, a_result)
|
||||
else
|
||||
-- Extended ASCII
|
||||
c := a_code.to_integer_32
|
||||
a_result.append_code (37) -- 37 '%%'
|
||||
a_result.append_code (hex_digit [c |>> 4])
|
||||
a_result.append_code (hex_digit [c & 0xF])
|
||||
end
|
||||
ensure
|
||||
appended: a_result.count > old a_result.count
|
||||
end
|
||||
|
||||
append_percent_encoded_unicode_character_code_to (a_code: NATURAL_32; a_result: STRING_GENERAL)
|
||||
-- Append Unicode character code `a_code' as UTF-8 and percent-encoded content into `a_result'
|
||||
-- Note: it does include UTF-8 conversion of extended ASCII and Unicode.
|
||||
do
|
||||
if a_code <= 0x7F then
|
||||
-- 0xxxxxxx
|
||||
append_percent_encoded_ascii_character_code_to (a_code, a_result)
|
||||
elseif a_code <= 0x7FF then
|
||||
-- 110xxxxx 10xxxxxx
|
||||
append_percent_encoded_ascii_character_code_to ((a_code |>> 6) | 0xC0, a_result)
|
||||
append_percent_encoded_ascii_character_code_to ((a_code & 0x3F) | 0x80, a_result)
|
||||
elseif a_code <= 0xFFFF then
|
||||
-- 1110xxxx 10xxxxxx 10xxxxxx
|
||||
append_percent_encoded_ascii_character_code_to ((a_code |>> 12) | 0xE0, a_result)
|
||||
append_percent_encoded_ascii_character_code_to (((a_code |>> 6) & 0x3F) | 0x80, a_result)
|
||||
append_percent_encoded_ascii_character_code_to ((a_code & 0x3F) | 0x80, a_result)
|
||||
else
|
||||
-- c <= 1FFFFF - there are no higher code points
|
||||
-- 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
append_percent_encoded_ascii_character_code_to ((a_code |>> 18) | 0xF0, a_result)
|
||||
append_percent_encoded_ascii_character_code_to (((a_code |>> 12) & 0x3F) | 0x80, a_result)
|
||||
append_percent_encoded_ascii_character_code_to (((a_code |>> 6) & 0x3F) | 0x80, a_result)
|
||||
append_percent_encoded_ascii_character_code_to ((a_code & 0x3F) | 0x80, a_result)
|
||||
end
|
||||
ensure
|
||||
appended: a_result.count > old a_result.count
|
||||
end
|
||||
|
||||
feature -- Percent decoding
|
||||
|
||||
percent_decoded_string (v: READABLE_STRING_GENERAL): STRING_32
|
||||
-- Return the percent decoded string equivalent to the percent-encoded string `v'
|
||||
--| Note that is `a_result' is a STRING_8, any Unicode character will be kept as UTF-8
|
||||
do
|
||||
create Result.make (v.count)
|
||||
append_percent_decoded_string_to (v, Result)
|
||||
end
|
||||
|
||||
append_percent_decoded_string_to (v: READABLE_STRING_GENERAL; a_result: STRING_GENERAL)
|
||||
-- Append to `a_result' a string equivalent to the percent-encoded string `v'
|
||||
--| Note that is `a_result' is a STRING_8, any Unicode character will be kept as UTF-8
|
||||
local
|
||||
i,n: INTEGER
|
||||
c: NATURAL_32
|
||||
pr: CELL [INTEGER]
|
||||
a_result_is_string_32: BOOLEAN
|
||||
do
|
||||
a_result_is_string_32 := attached {STRING_32} a_result
|
||||
from
|
||||
i := 1
|
||||
create pr.put (i)
|
||||
n := v.count
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
c := v.code (i)
|
||||
inspect c
|
||||
when 43 then -- 43 '+'
|
||||
-- Some implementation are replacing spaces with "+" instead of "%20"
|
||||
a_result.append_code (32) -- 32 ' '
|
||||
when 37 then -- 37 '%%'
|
||||
-- An escaped character ?
|
||||
if i = n then -- Error?
|
||||
a_result.append_code (c)
|
||||
else
|
||||
if a_result_is_string_32 then
|
||||
-- Convert UTF-8 to UTF-32
|
||||
pr.replace (i)
|
||||
c := next_percent_decoded_unicode_character_code (v, pr)
|
||||
a_result.append_code (c)
|
||||
i := pr.item
|
||||
else
|
||||
-- Keep UTF-8
|
||||
pr.replace (i)
|
||||
c := next_percent_decoded_character_code (v, pr)
|
||||
a_result.append_code (c)
|
||||
i := pr.item
|
||||
end
|
||||
end
|
||||
else
|
||||
if c <= 0x7F then
|
||||
a_result.append_code (c)
|
||||
else
|
||||
if a_result_is_string_32 then
|
||||
a_result.append_code (c)
|
||||
else
|
||||
append_percent_encoded_character_code_to (c, a_result)
|
||||
end
|
||||
end
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: decoding
|
||||
|
||||
next_percent_decoded_character_code (v: READABLE_STRING_GENERAL; a_position: CELL [INTEGER]): NATURAL_32
|
||||
-- Character decoded from string `v' starting from index `a_position.item'
|
||||
-- note: it also updates `a_position.item' to indicate the new index position.
|
||||
require
|
||||
valid_start: a_position.item <= v.count
|
||||
is_percent_char: v.code (a_position.item) = 37 -- 37 '%%'
|
||||
local
|
||||
c: NATURAL_32
|
||||
i, n: INTEGER
|
||||
not_a_digit: BOOLEAN
|
||||
ascii_pos: NATURAL_32
|
||||
ival: NATURAL_32
|
||||
pos: INTEGER
|
||||
c_is_digit: BOOLEAN
|
||||
do
|
||||
--| pos is index in stream of escape character ('%')
|
||||
pos := a_position.item
|
||||
c := v.code (pos + 1)
|
||||
if c = 85 or c = 117 then -- 117 'u' 85 'U'
|
||||
-- NOTE: this is not a standard, but it can occur, so use this for decoding only
|
||||
-- An escaped Unicode (ucs2) value, from ECMA scripts
|
||||
-- has the form: %u<n> where <n> is the UCS value
|
||||
-- of the character (two byte integer, one to 4 chars
|
||||
-- after escape sequence).
|
||||
-- See: http://en.wikipedia.org/wiki/Percent-encoding#Non-standard_implementations
|
||||
-- UTF-8 result can be 1 to 4 characters.
|
||||
from
|
||||
i := pos + 2
|
||||
n := v.count
|
||||
until
|
||||
(i > n) or not_a_digit
|
||||
loop
|
||||
c := v.code (i)
|
||||
c_is_digit := (48 <= c and c <= 57) -- DIGIT: 0 .. 9
|
||||
if
|
||||
c_is_digit
|
||||
or (97 <= c and c <= 102) -- ALPHA: a..f
|
||||
or (65 <= c and c <= 70) -- ALPHA: A..F
|
||||
then
|
||||
ival := ival * 16
|
||||
if c_is_digit then
|
||||
ival := ival + (c - 48) -- 48 '0'
|
||||
else
|
||||
if c > 70 then -- a..f
|
||||
ival := ival + (c - 97) + 10 -- 97 'a'
|
||||
else -- A..F
|
||||
ival := ival + (c - 65) + 10 -- 65 'A'
|
||||
end
|
||||
end
|
||||
i := i + 1
|
||||
else
|
||||
not_a_digit := True
|
||||
i := i - 1
|
||||
end
|
||||
end
|
||||
a_position.replace (i)
|
||||
Result := ival
|
||||
else
|
||||
-- ASCII char?
|
||||
ascii_pos := hexadecimal_string_to_natural_32 (v.substring (pos + 1, pos + 2))
|
||||
Result := ascii_pos
|
||||
a_position.replace (pos + 2)
|
||||
end
|
||||
end
|
||||
|
||||
next_percent_decoded_unicode_character_code (v: READABLE_STRING_GENERAL; a_position: CELL [INTEGER]): NATURAL_32
|
||||
-- Next decoded character from `v' at position `a_position.item'
|
||||
-- note: it also updates `a_position' to indicate the new index position.
|
||||
require
|
||||
valid_start: a_position.item <= v.count
|
||||
is_percent_char: v.code (a_position.item) = 37 -- 37 '%%'
|
||||
local
|
||||
n, j: INTEGER
|
||||
c: NATURAL_32
|
||||
c1, c2, c3, c4: NATURAL_32
|
||||
pr: CELL [INTEGER]
|
||||
do
|
||||
create pr.put (a_position.item)
|
||||
c1 := next_percent_decoded_character_code (v, pr)
|
||||
|
||||
j := pr.item
|
||||
n := v.count
|
||||
|
||||
Result := c1
|
||||
a_position.replace (j)
|
||||
|
||||
if c1 <= 0x7F then
|
||||
-- 0xxxxxxx
|
||||
Result := c1
|
||||
elseif c1 <= 0xDF then
|
||||
-- 110xxxxx 10xxxxxx
|
||||
if j + 2 <= n then
|
||||
c := v.code (j + 1)
|
||||
if c = 37 then -- 37 '%%'
|
||||
pr.replace (j + 1)
|
||||
c2 := next_percent_decoded_character_code (v, pr)
|
||||
j := pr.item
|
||||
Result := (
|
||||
((c1 & 0x1F) |<< 6) |
|
||||
( c2 & 0x3F )
|
||||
)
|
||||
a_position.replace (j)
|
||||
else
|
||||
-- Do not try to decode
|
||||
end
|
||||
end
|
||||
elseif c1 <= 0xEF then
|
||||
-- 1110xxxx 10xxxxxx 10xxxxxx
|
||||
if j + 2 <= n then
|
||||
c := v.code (j + 1)
|
||||
if c = 37 then -- 37 '%%'
|
||||
pr.replace (j + 1)
|
||||
c2 := next_percent_decoded_character_code (v, pr)
|
||||
j := pr.item
|
||||
if j + 2 <= n then
|
||||
c := v.code (j + 1)
|
||||
if c = 37 then -- 37 '%%'
|
||||
pr.replace (j + 1)
|
||||
c3 := next_percent_decoded_character_code (v, pr)
|
||||
j := pr.item
|
||||
|
||||
Result := (
|
||||
((c1 & 0xF) |<< 12) |
|
||||
((c2 & 0x3F) |<< 6) |
|
||||
( c3 & 0x3F )
|
||||
)
|
||||
a_position.replace (j)
|
||||
else
|
||||
-- Do not try to decode
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Do not try to decode
|
||||
end
|
||||
end
|
||||
elseif c1 <= 0xF7 then
|
||||
-- 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
|
||||
if j + 2 <= n then
|
||||
c := v.code (j + 1)
|
||||
if c = 37 then -- 37 '%%'
|
||||
pr.replace (j + 1)
|
||||
c2 := next_percent_decoded_character_code (v, pr)
|
||||
j := pr.item
|
||||
if j + 2 <= n then
|
||||
c := v.code (j + 1)
|
||||
if c = 37 then -- 37 '%%'
|
||||
pr.replace (j + 1)
|
||||
c3 := next_percent_decoded_character_code (v, pr)
|
||||
j := pr.item
|
||||
if j + 2 <= n then
|
||||
c := v.code (j + 1)
|
||||
if c = 37 then -- 37 '%%'
|
||||
pr.replace (j + 1)
|
||||
c4 := next_percent_decoded_character_code (v, pr)
|
||||
j := pr.item
|
||||
|
||||
a_position.replace (j)
|
||||
|
||||
Result := (
|
||||
((c1 & 0x7) |<< 18 ) |
|
||||
((c2 & 0x3F) |<< 12) |
|
||||
((c3 & 0x3F) |<< 6) |
|
||||
( c4 & 0x3F )
|
||||
)
|
||||
else
|
||||
-- Do not try to decode
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Do not try to decode
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Do not try to decode
|
||||
end
|
||||
end
|
||||
else
|
||||
Result := c1
|
||||
end
|
||||
end
|
||||
|
||||
feature -- RFC and characters
|
||||
|
||||
is_hexa_decimal_character (c: CHARACTER_32): BOOLEAN
|
||||
-- Is hexadecimal character ?
|
||||
do
|
||||
Result := ('a' <= c and c <= 'f') or ('A' <= c and c <= 'F') -- HEXA
|
||||
or ('0' <= c and c <= '9') -- DIGIT
|
||||
end
|
||||
|
||||
is_alpha_or_digit_character (c: CHARACTER_32): BOOLEAN
|
||||
-- Is ALPHA or DIGIT character ?
|
||||
do
|
||||
Result := ('a' <= c and c <= 'z') or ('A' <= c and c <= 'Z') -- ALPHA
|
||||
or ('0' <= c and c <= '9') -- DIGIT
|
||||
end
|
||||
|
||||
is_alpha_character (c: CHARACTER_32): BOOLEAN
|
||||
-- Is ALPHA character ?
|
||||
do
|
||||
Result := ('a' <= c and c <= 'z') or ('A' <= c and c <= 'Z')
|
||||
end
|
||||
|
||||
is_digit_character (c: CHARACTER_32): BOOLEAN
|
||||
-- Is DIGIT character ?
|
||||
do
|
||||
Result := ('0' <= c and c <= '9')
|
||||
end
|
||||
|
||||
is_unreserved_character (c: CHARACTER_32): BOOLEAN
|
||||
-- unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||
do
|
||||
if
|
||||
('a' <= c and c <= 'z') -- ALPHA
|
||||
or ('A' <= c and c <= 'Z') -- ALPHA
|
||||
or ('0' <= c and c <= '9') -- DIGIT
|
||||
then
|
||||
Result := True
|
||||
else
|
||||
inspect c
|
||||
when '-', '_', '.', '~' then -- unreserved
|
||||
Result := True
|
||||
else
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
is_reserved_character (c: CHARACTER_32): BOOLEAN
|
||||
-- reserved = gen-delims / sub-delims
|
||||
do
|
||||
Result := is_gen_delims_character (c) or is_sub_delims_character (c)
|
||||
end
|
||||
|
||||
is_gen_delims_character (c: CHARACTER_32): BOOLEAN
|
||||
-- gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
|
||||
do
|
||||
inspect c
|
||||
when ':' , '/', '?' , '#' , '[' , ']' , '@' then
|
||||
Result := True
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
is_sub_delims_character (c: CHARACTER_32): BOOLEAN
|
||||
-- sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||
-- / "*" / "+" / "," / ";" / "="
|
||||
do
|
||||
inspect c
|
||||
when '!' , '$' , '&' , '%'' , '(' , ')' , '*' , '+' , ',' , ';' , '=' then -- sub-delims
|
||||
Result := True
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
hex_digit: SPECIAL [NATURAL_32]
|
||||
-- Hexadecimal digits.
|
||||
once
|
||||
create Result.make_filled (0, 16)
|
||||
Result [0] := {NATURAL_32} 48 -- 48 '0'
|
||||
Result [1] := {NATURAL_32} 49 -- 49 '1'
|
||||
Result [2] := {NATURAL_32} 50 -- 50 '2'
|
||||
Result [3] := {NATURAL_32} 51 -- 51 '3'
|
||||
Result [4] := {NATURAL_32} 52 -- 52 '4'
|
||||
Result [5] := {NATURAL_32} 53 -- 53 '5'
|
||||
Result [6] := {NATURAL_32} 54 -- 54 '6'
|
||||
Result [7] := {NATURAL_32} 55 -- 55 '7'
|
||||
Result [8] := {NATURAL_32} 56 -- 56 '8'
|
||||
Result [9] := {NATURAL_32} 57 -- 57 '9'
|
||||
Result [10] := {NATURAL_32} 65 -- 65 'A'
|
||||
Result [11] := {NATURAL_32} 66 -- 66 'B'
|
||||
Result [12] := {NATURAL_32} 67 -- 67 'C'
|
||||
Result [13] := {NATURAL_32} 68 -- 68 'D'
|
||||
Result [14] := {NATURAL_32} 69 -- 69 'E'
|
||||
Result [15] := {NATURAL_32} 70 -- 70 'F'
|
||||
end
|
||||
|
||||
is_hexa_decimal (a_string: READABLE_STRING_GENERAL): BOOLEAN
|
||||
-- Is `a_string' a valid hexadecimal sequence?
|
||||
local
|
||||
l_convertor: like ctoi_convertor
|
||||
do
|
||||
l_convertor := ctoi_convertor
|
||||
l_convertor.parse_string_with_type (a_string, {NUMERIC_INFORMATION}.type_natural_32)
|
||||
Result := l_convertor.is_integral_integer
|
||||
end
|
||||
|
||||
hexadecimal_string_to_natural_32 (a_hex_string: READABLE_STRING_GENERAL): NATURAL_32
|
||||
-- Convert hexadecimal value `a_hex_string' to its corresponding NATURAL_32 value.
|
||||
require
|
||||
is_hexa: is_hexa_decimal (a_hex_string)
|
||||
local
|
||||
l_convertor: like ctoi_convertor
|
||||
do
|
||||
l_convertor := ctoi_convertor
|
||||
l_convertor.parse_string_with_type (a_hex_string, {NUMERIC_INFORMATION}.type_no_limitation)
|
||||
Result := l_convertor.parsed_natural_32
|
||||
end
|
||||
|
||||
ctoi_convertor: HEXADECIMAL_STRING_TO_INTEGER_CONVERTER
|
||||
-- Converter used to convert string to integer or natural.
|
||||
once
|
||||
create Result.make
|
||||
Result.set_leading_separators_acceptable (False)
|
||||
Result.set_trailing_separators_acceptable (False)
|
||||
ensure
|
||||
ctoi_convertor_not_void: Result /= Void
|
||||
end
|
||||
inherit
|
||||
PERCENT_ENCODER
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
@@ -102,6 +102,16 @@ feature -- Access: Uploaded File
|
||||
filename: STRING
|
||||
-- original filename
|
||||
|
||||
safe_filename: STRING
|
||||
-- Safe name version of `filename'.
|
||||
-- i.e: removing whitespace, accent, unicode characters ...
|
||||
local
|
||||
ut: WSF_FILE_UTILITIES [RAW_FILE]
|
||||
do
|
||||
create ut
|
||||
Result := ut.safe_filename (filename)
|
||||
end
|
||||
|
||||
content_type: STRING
|
||||
-- Content type
|
||||
|
||||
@@ -118,7 +128,7 @@ feature -- Access: Uploaded File
|
||||
end
|
||||
end
|
||||
|
||||
tmp_basename: detachable STRING
|
||||
tmp_basename: detachable READABLE_STRING_GENERAL
|
||||
-- Basename of tmp file
|
||||
|
||||
feature -- Conversion
|
||||
@@ -156,92 +166,6 @@ feature -- Conversion
|
||||
retry
|
||||
end
|
||||
|
||||
feature -- Implementation
|
||||
|
||||
safe_filename: STRING
|
||||
local
|
||||
fn: like filename
|
||||
c: CHARACTER
|
||||
i, n: INTEGER
|
||||
do
|
||||
fn := filename
|
||||
|
||||
--| Compute safe filename, to avoid creating impossible filename, or dangerous one
|
||||
from
|
||||
i := 1
|
||||
n := fn.count
|
||||
create Result.make (n)
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
c := fn[i]
|
||||
inspect c
|
||||
when '.', '-', '_' then
|
||||
Result.extend (c)
|
||||
when 'A' .. 'Z', 'a' .. 'z', '0' .. '9' then
|
||||
Result.extend (c)
|
||||
else
|
||||
inspect c
|
||||
when '%/192/' then Result.extend ('A') -- À
|
||||
when '%/193/' then Result.extend ('A') -- Á
|
||||
when '%/194/' then Result.extend ('A') -- Â
|
||||
when '%/195/' then Result.extend ('A') -- Ã
|
||||
when '%/196/' then Result.extend ('A') -- Ä
|
||||
when '%/197/' then Result.extend ('A') -- Å
|
||||
when '%/199/' then Result.extend ('C') -- Ç
|
||||
when '%/200/' then Result.extend ('E') -- È
|
||||
when '%/201/' then Result.extend ('E') -- É
|
||||
when '%/202/' then Result.extend ('E') -- Ê
|
||||
when '%/203/' then Result.extend ('E') -- Ë
|
||||
when '%/204/' then Result.extend ('I') -- Ì
|
||||
when '%/205/' then Result.extend ('I') -- Í
|
||||
when '%/206/' then Result.extend ('I') -- Î
|
||||
when '%/207/' then Result.extend ('I') -- Ï
|
||||
when '%/210/' then Result.extend ('O') -- Ò
|
||||
when '%/211/' then Result.extend ('O') -- Ó
|
||||
when '%/212/' then Result.extend ('O') -- Ô
|
||||
when '%/213/' then Result.extend ('O') -- Õ
|
||||
when '%/214/' then Result.extend ('O') -- Ö
|
||||
when '%/217/' then Result.extend ('U') -- Ù
|
||||
when '%/218/' then Result.extend ('U') -- Ú
|
||||
when '%/219/' then Result.extend ('U') -- Û
|
||||
when '%/220/' then Result.extend ('U') -- Ü
|
||||
when '%/221/' then Result.extend ('Y') -- Ý
|
||||
when '%/224/' then Result.extend ('a') -- à
|
||||
when '%/225/' then Result.extend ('a') -- á
|
||||
when '%/226/' then Result.extend ('a') -- â
|
||||
when '%/227/' then Result.extend ('a') -- ã
|
||||
when '%/228/' then Result.extend ('a') -- ä
|
||||
when '%/229/' then Result.extend ('a') -- å
|
||||
when '%/231/' then Result.extend ('c') -- ç
|
||||
when '%/232/' then Result.extend ('e') -- è
|
||||
when '%/233/' then Result.extend ('e') -- é
|
||||
when '%/234/' then Result.extend ('e') -- ê
|
||||
when '%/235/' then Result.extend ('e') -- ë
|
||||
when '%/236/' then Result.extend ('i') -- ì
|
||||
when '%/237/' then Result.extend ('i') -- í
|
||||
when '%/238/' then Result.extend ('i') -- î
|
||||
when '%/239/' then Result.extend ('i') -- ï
|
||||
when '%/240/' then Result.extend ('o') -- ð
|
||||
when '%/242/' then Result.extend ('o') -- ò
|
||||
when '%/243/' then Result.extend ('o') -- ó
|
||||
when '%/244/' then Result.extend ('o') -- ô
|
||||
when '%/245/' then Result.extend ('o') -- õ
|
||||
when '%/246/' then Result.extend ('o') -- ö
|
||||
when '%/249/' then Result.extend ('u') -- ù
|
||||
when '%/250/' then Result.extend ('u') -- ú
|
||||
when '%/251/' then Result.extend ('u') -- û
|
||||
when '%/252/' then Result.extend ('u') -- ü
|
||||
when '%/253/' then Result.extend ('y') -- ý
|
||||
when '%/255/' then Result.extend ('y') -- ÿ
|
||||
else
|
||||
Result.extend ('-')
|
||||
end
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
move_to (a_destination: READABLE_STRING_GENERAL): BOOLEAN
|
||||
@@ -317,7 +241,7 @@ feature -- Element change
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
@@ -148,8 +148,10 @@ feature {WSF_RESPONSE} -- Output
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="header">]" + l_html_error_code_text + "[!!</div>
|
||||
<div id="header">
|
||||
]")
|
||||
s.append (l_html_error_code_text)
|
||||
s.append ("!!</div>")
|
||||
s.append ("<div id=%"logo%">")
|
||||
s.append ("<div class=%"outter%"> ")
|
||||
s.append ("<div class=%"inner1%"></div>")
|
||||
|
||||
@@ -55,6 +55,8 @@ feature {WSF_RESPONSE} -- Output
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.not_implemented)
|
||||
|
||||
s := "Error 501 Not Implemented ! "
|
||||
s.append (request.request_method)
|
||||
s.append (" ")
|
||||
s.append (request.request_uri)
|
||||
if attached body as b then
|
||||
s.append ("%N")
|
||||
@@ -69,7 +71,7 @@ feature {WSF_RESPONSE} -- Output
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2013, 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
|
||||
|
||||
@@ -98,14 +98,14 @@ feature {WSF_RESPONSE} -- Output
|
||||
h.put_content_type_text_plain
|
||||
end
|
||||
end
|
||||
res.put_header_text (h.string)
|
||||
res.put_header_lines (h)
|
||||
if b /= Void then
|
||||
res.put_string (b)
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -45,7 +45,7 @@ feature {WSF_RESPONSE} -- Output
|
||||
req := request
|
||||
if attached req.raw_header_data as l_header then
|
||||
create s.make (l_header.count)
|
||||
s.append (l_header.to_string_8)
|
||||
s.append (l_header.to_string_8) -- Is valid as string 8, as ensured by req.raw_header_data
|
||||
s.append_character ('%N')
|
||||
else
|
||||
create s.make_empty
|
||||
@@ -99,7 +99,7 @@ feature {WSF_RESPONSE} -- Output
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
@@ -56,12 +56,12 @@ feature {NONE} -- Initialization
|
||||
launch
|
||||
end
|
||||
|
||||
frozen make_callback (a_callback: like {WSF_CALLBACK_SERVICE}.callback; a_options: like options)
|
||||
frozen make_callback (a_callback: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]; a_options: like options)
|
||||
do
|
||||
make (create {WSF_CALLBACK_SERVICE}.make (a_callback), a_options)
|
||||
end
|
||||
|
||||
frozen make_callback_and_launch (a_callback: like {WSF_CALLBACK_SERVICE}.callback; a_options: like options)
|
||||
frozen make_callback_and_launch (a_callback: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]; a_options: like options)
|
||||
do
|
||||
make (create {WSF_CALLBACK_SERVICE}.make (a_callback), a_options)
|
||||
end
|
||||
@@ -120,7 +120,7 @@ invariant
|
||||
connector_attached: connector /= Void
|
||||
|
||||
note
|
||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
171
library/server/wsf/src/support/wsf_file_utilities.e
Normal file
171
library/server/wsf/src/support/wsf_file_utilities.e
Normal file
@@ -0,0 +1,171 @@
|
||||
note
|
||||
description: "Summary description for {WSF_FILE_UTILITIES}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
expanded class
|
||||
WSF_FILE_UTILITIES [G -> FILE create make_with_path end]
|
||||
|
||||
feature -- Factory
|
||||
|
||||
new_temporary_file (d: DIRECTORY; a_prefix: detachable READABLE_STRING_GENERAL; a_name: detachable READABLE_STRING_GENERAL): detachable G
|
||||
-- New temporary file open for writing inside directory `d', with prefix `a_prefix' is set, and based on name `a_name' is set.
|
||||
-- If it is unable to create such file opened for writing, then return Void.
|
||||
require
|
||||
d_valid: d.exists and then d.is_writable
|
||||
local
|
||||
f: G
|
||||
fn: PATH
|
||||
bn, tmp: STRING_32
|
||||
dn: PATH
|
||||
n: INTEGER
|
||||
do
|
||||
from
|
||||
if a_prefix /= Void then
|
||||
create tmp.make_from_string_general (a_prefix)
|
||||
else
|
||||
create tmp.make_from_string_general ("tmp")
|
||||
end
|
||||
dn := d.path
|
||||
if a_name /= Void then
|
||||
tmp.append_character ('-')
|
||||
tmp.append_string_general (safe_filename (a_name))
|
||||
end
|
||||
|
||||
fn := dn.extended (tmp)
|
||||
create f.make_with_path (fn)
|
||||
Result := new_file_opened_for_writing (f)
|
||||
n := 0
|
||||
until
|
||||
Result /= Void
|
||||
or else n > 1_000
|
||||
loop
|
||||
n := n + 1
|
||||
create bn.make_from_string (tmp)
|
||||
bn.append_character ('-')
|
||||
bn.append_integer (n)
|
||||
fn := dn.extended (bn)
|
||||
f.make_with_path (fn)
|
||||
Result := new_file_opened_for_writing (f)
|
||||
end
|
||||
ensure
|
||||
result_opened_for_writing_if_set: Result /= Void implies Result.is_open_write
|
||||
end
|
||||
|
||||
safe_filename (fn: READABLE_STRING_GENERAL): STRING
|
||||
-- Safe filename that avoid impossible filename, or dangerous one.
|
||||
local
|
||||
c: CHARACTER_32
|
||||
i, n: INTEGER
|
||||
do
|
||||
from
|
||||
i := 1
|
||||
n := fn.count
|
||||
create Result.make (n)
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
c := fn[i]
|
||||
inspect c
|
||||
when '.', '-', '_' then
|
||||
Result.append_code (c.natural_32_code)
|
||||
when 'A' .. 'Z', 'a' .. 'z', '0' .. '9' then
|
||||
Result.append_code (c.natural_32_code)
|
||||
else
|
||||
inspect c
|
||||
when '%/192/' then Result.extend ('A') -- À
|
||||
when '%/193/' then Result.extend ('A') -- Á
|
||||
when '%/194/' then Result.extend ('A') -- Â
|
||||
when '%/195/' then Result.extend ('A') -- Ã
|
||||
when '%/196/' then Result.extend ('A') -- Ä
|
||||
when '%/197/' then Result.extend ('A') -- Å
|
||||
when '%/199/' then Result.extend ('C') -- Ç
|
||||
when '%/200/' then Result.extend ('E') -- È
|
||||
when '%/201/' then Result.extend ('E') -- É
|
||||
when '%/202/' then Result.extend ('E') -- Ê
|
||||
when '%/203/' then Result.extend ('E') -- Ë
|
||||
when '%/204/' then Result.extend ('I') -- Ì
|
||||
when '%/205/' then Result.extend ('I') -- Í
|
||||
when '%/206/' then Result.extend ('I') -- Î
|
||||
when '%/207/' then Result.extend ('I') -- Ï
|
||||
when '%/210/' then Result.extend ('O') -- Ò
|
||||
when '%/211/' then Result.extend ('O') -- Ó
|
||||
when '%/212/' then Result.extend ('O') -- Ô
|
||||
when '%/213/' then Result.extend ('O') -- Õ
|
||||
when '%/214/' then Result.extend ('O') -- Ö
|
||||
when '%/217/' then Result.extend ('U') -- Ù
|
||||
when '%/218/' then Result.extend ('U') -- Ú
|
||||
when '%/219/' then Result.extend ('U') -- Û
|
||||
when '%/220/' then Result.extend ('U') -- Ü
|
||||
when '%/221/' then Result.extend ('Y') -- Ý
|
||||
when '%/224/' then Result.extend ('a') -- à
|
||||
when '%/225/' then Result.extend ('a') -- á
|
||||
when '%/226/' then Result.extend ('a') -- â
|
||||
when '%/227/' then Result.extend ('a') -- ã
|
||||
when '%/228/' then Result.extend ('a') -- ä
|
||||
when '%/229/' then Result.extend ('a') -- å
|
||||
when '%/231/' then Result.extend ('c') -- ç
|
||||
when '%/232/' then Result.extend ('e') -- è
|
||||
when '%/233/' then Result.extend ('e') -- é
|
||||
when '%/234/' then Result.extend ('e') -- ê
|
||||
when '%/235/' then Result.extend ('e') -- ë
|
||||
when '%/236/' then Result.extend ('i') -- ì
|
||||
when '%/237/' then Result.extend ('i') -- í
|
||||
when '%/238/' then Result.extend ('i') -- î
|
||||
when '%/239/' then Result.extend ('i') -- ï
|
||||
when '%/240/' then Result.extend ('o') -- ð
|
||||
when '%/242/' then Result.extend ('o') -- ò
|
||||
when '%/243/' then Result.extend ('o') -- ó
|
||||
when '%/244/' then Result.extend ('o') -- ô
|
||||
when '%/245/' then Result.extend ('o') -- õ
|
||||
when '%/246/' then Result.extend ('o') -- ö
|
||||
when '%/249/' then Result.extend ('u') -- ù
|
||||
when '%/250/' then Result.extend ('u') -- ú
|
||||
when '%/251/' then Result.extend ('u') -- û
|
||||
when '%/252/' then Result.extend ('u') -- ü
|
||||
when '%/253/' then Result.extend ('y') -- ý
|
||||
when '%/255/' then Result.extend ('y') -- ÿ
|
||||
else
|
||||
Result.extend ('-')
|
||||
end
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
new_file_opened_for_writing (f: G): detachable G
|
||||
-- Returns a new file object opened for writing if possible
|
||||
-- otherwise returns Void.
|
||||
local
|
||||
retried: BOOLEAN
|
||||
do
|
||||
if not retried then
|
||||
if not f.exists then
|
||||
f.open_write
|
||||
if f.is_open_write then
|
||||
Result := f
|
||||
elseif not f.is_closed then
|
||||
f.close
|
||||
end
|
||||
end
|
||||
end
|
||||
ensure
|
||||
Result /= Void implies Result.is_open_write
|
||||
rescue
|
||||
retried := True
|
||||
retry
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, 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
|
||||
@@ -16,6 +16,9 @@ note
|
||||
And also has
|
||||
execution_variable (a_name: READABLE_STRING_GENERAL): detachable ANY
|
||||
--| to keep value attached to the request
|
||||
|
||||
About https support: `is_https' indicates if the request is made through an https connection or not.
|
||||
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
@@ -120,6 +123,20 @@ feature {NONE} -- Initialization
|
||||
if meta_variable ({WSF_META_NAMES}.request_time) = Void then
|
||||
set_meta_string_variable ({WSF_META_NAMES}.request_time, date_time_utilities.unix_time_stamp (Void).out)
|
||||
end
|
||||
|
||||
--| HTTPS support
|
||||
is_https := False
|
||||
if attached meta_string_variable ("HTTPS") as l_https and then not l_https.is_empty then
|
||||
is_https := l_https.is_case_insensitive_equal_general ("on")
|
||||
or else l_https.is_case_insensitive_equal_general ("yes")
|
||||
or else l_https.is_case_insensitive_equal_general ("true")
|
||||
or else l_https.is_case_insensitive_equal_general ("1")
|
||||
--| Usually, if not empty, this means this is https
|
||||
--| but it occurs that server (like IIS) sets "off" when this is NOT https
|
||||
--| so, let's be flexible, and accepts other variants of "on"
|
||||
else
|
||||
check is_not_https: is_https = False end
|
||||
end
|
||||
end
|
||||
|
||||
wgi_request: WGI_REQUEST
|
||||
@@ -156,10 +173,15 @@ feature -- Destroy
|
||||
raw_input_data_recorded := False
|
||||
request_method := empty_string_8
|
||||
set_uploaded_file_path (Void)
|
||||
is_https := False
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_https: BOOLEAN
|
||||
-- Is https connection?
|
||||
--| based on meta variable HTTPS=on .
|
||||
|
||||
debug_output: STRING_8
|
||||
do
|
||||
create Result.make_from_string (request_method + " " + request_uri)
|
||||
@@ -270,7 +292,9 @@ feature -- Access: Input
|
||||
s: STRING
|
||||
l_input: WGI_INPUT_STREAM
|
||||
l_raw_data: detachable STRING_8
|
||||
n: INTEGER
|
||||
len: NATURAL_64
|
||||
nb, l_step: INTEGER
|
||||
l_size: NATURAL_64
|
||||
do
|
||||
if raw_input_data_recorded and then attached raw_input_data as d then
|
||||
a_file.put_string (d)
|
||||
@@ -279,22 +303,47 @@ feature -- Access: Input
|
||||
create l_raw_data.make_empty
|
||||
end
|
||||
l_input := input
|
||||
len := content_length_value
|
||||
|
||||
debug ("wsf")
|
||||
io.error.put_string (generator + ".read_input_data_into_file (a_file) content_length=" + len.out + "%N")
|
||||
end
|
||||
|
||||
from
|
||||
n := 8_192
|
||||
create s.make (n)
|
||||
l_size := 0
|
||||
l_step := 8_192
|
||||
create s.make (l_step)
|
||||
until
|
||||
n = 0 or l_input.end_of_input
|
||||
l_step = 0 or l_input.end_of_input
|
||||
loop
|
||||
l_input.append_to_string (s, n)
|
||||
a_file.put_string (s)
|
||||
if l_raw_data /= Void then
|
||||
l_raw_data.append (s)
|
||||
if len < l_step.to_natural_64 then
|
||||
l_step := len.to_integer_32
|
||||
end
|
||||
s.wipe_out
|
||||
if l_input.last_appended_count < n then
|
||||
n := 0
|
||||
if l_step > 0 then
|
||||
l_input.append_to_string (s, l_step)
|
||||
nb := l_input.last_appended_count
|
||||
l_size := l_size + nb.to_natural_64
|
||||
len := len - nb.to_natural_64
|
||||
|
||||
debug ("wsf")
|
||||
io.error.put_string (" append (s, " + l_step.out + ") -> " + nb.out + " (" + l_size.out + " / "+ content_length_value.out + ")%N")
|
||||
end
|
||||
|
||||
a_file.put_string (s)
|
||||
if l_raw_data /= Void then
|
||||
l_raw_data.append (s)
|
||||
end
|
||||
s.wipe_out
|
||||
if nb < l_step then
|
||||
l_step := 0
|
||||
end
|
||||
end
|
||||
end
|
||||
a_file.flush
|
||||
debug ("wsf")
|
||||
io.error.put_string ("offset =" + len.out + "%N")
|
||||
end
|
||||
check got_all_data: len = 0 end
|
||||
if l_raw_data /= Void then
|
||||
set_raw_input_data (l_raw_data)
|
||||
end
|
||||
@@ -351,31 +400,9 @@ feature -- Helper
|
||||
-- Does client accepts content_type for the response?
|
||||
--| Based on header "Accept:" that can be for instance
|
||||
--| text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
||||
local
|
||||
i, j: INTEGER
|
||||
do
|
||||
if attached http_accept as l_accept then
|
||||
i := l_accept.substring_index (a_content_type, 1)
|
||||
if i > 0 then
|
||||
-- contains the text, now check if this is the exact text
|
||||
if
|
||||
i = 1 -- At the beginning of text
|
||||
or else l_accept[i-1].is_space -- preceded by space
|
||||
or else l_accept[i-1] = ',' -- preceded by other mime type
|
||||
then
|
||||
j := i + a_content_type.count
|
||||
if l_accept.valid_index (j) then
|
||||
Result := l_accept[j] = ',' -- followed by other mime type
|
||||
or else l_accept[j] = ';' -- followed by quality ;q=...
|
||||
or else l_accept[j].is_space -- followed by space
|
||||
else -- end of text
|
||||
Result := True
|
||||
end
|
||||
end
|
||||
end
|
||||
Result := l_accept.has_substring (a_content_type)
|
||||
else
|
||||
Result := True
|
||||
if attached (create {SERVER_MEDIA_TYPE_NEGOTIATION}.make (a_content_type.as_string_8)).preference (<<a_content_type.as_string_8>>, http_accept) as l_variants then
|
||||
Result := l_variants.is_acceptable
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1260,41 +1287,43 @@ feature {NONE} -- Cookies
|
||||
local
|
||||
i,j,p,n: INTEGER
|
||||
l_cookies: like internal_cookies_table
|
||||
s32: READABLE_STRING_32
|
||||
k,v,s: STRING
|
||||
do
|
||||
l_cookies := internal_cookies_table
|
||||
if l_cookies = Void then
|
||||
create l_cookies.make_equal (0)
|
||||
if attached {WSF_STRING} meta_variable ({WSF_META_NAMES}.http_cookie) as val then
|
||||
s := val.value
|
||||
create l_cookies.make_equal (5)
|
||||
from
|
||||
n := s.count
|
||||
p := 1
|
||||
i := 1
|
||||
until
|
||||
p < 1
|
||||
loop
|
||||
i := s.index_of ('=', p)
|
||||
if i > 0 then
|
||||
j := s.index_of (';', i)
|
||||
if j = 0 then
|
||||
j := n + 1
|
||||
k := s.substring (p, i - 1)
|
||||
v := s.substring (i + 1, n)
|
||||
s32 := val.value
|
||||
if s32.is_valid_as_string_8 then
|
||||
s := s32.to_string_8
|
||||
from
|
||||
n := s.count
|
||||
p := 1
|
||||
i := 1
|
||||
until
|
||||
p < 1
|
||||
loop
|
||||
i := s.index_of ('=', p)
|
||||
if i > 0 then
|
||||
j := s.index_of (';', i)
|
||||
if j = 0 then
|
||||
j := n + 1
|
||||
k := s.substring (p, i - 1)
|
||||
v := s.substring (i + 1, n)
|
||||
|
||||
p := 0 -- force termination
|
||||
else
|
||||
k := s.substring (p, i - 1)
|
||||
v := s.substring (i + 1, j - 1)
|
||||
p := j + 1
|
||||
p := 0 -- force termination
|
||||
else
|
||||
k := s.substring (p, i - 1)
|
||||
v := s.substring (i + 1, j - 1)
|
||||
p := j + 1
|
||||
end
|
||||
k.left_adjust
|
||||
k.right_adjust
|
||||
add_value_to_table (k, v, l_cookies)
|
||||
end
|
||||
k.left_adjust
|
||||
k.right_adjust
|
||||
add_value_to_table (k, v, l_cookies)
|
||||
end
|
||||
end
|
||||
else
|
||||
create l_cookies.make_equal (0)
|
||||
end
|
||||
internal_cookies_table := l_cookies
|
||||
end
|
||||
@@ -1443,8 +1472,12 @@ feature {NONE} -- Query parameters: implementation
|
||||
if j > 0 then
|
||||
l_name := s.substring (1, j - 1)
|
||||
l_value := s.substring (j + 1, s.count)
|
||||
add_value_to_table (l_name, l_value, Result)
|
||||
else
|
||||
-- I.e variable without value
|
||||
l_name := s
|
||||
l_value := empty_string_8
|
||||
end
|
||||
add_value_to_table (l_name, l_value, Result)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1729,10 +1762,7 @@ feature -- URL Utility
|
||||
do
|
||||
s := internal_server_url
|
||||
if s = Void then
|
||||
if
|
||||
server_protocol.count >= 5 and then
|
||||
server_protocol.substring (1, 5).is_case_insensitive_equal ("https")
|
||||
then
|
||||
if is_https then
|
||||
create s.make_from_string ("https://")
|
||||
else
|
||||
create s.make_from_string ("http://")
|
||||
@@ -1740,8 +1770,14 @@ feature -- URL Utility
|
||||
s.append (server_name)
|
||||
p := server_port
|
||||
if p > 0 then
|
||||
s.append_character (':')
|
||||
s.append_integer (p)
|
||||
if is_https and p = 443 then
|
||||
-- :443 is default for https, so no need to put it
|
||||
elseif not is_https and p = 80 then
|
||||
-- :80 is default for http, so no need to put it
|
||||
else
|
||||
s.append_character (':')
|
||||
s.append_integer (p)
|
||||
end
|
||||
end
|
||||
end
|
||||
Result := s
|
||||
@@ -1853,16 +1889,14 @@ feature {WSF_MIME_HANDLER} -- Temporary File handling
|
||||
end
|
||||
|
||||
save_uploaded_file (a_up_file: WSF_UPLOADED_FILE; a_content: STRING)
|
||||
-- Save uploaded file content to `a_filename'
|
||||
-- Save uploaded file content `a_content' into `a_filename'.
|
||||
local
|
||||
bn: STRING
|
||||
l_safe_name: STRING
|
||||
f: RAW_FILE
|
||||
dn: PATH
|
||||
fn: PATH
|
||||
d: DIRECTORY
|
||||
n: INTEGER
|
||||
rescued: BOOLEAN
|
||||
temp_fac: WSF_FILE_UTILITIES [RAW_FILE]
|
||||
l_prefix: STRING
|
||||
dt: DATE_TIME
|
||||
do
|
||||
if not rescued then
|
||||
if attached uploaded_file_path as p then
|
||||
@@ -1873,26 +1907,24 @@ feature {WSF_MIME_HANDLER} -- Temporary File handling
|
||||
end
|
||||
create d.make_with_path (dn)
|
||||
if d.exists and then d.is_writable then
|
||||
l_safe_name := a_up_file.safe_filename
|
||||
from
|
||||
bn := "tmp-" + l_safe_name
|
||||
fn := dn.extended (bn)
|
||||
create f.make_with_path (fn)
|
||||
n := 0
|
||||
until
|
||||
not f.exists
|
||||
or else n > 1_000
|
||||
loop
|
||||
n := n + 1
|
||||
bn := "tmp-" + n.out + "-" + l_safe_name
|
||||
fn := dn.extended (bn)
|
||||
f.make_with_path (fn)
|
||||
end
|
||||
create temp_fac
|
||||
|
||||
if not f.exists or else f.is_writable then
|
||||
create l_prefix.make_from_string ("tmp_uploaded_")
|
||||
create dt.make_now_utc
|
||||
l_prefix.append_integer (dt.date.ordered_compact_date)
|
||||
l_prefix.append_character ('_')
|
||||
l_prefix.append_integer (dt.time.compact_time)
|
||||
l_prefix.append_character ('.')
|
||||
l_prefix.append_integer ((dt.time.fractional_second * 1_000_000_000).truncated_to_integer)
|
||||
|
||||
if attached temp_fac.new_temporary_file (d, l_prefix, a_up_file.filename) as f then
|
||||
a_up_file.set_tmp_path (f.path)
|
||||
a_up_file.set_tmp_basename (bn)
|
||||
f.open_write
|
||||
if attached f.path.entry as e then
|
||||
a_up_file.set_tmp_basename (e.name)
|
||||
else
|
||||
a_up_file.set_tmp_basename (f.path.name) -- Should not occurs.
|
||||
end
|
||||
check f.is_open_write end
|
||||
f.put_string (a_content)
|
||||
f.close
|
||||
else
|
||||
@@ -2059,7 +2091,7 @@ invariant
|
||||
wgi_request.content_type /= Void implies content_type /= Void
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
@@ -35,15 +35,17 @@ feature {NONE} -- Initialization
|
||||
wres: detachable WSF_WGI_DELAYED_HEADER_RESPONSE
|
||||
do
|
||||
transfered_content_length := 0
|
||||
create header.make
|
||||
create internal_header.make
|
||||
wgi_response := r
|
||||
if attached {WSF_WGI_DELAYED_HEADER_RESPONSE} r as r_delayed then
|
||||
wres := r_delayed
|
||||
wres.update_wsf_response (Current)
|
||||
r_delayed.update_wsf_response (Current)
|
||||
wgi_response := r_delayed
|
||||
elseif attached {WGI_FILTER_RESPONSE} r as r_filter then
|
||||
wgi_response := r_filter.wgi_response
|
||||
else
|
||||
create wres.make (r, Current)
|
||||
wgi_response := wres
|
||||
end
|
||||
wgi_response := wres
|
||||
set_status_code ({HTTP_STATUS_CODE}.ok) -- Default value
|
||||
end
|
||||
|
||||
@@ -51,7 +53,7 @@ feature {NONE} -- Initialization
|
||||
do
|
||||
transfered_content_length := 0
|
||||
wgi_response := res.wgi_response
|
||||
header := res.header
|
||||
internal_header := res.internal_header
|
||||
set_status_code ({HTTP_STATUS_CODE}.ok) -- Default value
|
||||
end
|
||||
|
||||
@@ -60,7 +62,7 @@ feature {WSF_RESPONSE, WSF_RESPONSE_EXPORTER} -- Properties
|
||||
wgi_response: WGI_RESPONSE
|
||||
-- Associated WGI_RESPONSE.
|
||||
|
||||
header: WSF_HEADER
|
||||
internal_header: WSF_HEADER
|
||||
-- Associated response header.
|
||||
|
||||
feature {WSF_RESPONSE_EXPORTER} -- Change
|
||||
@@ -156,7 +158,7 @@ feature {WSF_RESPONSE_EXPORTER} -- Header output operation
|
||||
-- commit status code and reason phrase
|
||||
wgi_response.set_status_code (status_code, status_reason_phrase)
|
||||
-- commit header text
|
||||
wgi_response.put_header_text (header.string)
|
||||
wgi_response.put_header_text (internal_header.string)
|
||||
end
|
||||
ensure
|
||||
status_committed: status_committed
|
||||
@@ -168,6 +170,26 @@ feature {WSF_RESPONSE_EXPORTER} -- Header output operation
|
||||
put_error ("Content already sent, new header text ignored!")
|
||||
end
|
||||
|
||||
feature -- Header access
|
||||
|
||||
header: HTTP_HEADER_MODIFIER
|
||||
-- Associated header builder interface.
|
||||
local
|
||||
res: like internal_response_header
|
||||
do
|
||||
res := internal_response_header
|
||||
if res = Void then
|
||||
create {WSF_RESPONSE_HEADER} res.make_with_response (Current)
|
||||
internal_response_header := res
|
||||
end
|
||||
Result := res
|
||||
end
|
||||
|
||||
feature {NONE} -- Header access
|
||||
|
||||
internal_response_header: detachable like header
|
||||
-- Cached version of `header'.
|
||||
|
||||
feature -- Header output operation
|
||||
|
||||
put_header_line (h: READABLE_STRING_8)
|
||||
@@ -179,7 +201,7 @@ feature -- Header output operation
|
||||
if header_committed then
|
||||
report_content_already_sent_and_header_ignored
|
||||
else
|
||||
header.put_header (h)
|
||||
internal_header.put_header (h)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -192,7 +214,7 @@ feature -- Header output operation
|
||||
if header_committed then
|
||||
report_content_already_sent_and_header_ignored
|
||||
else
|
||||
header.add_header (h)
|
||||
internal_header.add_header (h)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -207,7 +229,7 @@ feature -- Header output operation
|
||||
if header_committed then
|
||||
report_content_already_sent_and_header_ignored
|
||||
else
|
||||
header.put_raw_header_data (a_text)
|
||||
internal_header.put_raw_header_data (a_text)
|
||||
end
|
||||
ensure
|
||||
message_writable: message_writable
|
||||
@@ -225,7 +247,7 @@ feature -- Header output operation
|
||||
if header_committed then
|
||||
report_content_already_sent_and_header_ignored
|
||||
else
|
||||
header.append_raw_header_data (a_text)
|
||||
internal_header.append_raw_header_data (a_text)
|
||||
end
|
||||
ensure
|
||||
status_set: status_is_set
|
||||
@@ -494,7 +516,7 @@ feature -- Error reporting
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2014, 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
|
||||
|
||||
64
library/server/wsf/src/wsf_response_header.e
Normal file
64
library/server/wsf/src/wsf_response_header.e
Normal file
@@ -0,0 +1,64 @@
|
||||
note
|
||||
description: "[
|
||||
Interface to build the http header associated with WSF_RESPONSE.
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WSF_RESPONSE_HEADER
|
||||
|
||||
inherit
|
||||
HTTP_HEADER_MODIFIER
|
||||
|
||||
WSF_RESPONSE_EXPORTER -- to access WSF_RESPONSE.internal_header
|
||||
|
||||
create
|
||||
make_with_response
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_with_response (res: WSF_RESPONSE)
|
||||
do
|
||||
response := res
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
response: WSF_RESPONSE
|
||||
|
||||
feature -- Access
|
||||
|
||||
new_cursor: INDEXABLE_ITERATION_CURSOR [READABLE_STRING_8]
|
||||
-- Fresh cursor associated with current structure.
|
||||
do
|
||||
Result := response.internal_header.new_cursor
|
||||
end
|
||||
|
||||
feature -- Header change: core
|
||||
|
||||
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
|
||||
do
|
||||
response.add_header_line (h)
|
||||
end
|
||||
|
||||
put_header (h: READABLE_STRING_8)
|
||||
-- Add header `h' or replace existing header of same header name
|
||||
do
|
||||
response.put_header_line (h)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, 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
|
||||
149
library/server/wsf/tests/src/test_wsf_file_utilities.e
Normal file
149
library/server/wsf/tests/src/test_wsf_file_utilities.e
Normal file
@@ -0,0 +1,149 @@
|
||||
note
|
||||
description: "Summary description for {TEST_WSF_FILE_UTILITIES}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
TEST_WSF_FILE_UTILITIES
|
||||
|
||||
inherit
|
||||
EQA_TEST_SET
|
||||
|
||||
SHARED_EXECUTION_ENVIRONMENT
|
||||
undefine
|
||||
default_create, copy
|
||||
end
|
||||
|
||||
feature -- Tests
|
||||
|
||||
test_temporary_file_0
|
||||
do
|
||||
test_temporary_file (0)
|
||||
end
|
||||
|
||||
test_temporary_file_1_ns
|
||||
do
|
||||
test_temporary_file (1)
|
||||
end
|
||||
|
||||
test_temporary_file_100_ns
|
||||
do
|
||||
test_temporary_file (100)
|
||||
end
|
||||
|
||||
test_temporary_file_1_s
|
||||
do
|
||||
test_temporary_file (1_000_000_000)
|
||||
end
|
||||
|
||||
new_temp_prefix: STRING
|
||||
local
|
||||
dt: DATE_TIME
|
||||
do
|
||||
create dt.make_now_utc
|
||||
Result := "TEMP_"
|
||||
Result.append_integer (dt.date.ordered_compact_date)
|
||||
Result.append_character ('_')
|
||||
Result.append_integer (dt.time.compact_time)
|
||||
Result.append_character ('.')
|
||||
-- Result.append_integer (dt.time.milli_second)
|
||||
Result.append_integer ((dt.time.fractional_second * 1_000_000_000).truncated_to_integer)
|
||||
end
|
||||
|
||||
test_temporary_file (a_delay: INTEGER_64)
|
||||
local
|
||||
f: detachable FILE
|
||||
f1,f2: detachable FILE
|
||||
fac: WSF_FILE_UTILITIES [RAW_FILE]
|
||||
d: DIRECTORY
|
||||
logs: STRING_32
|
||||
l_prefix: STRING
|
||||
do
|
||||
|
||||
create logs.make (0)
|
||||
|
||||
create d.make_with_path ((create {PATH}.make_current).extended ("_tmp_"))
|
||||
d.recursive_create_dir
|
||||
|
||||
create fac
|
||||
|
||||
l_prefix := new_temp_prefix
|
||||
f := fac.new_temporary_file (d, l_prefix, "l'<27>t<EFBFBD> est l<>!")
|
||||
if f /= Void then
|
||||
create {RAW_FILE}f1.make_with_path (f.path)
|
||||
f1.open_write
|
||||
f1.close
|
||||
|
||||
logs.append ("f="); logs.append (f.path.name); logs.append ("%N")
|
||||
if a_delay > 0 then
|
||||
-- Wait `a_delay' in nanoseconds.
|
||||
execution_environment.sleep (a_delay)
|
||||
l_prefix := new_temp_prefix
|
||||
end
|
||||
f1 := fac.new_temporary_file (d, l_prefix, "l'<27>t<EFBFBD> est l<>!")
|
||||
|
||||
if a_delay > 0 then
|
||||
-- Wait `a_delay' in nanoseconds.
|
||||
execution_environment.sleep (a_delay)
|
||||
l_prefix := new_temp_prefix
|
||||
end
|
||||
f2 := fac.new_temporary_file (d, l_prefix, "l'<27>t<EFBFBD> est l<>!")
|
||||
|
||||
if f1 /= Void then
|
||||
logs.append ("f1="); logs.append (f1.path.name); logs.append ("%N")
|
||||
f.put_string ("test")
|
||||
f1.put_string ("blabla")
|
||||
f1.close
|
||||
else
|
||||
assert ("able to create new file f1", False)
|
||||
end
|
||||
if f2 /= Void then
|
||||
logs.append ("f2="); logs.append (f2.path.name); logs.append ("%N")
|
||||
f.put_string ("TEST")
|
||||
f2.put_string ("BLABLA")
|
||||
f2.close
|
||||
else
|
||||
assert ("able to create new file f1", False)
|
||||
end
|
||||
assert ("f1 /= f2", (f1 /= Void and f2 /= Void) and then (not f1.path.is_same_file_as (f2.path)))
|
||||
f.close
|
||||
|
||||
assert ("expected content for f", content (f).same_string ("testTEST"))
|
||||
assert ("expected content for f1", content (f1).same_string ("blabla"))
|
||||
assert ("expected content for f2", content (f2).same_string ("BLABLA"))
|
||||
else
|
||||
assert ("able to create new file f", False)
|
||||
end
|
||||
-- Cleaning
|
||||
|
||||
if f /= Void then
|
||||
f.delete
|
||||
end
|
||||
if f1 /= Void then
|
||||
f1.delete
|
||||
end
|
||||
if f2 /= Void then
|
||||
f2.delete
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
content (f: detachable FILE): STRING
|
||||
do
|
||||
create Result.make (0)
|
||||
if f /= Void then
|
||||
from
|
||||
f.open_read
|
||||
assert (f.path.utf_8_name + " is opened", f.is_open_read)
|
||||
until
|
||||
f.end_of_file or f.exhausted
|
||||
loop
|
||||
f.read_stream (1_024)
|
||||
Result.append (f.last_string)
|
||||
end
|
||||
f.close
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -110,9 +110,9 @@ feature {NONE} -- Events
|
||||
create h.make
|
||||
b := base_url
|
||||
if b = Void then
|
||||
b := ""
|
||||
b := "/"
|
||||
end
|
||||
if attached {HTTP_CLIENT_SESSION} h.new_session ("localhost:" + port_number.out + "/" + b) as sess then
|
||||
if attached {HTTP_CLIENT_SESSION} h.new_session ("localhost:" + port_number.out + b) as sess then
|
||||
http_session := sess
|
||||
sess.set_timeout (-1)
|
||||
sess.set_is_debug (True)
|
||||
@@ -125,10 +125,16 @@ feature {NONE} -- Events
|
||||
do
|
||||
get_http_session
|
||||
if attached http_session as sess then
|
||||
if attached sess.get (a_url, adapted_context (ctx)) as res and then not res.error_occurred and then attached res.body as l_body then
|
||||
assert ("Good answer got=%""+l_body+"%" expected=%""+a_expected_body+"%"", l_body.same_string (a_expected_body))
|
||||
else
|
||||
assert ("Request %""+a_url+"%" failed", False)
|
||||
if attached sess.get (a_url, adapted_context (ctx)) as res then
|
||||
if attached res.body as l_body then
|
||||
if res.error_occurred then
|
||||
assert ("Request %""+a_url+"%" failed, got=[" + l_body + "]", False)
|
||||
else
|
||||
assert ("Good answer got=%""+l_body+"%" expected=%""+a_expected_body+"%"", l_body.same_string (a_expected_body))
|
||||
end
|
||||
else
|
||||
assert ("Request %""+a_url+"%" failed, no body, status=" + res.status.out , False)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -64,7 +64,7 @@ Content-Disposition: form-data; name="password"
|
||||
EWFpassword
|
||||
--__=_the_boundary_1332296477_1804289383_=__--
|
||||
]"
|
||||
|
||||
b.replace_substring_all ("%N", "%R%N")
|
||||
h.put_content_length (b.count)
|
||||
|
||||
--| Case #1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-10-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-10-0 http://www.eiffel.com/developers/xml/configuration-1-10-0.xsd" name="wsf_tests" uuid="C4FF9CDA-B4E4-4841-97E0-7F799B85B657">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="wsf_tests" uuid="C4FF9CDA-B4E4-4841-97E0-7F799B85B657">
|
||||
<target name="server">
|
||||
<root class="TEST" feature="make"/>
|
||||
<file_rule>
|
||||
@@ -23,6 +23,7 @@
|
||||
<library name="http" location="..\..\..\network\protocol\http\http-safe.ecf" readonly="false"/>
|
||||
<library name="http_client" location="..\..\..\network\http_client\http_client-safe.ecf" readonly="false"/>
|
||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||
<library name="wsf" location="..\wsf-safe.ecf" readonly="false">
|
||||
<option>
|
||||
<assertions precondition="true" postcondition="true" check="true" supplier_precondition="true"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-11-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-11-0 http://www.eiffel.com/developers/xml/configuration-1-11-0.xsd" name="wsf" uuid="A37CE5AA-4D2A-4441-BC6A-0A1D7EC49647" library_target="wsf">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-12-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-12-0 http://www.eiffel.com/developers/xml/configuration-1-12-0.xsd" name="wsf" uuid="A37CE5AA-4D2A-4441-BC6A-0A1D7EC49647" library_target="wsf">
|
||||
<target name="wsf">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
@@ -11,6 +11,7 @@
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/>
|
||||
<library name="conneg" location="..\..\network\protocol\content_negotiation\conneg-safe.ecf"/>
|
||||
<library name="encoder" location="..\..\text\encoder\encoder-safe.ecf"/>
|
||||
<library name="error" location="..\..\utility\general\error\error-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\ewsgi\ewsgi-safe.ecf"/>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||
<library name="error" location="../../utility/general/error/error.ecf"/>
|
||||
<library name="http" location="../../network/protocol/http/http.ecf"/>
|
||||
<library name="conneg" location="..\..\network\protocol\content_negotiation\conneg.ecf"/>
|
||||
<library name="uri_template"
|
||||
location="../../text/parser/uri_template/uri_template.ecf"/>
|
||||
<library name="encoder"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="encoder" location="..\..\text\encoder\encoder-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\ewsgi\ewsgi-safe.ecf"/>
|
||||
<library name="http" location="..\..\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="wsf" location="wsf-safe.ecf"/>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<option warning="true" full_class_checking="true" void_safety="none" syntax="standard">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY/library/base/base.ecf"/>
|
||||
<library name="encoder" location="..\..\text\encoder\encoder.ecf"/>
|
||||
<library name="http" location="../../network/protocol/http/http.ecf"/>
|
||||
<library name="ewsgi" location="..\ewsgi\ewsgi.ecf"/>
|
||||
<library name="wsf" location="wsf.ecf"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-11-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-11-0 http://www.eiffel.com/developers/xml/configuration-1-11-0.xsd" name="wsf_policy_driven" uuid="3FC00449-5101-461D-94C6-10920C30EBF4" library_target="wsf_policy_driven">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="wsf_policy_driven" uuid="3FC00449-5101-461D-94C6-10920C30EBF4" library_target="wsf_policy_driven">
|
||||
<target name="wsf_policy_driven">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
@@ -10,12 +10,12 @@
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="conneg" location="..\..\network\protocol\content_negotiation\conneg-safe.ecf"/>
|
||||
<library name="encoder" location="..\..\text\encoder\encoder-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\ewsgi\ewsgi-safe.ecf"/>
|
||||
<library name="http" location="..\..\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\ewsgi\ewsgi-safe.ecf"/>
|
||||
<library name="conneg" location="../../network/protocol/CONNEG/conneg-safe.ecf"/>
|
||||
<library name="encoder" location="..\..\text\encoder\encoder-safe.ecf"/>
|
||||
<library name="http" location="..\..\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="wsf" location="wsf-safe.ecf"/>
|
||||
<cluster name="policy" location=".\policy_driven\" recursive="true"/>
|
||||
</target>
|
||||
|
||||
10
library/server/wsf/wsf_policy_driven-safe.lic
Normal file
10
library/server/wsf/wsf_policy_driven-safe.lic
Normal file
@@ -0,0 +1,10 @@
|
||||
${NOTE_KEYWORD}
|
||||
copyright: "2011-${YEAR}, Colin Adams, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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
|
||||
]"
|
||||
@@ -13,7 +13,7 @@
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri.ecf"/>
|
||||
<library name="ewsgi" location="..\ewsgi\ewsgi.ecf"/>
|
||||
<library name="conneg" location="../../network/protocol/CONNEG/conneg.ecf"/>
|
||||
<library name="conneg" location="../../network/protocol/content_negotiation/conneg.ecf"/>
|
||||
<library name="encoder" location="..\..\text\encoder\encoder.ecf"/>
|
||||
<library name="http" location="..\..\network\protocol\http\http.ecf"/>
|
||||
<library name="wsf" location="wsf.ecf"/>
|
||||
|
||||
10
library/server/wsf/wsf_policy_driven.lic
Normal file
10
library/server/wsf/wsf_policy_driven.lic
Normal file
@@ -0,0 +1,10 @@
|
||||
${NOTE_KEYWORD}
|
||||
copyright: "2011-${YEAR}, Colin Adams, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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
|
||||
]"
|
||||
Reference in New Issue
Block a user