Merge branch 'master' of github.com:EiffelWebFramework/EWF into widget_integration

This commit is contained in:
2014-07-07 10:30:42 +02:00
318 changed files with 14865 additions and 10865 deletions

View File

@@ -0,0 +1,235 @@
note
description : "simple application root class"
date : "$Date$"
revision : "$Revision$"
class
DEMO_BASIC
inherit
WSF_DEFAULT_SERVICE
redefine
initialize
end
SHARED_HTML_ENCODER
create
make_and_launch
feature {NONE} -- Initialization
initialize
-- Initialize current service.
do
set_service_option ("port", 9090)
set_service_option ("verbose", True)
end
feature -- Credentials
is_known_login (a_login: READABLE_STRING_GENERAL): BOOLEAN
-- Is `a_login' a known username?
do
Result := valid_credentials.has (a_login)
end
is_valid_credential (a_login: READABLE_STRING_GENERAL; a_password: detachable READABLE_STRING_GENERAL): BOOLEAN
-- Is `a_login:a_password' a valid credential?
do
if
a_password /= Void and
attached valid_credentials.item (a_login) as l_passwd
then
Result := a_password.is_case_insensitive_equal (l_passwd)
end
ensure
Result implies is_known_login (a_login)
end
demo_credential: STRING_32
-- First valid known credential display for demo in dialog.
do
valid_credentials.start
create Result.make_from_string_general (valid_credentials.key_for_iteration)
Result.append_character (':')
Result.append (valid_credentials.item_for_iteration)
end
valid_credentials: STRING_TABLE [READABLE_STRING_32]
-- Password indexed by login.
once
create Result.make_caseless (3)
Result.force ("world", "eiffel")
Result.force ("bar", "foo")
Result.force ("password", "user")
ensure
not Result.is_empty
end
feature -- Basic operations
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
auth: HTTP_AUTHORIZATION
l_authenticated_username: detachable READABLE_STRING_32
l_invalid_credential: BOOLEAN
do
if attached req.http_authorization as l_http_auth then
create auth.make (l_http_auth)
if attached auth.login as l_login and then is_valid_credential (l_login, auth.password) then
l_authenticated_username := auth.login
else
l_invalid_credential := True
end
end
if l_invalid_credential then
handle_unauthorized ("ERROR: Invalid credential", req, res)
else
if l_authenticated_username /= Void then
handle_authenticated (l_authenticated_username, req, res)
elseif req.path_info.same_string_general ("/login") then
handle_unauthorized ("Please provide credential ...", req, res)
elseif req.path_info.starts_with_general ("/protected/") then
-- any "/protected/*" url
handle_unauthorized ("Protected area, please sign in before", req, res)
else
handle_anonymous (req, res)
end
end
end
handle_authenticated (a_username: READABLE_STRING_32; req: WSF_REQUEST; res: WSF_RESPONSE)
-- User `a_username' is authenticated, execute request `req' with response `res'.
require
valid_username: not a_username.is_empty
known_username: is_known_login (a_username)
local
s: STRING
page: WSF_HTML_PAGE_RESPONSE
do
create s.make_empty
append_html_header (req, s)
s.append ("<p>The authenticated user is <strong>")
s.append (html_encoder.general_encoded_string (a_username))
s.append ("</strong> ...</p>")
append_html_menu (a_username, req, s)
append_html_logout (a_username, req, s)
append_html_footer (req, s)
create page.make
page.set_body (s)
res.send (page)
end
handle_anonymous (req: WSF_REQUEST; res: WSF_RESPONSE)
-- No user is authenticated, execute request `req' with response `res'.
local
s: STRING
page: WSF_HTML_PAGE_RESPONSE
do
create s.make_empty
append_html_header (req, s)
s.append ("Anonymous visitor ...<br/>")
append_html_login (req, s)
append_html_menu (Void, req, s)
append_html_footer (req, s)
create page.make
page.set_body (s)
res.send (page)
end
handle_unauthorized (a_description: STRING; req: WSF_REQUEST; res: WSF_RESPONSE)
-- Restricted page, authenticated user is required.
-- Send `a_description' as part of the response.
local
h: HTTP_HEADER
s: STRING
page: WSF_HTML_PAGE_RESPONSE
do
create s.make_from_string (a_description)
append_html_login (req, s)
append_html_menu (Void, req, s)
append_html_footer (req, s)
create page.make
page.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
page.header.put_header_key_value ({HTTP_HEADER_NAMES}.header_www_authenticate,
"Basic realm=%"Please enter a valid username and password (demo [" + html_encoder.encoded_string (demo_credential) + "])%""
--| warning: for this example: a valid credential is provided in the message, of course that for real application.
)
page.set_body (s)
res.send (page)
end
feature -- Helper
append_html_header (req: WSF_REQUEST; s: STRING)
-- Append header paragraph to `s'.
do
s.append ("<p>The current page is " + html_encoder.encoded_string (req.path_info) + "</p>")
end
append_html_menu (a_username: detachable READABLE_STRING_32; req: WSF_REQUEST; s: STRING)
-- Append menu to `s'.
-- when an user is authenticated, `a_username' is attached.
do
if a_username /= Void then
s.append ("<li><a href=%""+ req.absolute_script_url ("") +"%">Your account</a> (displayed only is user is authenticated!)</li>")
end
s.append ("<li><a href=%""+ req.absolute_script_url ("") +"%">home</a></li>")
s.append ("<li><a href=%""+ req.script_url ("/public/area") +"%">public area</a></li>")
s.append ("<li><a href=%""+ req.script_url ("/protected/area") +"%">protected area</a></li>")
end
append_html_login (req: WSF_REQUEST; s: STRING)
-- Append login link to `s'.
do
s.append ("<li><a href=%""+ req.script_url ("/login") +"%">sign in</a></li>")
end
append_html_logout (a_username: detachable READABLE_STRING_32; req: WSF_REQUEST; s: STRING)
-- Append logout link to `s'.
local
l_logout_url: STRING
do
l_logout_url := req.absolute_script_url ("/login")
l_logout_url.replace_substring_all ("://", "://_@") -- Hack to clear http authorization, i.e connect with bad username "_".
s.append ("<li><a href=%""+ l_logout_url +"%">logout</a></li>")
end
append_html_footer (req: WSF_REQUEST; s: STRING)
-- Append html footer to `s'.
local
hauth: HTTP_AUTHORIZATION
do
s.append ("<hr/>")
if attached req.http_authorization as l_http_authorization then
s.append ("Has <em>Authorization:</em> header: ")
create hauth.make (req.http_authorization)
if attached hauth.login as l_login then
s.append (" login=<strong>" + html_encoder.encoded_string (l_login)+ "</strong>")
end
if attached hauth.password as l_password then
s.append (" password=<strong>" + html_encoder.encoded_string (l_password)+ "</strong>")
end
s.append ("<br/>")
end
if attached req.raw_header_data as l_header then
-- Append the raw header data for information
s.append ("Raw header data:")
s.append ("<pre>")
s.append (l_header)
s.append ("</pre>")
end
end
end

View File

@@ -0,0 +1,21 @@
<?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="basic" uuid="9CB82EB8-CA38-44CD-9CC8-EBC56401BBB2">
<target name="basic">
<root class="DEMO_BASIC" feature="make_and_launch"/>
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="http" location="..\..\..\..\network\protocol\http\http-safe.ecf"/>
<library name="http_auth" location="..\http_authorization-safe.ecf"/>
<library name="encoders" location="..\..\..\..\text\encoder\encoder-safe.ecf"/>
<library name="wsf" location="..\..\..\wsf\wsf-safe.ecf"/>
<library name="default_nino" location="..\..\..\wsf\default\nino-safe.ecf"/>
<cluster name="src" location=".\" recursive="true"/>
</target>
</system>

View File

@@ -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="http_authorization" uuid="321674DB-CE7C-417C-ADE8-64CFA376CD3E" library_target="http_authorization">
<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="http_authorization" uuid="321674DB-CE7C-417C-ADE8-64CFA376CD3E" library_target="http_authorization">
<target name="http_authorization">
<root all_classes="true"/>
<file_rule>

View File

@@ -0,0 +1,15 @@
package http_authorization
project
http_authorization = "http_authorization-safe.ecf"
http_authorization = "http_authorization.ecf"
note
-- title:
-- description:
-- tags:
-- license:
-- copyright:
-- link[doc]: "Documentation" http://
end

View File

@@ -1,8 +1,12 @@
note
description : "Objects that ..."
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
description : "[
Object representing Authorization http header
]"
date: "$Date$"
revision: "$Revision$"
EIS: "name=RFC2617 HTTP Authentication: Basic and Digest Access Authentication", "protocol=URI", "src=http://tools.ietf.org/html/rfc2617"
EIS: "name=Wikipedia Basic Access Authentication", "protocol=URI", "src=http://en.wikipedia.org/wiki/Basic_access_authentication"
EIS: "name=Wikipedia Digest Access Authentication", "protocol=URI", "src=http://en.wikipedia.org/wiki/Digest_access_authentication"
class
HTTP_AUTHORIZATION
@@ -10,101 +14,152 @@ class
inherit
REFACTORING_HELPER
DEBUG_OUTPUT
create
make,
make_basic_auth,
make_custom_auth
feature {NONE} -- Initialization
feature -- Initialization
make (a_http_authorization: detachable READABLE_STRING_GENERAL)
make (a_http_authorization: detachable READABLE_STRING_8)
-- Initialize `Current'.
local
i: INTEGER
t, s: STRING_8
u,p: READABLE_STRING_8
u,p: READABLE_STRING_32
utf: UTF_CONVERTER
do
if a_http_authorization /= Void then
s := a_http_authorization.as_string_8
create http_authorization.make_from_string (s)
if not s.is_empty then
login := Void
password := Void
if a_http_authorization = Void then
-- Default: Basic
type := basic_auth_type
http_authorization := Void
else
create http_authorization.make_from_string (a_http_authorization)
create t.make_empty
type := t
if not a_http_authorization.is_empty then
i := 1
if s[i] = ' ' then
if a_http_authorization[i] = ' ' then
i := i + 1
end
i := s.index_of (' ', i)
i := a_http_authorization.index_of (' ', i)
if i > 0 then
t := s.substring (1, i - 1).as_lower
t.append (a_http_authorization.substring (1, i - 1))
t.right_adjust; t.left_adjust
type := t
if t.same_string ("basic") then
s := (create {BASE64}).decoded_string (s.substring (i + 1, s.count))
if t.same_string (Basic_auth_type) then
type := Basic_auth_type
s := (create {BASE64}).decoded_string (a_http_authorization.substring (i + 1, a_http_authorization.count))
i := s.index_of (':', 1) --| Let's assume ':' is forbidden in login ...
if i > 0 then
u := s.substring (1, i - 1).as_string_32
p := s.substring (i + 1, s.count).as_string_32
u := utf.utf_8_string_8_to_string_32 (s.substring (1, i - 1)) -- UTF_8 decoding to support unicode password
p := utf.utf_8_string_8_to_string_32 (s.substring (i + 1, s.count)) -- UTF_8 decoding to support unicode password
login := u
password := p
check
(create {HTTP_AUTHORIZATION}.make_custom_auth (u, p, t)).http_authorization ~ http_authorization
end
end
elseif t.same_string ("digest") then
elseif t.same_string (Digest_auth_type) then
type := Digest_auth_type
to_implement ("HTTP Authorization %"digest%", not yet implemented")
else
to_implement ("HTTP Authorization %""+ t +"%", not yet implemented")
end
end
end
else
http_authorization := Void
end
ensure
a_http_authorization /= Void implies http_authorization /= Void
end
make_basic_auth (u: READABLE_STRING_32; p: READABLE_STRING_32)
-- Create a Basic authentication.
do
make_custom_auth (u, p, "basic")
make_custom_auth (u, p, Basic_auth_type)
end
make_custom_auth (u: READABLE_STRING_32; p: READABLE_STRING_32; a_type: READABLE_STRING_8)
-- Create a custom `a_type' authentication.
require
a_type_accepted: a_type.is_case_insensitive_equal (Basic_auth_type)
or a_type.is_case_insensitive_equal (Digest_auth_type)
local
t: STRING_8
utf: UTF_CONVERTER
do
login := u
password := p
create t.make_from_string (a_type.as_lower)
create t.make_from_string (a_type)
t.left_adjust; t.right_adjust
type := t
if t.same_string ("basic") then
create http_authorization.make_from_string ("Basic " + (create {BASE64}).encoded_string (u + ":" + p))
if t.is_case_insensitive_equal (Basic_auth_type) then
type := Basic_auth_type
create http_authorization.make_from_string ("Basic " + (create {BASE64}).encoded_string (utf.string_32_to_utf_8_string_8 (u + {STRING_32} ":" + p)))
elseif t.is_case_insensitive_equal (Digest_auth_type) then
type := Digest_auth_type
to_implement ("HTTP Authorization %""+ t +"%", not yet implemented")
create http_authorization.make_from_string (t + " ...NOT IMPLEMENTED")
else
to_implement ("HTTP Authorization %""+ t +"%", not yet implemented")
create http_authorization.make_from_string ("Digest ...NOT IMPLEMENTED")
end
end
feature -- Access
type: detachable READABLE_STRING_8
http_authorization: detachable IMMUTABLE_STRING_8
type: READABLE_STRING_8
login: detachable READABLE_STRING_32
password: detachable READABLE_STRING_32
http_authorization: detachable IMMUTABLE_STRING_8
feature -- Status report
is_basic: BOOLEAN
-- Is Basic authorization?
do
if attached type as t then
Result := t.same_string ("basic")
Result := type.is_case_insensitive_equal (Basic_auth_type)
end
is_digest: BOOLEAN
-- Is Basic authorization?
do
Result := type.is_case_insensitive_equal (Digest_auth_type)
end
debug_output: STRING_32
-- String that should be displayed in debugger to represent `Current'.
do
create Result.make_empty
Result.append (type)
Result.append (" ")
if attached login as l_login then
Result.append ("login=[")
Result.append (l_login)
Result.append ("] ")
end
if attached password as l_password then
Result.append ("password=[")
Result.append (l_password)
Result.append ("] ")
end
end
feature -- Constants
Basic_auth_type: STRING_8 = "Basic"
Digest_auth_type: STRING_8 = "Digest"
invariant
type_is_lower: attached type as t implies t.same_string (t.as_lower)
type_valid: (type.is_case_insensitive_equal (basic_auth_type) implies type = basic_auth_type)
or (type.is_case_insensitive_equal (Digest_auth_type) implies type = Digest_auth_type)
end

View File

@@ -0,0 +1,57 @@
note
description: "[
Eiffel tests that can be executed by testing tool.
]"
author: "EiffelStudio test wizard"
date: "$Date$"
revision: "$Revision$"
testing: "type/manual"
class
HTTP_AUTHORIZATION_TESTS
inherit
EQA_TEST_SET
feature -- Test routines
test_basic
-- New test routine
local
l_auth: READABLE_STRING_8
u,p: detachable READABLE_STRING_32
h: HTTP_AUTHORIZATION
do
l_auth := "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
create h.make (l_auth)
assert ("login", attached h.login as l_login and then l_login.same_string ("Aladdin"))
assert ("password", attached h.password as l_password and then l_password.same_string ("open sesame"))
check_basic_auth_for_login_password ("Aladdin", "open sesame", "Aladdin")
check_basic_auth_for_login_password ("", "", "empty")
check_basic_auth_for_login_password ("@#$@%%@??<.,.,", "@@#$&)&*>M<?>:ASDFDSA''", "symbol")
check_basic_auth_for_login_password ({STRING_32} "%/20320/%/22909/%/21527/", {STRING_32}"%/20320/%/22909/%/21527/", "unicode")
check_basic_auth_for_login_password (create {STRING_32}.make_filled ('u', 100) + {STRING_32}"%/20320/%/22909/%/21527/", create {STRING_32}.make_filled ('p', 100) + {STRING_32}"%/20320/%/22909/%/21527/", "long unicode")
end
feature -- Impl
check_basic_auth_for_login_password (u,p: READABLE_STRING_32; a_title: READABLE_STRING_8)
local
h: HTTP_AUTHORIZATION
l_auth: detachable READABLE_STRING_8
do
create h.make_basic_auth (u, p)
assert (a_title + ":login", attached h.login as l_login and then l_login.same_string (u))
assert (a_title + ":password", attached h.password as l_password and then l_password.same_string (p))
l_auth := h.http_authorization
create h.make (l_auth)
assert (a_title + ":basic", h.type.is_case_insensitive_equal ("Basic"))
assert (a_title + ":login", attached h.login as l_login and then l_login.same_string (u))
assert (a_title + ":password", attached h.password as l_password and then l_password.same_string (p))
end
end

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<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="testing" uuid="1AEF36BD-FB72-4B52-8845-4EF4AC7B709A">
<target name="testing">
<root class="ANY" feature="default_create"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="transitional" syntax="standard">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="concurrency" value="none"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="http_authorization" location="..\http_authorization-safe.ecf" readonly="false" use_application_options="true"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
<tests name="tests" location=".\" recursive="true"/>
</target>
</system>

View File

@@ -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="connector_cgi" uuid="3BCBC1C5-9D99-45BB-B15D-B03D2C069CED" library_target="connector_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="connector_cgi" uuid="3BCBC1C5-9D99-45BB-B15D-B03D2C069CED" library_target="connector_cgi">
<target name="connector_cgi">
<root all_classes="true"/>
<file_rule>

View File

@@ -62,6 +62,7 @@ feature -- Execution
rescued: BOOLEAN
do
if not rescued then
a_input.reset
create req.make (vars, a_input, Current)
create res.make (a_output, a_output)
service.execute (req, res)

View File

@@ -32,6 +32,21 @@ feature {NONE} -- Initialization
create last_string.make_empty
end
feature -- Reset
reset
-- Reset current input stream
-- especially any previous error if any.
do
debug ("wsf")
io.error.put_string (generator + " : reset %N")
end
last_string.wipe_out
last_character := '%U'
internal_end_of_input := False
fcgi.fcgi_clearerr
end
feature -- Status report
is_open_read: BOOLEAN
@@ -43,9 +58,11 @@ feature -- Status report
end_of_input: BOOLEAN
-- Has the end of input stream been reached?
do
Result := fcgi.fcgi_end_of_input
Result := fcgi.fcgi_end_of_input or internal_end_of_input
end
internal_end_of_input: BOOLEAN
feature -- Input
read_character
@@ -59,6 +76,7 @@ feature -- Input
if s.count >= 1 then
last_character := s.item (1)
else
internal_end_of_input := True
last_character := '%U'
end
end
@@ -69,6 +87,7 @@ feature -- Input
-- Make result available in `last_string'.
do
fcgi.fill_string_from_stdin (last_string, nb_char)
internal_end_of_input := last_string.count < nb_char
end
feature -- Access
@@ -86,7 +105,7 @@ feature {NONE} -- Implementation
-- Bridge to FCGI world
note
copyright: "2011-2011, Eiffel Software and others"
copyright: "2011-2013, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -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="connector_nino" uuid="F91861FB-4FEA-455F-9570-828D7903DC64" library_target="connector_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="connector_nino" uuid="F91861FB-4FEA-455F-9570-828D7903DC64" library_target="connector_nino">
<target name="connector_nino">
<root all_classes="true"/>
<file_rule>
@@ -7,12 +7,13 @@
<exclude>/\.git$</exclude>
<exclude>/\.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all">
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
</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-safe.ecf" readonly="false"/>
<library name="http" location="../../../../network/protocol/http/http-safe.ecf"/>
<library name="nino" location="../../../../../contrib/library/network/server/nino/nino-safe.ecf" readonly="false">
<library name="http" location="..\..\..\..\network\protocol\http\http-safe.ecf"/>
<library name="nino" location="..\..\..\..\..\contrib\library\network\server\nino\nino-safe.ecf" readonly="false">
<renaming old_name="HTTP_CONSTANTS" new_name="NINO_HTTP_CONSTANTS"/>
</library>
<cluster name="src" location=".\src\" recursive="true"/>

View File

@@ -10,6 +10,7 @@
<option warning="true" full_class_checking="true">
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="encoder" location="../../../../text/encoder/encoder.ecf"/>
<library name="ewsgi" location="..\..\ewsgi.ecf" readonly="false"/>
<library name="http" location="../../../../network/protocol/http/http.ecf"/>
<library name="nino" location="../../../../../contrib/library/network/server/nino/nino.ecf" readonly="false">

View File

@@ -28,13 +28,13 @@ feature {NONE} -- Implementation
create connector.make_with_base (a_service, a_base_url)
end
make_with_callback (a_callback: like {WGI_AGENT_SERVICE}.callback)
make_with_callback (a_callback: PROCEDURE [ANY, TUPLE [req: WGI_REQUEST; res: WGI_RESPONSE]])
-- Initialize `Current'.
do
make_custom_with_callback (a_callback, Void)
end
make_custom_with_callback (a_callback: like {WGI_AGENT_SERVICE}.callback; a_base_url: detachable STRING)
make_custom_with_callback (a_callback: PROCEDURE [ANY, TUPLE [req: WGI_REQUEST; res: WGI_RESPONSE]]; a_base_url: detachable STRING)
-- Initialize `Current'.
require
base_url_starts_with_slash: (a_base_url /= Void and then not a_base_url.is_empty) implies a_base_url.starts_with ("/")
@@ -104,7 +104,7 @@ feature -- Server
end
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -69,16 +69,18 @@ feature -- Request processing
vn: STRING
e: EXECUTION_ENVIRONMENT
enc: URL_ENCODER
do
l_request_uri := a_handler.uri
l_headers_map := a_handler.request_header_map
create e
if attached e.starting_environment_variables as vars then
if attached e.starting_environment as vars then
create enc
create env.make_equal (vars.count)
across
vars as c
loop
env.force (c.item.to_string_8, c.key)
env.force (enc.encoded_string (c.item), enc.encoded_string (c.key))
end
else
create env.make (0)

View File

@@ -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="ewsgi" uuid="D924DBE1-1231-434A-80EF-234BA09D1E30" library_target="ewsgi">
<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="ewsgi" uuid="D924DBE1-1231-434A-80EF-234BA09D1E30" library_target="ewsgi">
<target name="ewsgi">
<root all_classes="true"/>
<file_rule>

View File

@@ -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="ewsgi_spec" uuid="AA193B9F-02FD-47B9-B60D-C42B9AB35E1C" library_target="ewsgi_spec">
<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="ewsgi_spec" uuid="AA193B9F-02FD-47B9-B60D-C42B9AB35E1C" library_target="ewsgi_spec">
<target name="ewsgi_spec">
<root all_classes="true"/>
<file_rule>

View File

@@ -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="hello_world" uuid="734385F1-0D17-4B5F-9138-24DC8D4F06C6" library_target="hello_world">
<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="hello_world" uuid="734385F1-0D17-4B5F-9138-24DC8D4F06C6" library_target="hello_world">
<target name="hello_world">
<root class="HELLO_WORLD" feature="make"/>
<file_rule>

View File

@@ -20,8 +20,9 @@ feature {NONE} -- Initialization
res.set_post_commit_action (agent commit)
end
wgi_response: WGI_RESPONSE
feature -- Access
wgi_response: WGI_RESPONSE
feature {WGI_FILTER_RESPONSE} -- Change

View File

@@ -9,6 +9,9 @@ class
inherit
WGI_INPUT_STREAM
redefine
last_character_available
end
create
make
@@ -36,11 +39,17 @@ feature -- Input
index := index + 1
if index > chunk_upper then
read_chunk_block
if last_chunk_data = Void then
if
last_chunk_size = 0
then
read_trailer_and_crlf
last_character := '%U'
else
last_character := last_chunk_data.item (index)
end
else
last_character := last_chunk_data.item (index)
end
last_character := last_chunk_data.item (index)
end
read_string (nb: INTEGER)
@@ -54,7 +63,7 @@ feature -- Input
i: like index
do
last_string.wipe_out
if last_trailer /= Void then
if is_trailer_reached then
-- trailer already reached, no more data
check input.end_of_input end
else
@@ -103,6 +112,12 @@ feature -- Access
last_character: CHARACTER_8
-- Last item read.
last_character_available: BOOLEAN
-- <Precursor>
do
Result := not is_trailer_reached
end
feature -- Access: chunk
last_chunk_size: INTEGER
@@ -142,7 +157,13 @@ feature -- Status report
end_of_input: BOOLEAN
-- Has the end of input stream been reached?
do
Result := input.end_of_input
Result := input.end_of_input or is_trailer_reached
end
is_trailer_reached: BOOLEAN
-- Trailer reached?
do
Result := last_trailer /= Void
end
feature {NONE} -- Parser
@@ -320,11 +341,7 @@ feature {NONE} -- Parser
check l_input.last_character = '%N' end
end
end
if s.is_empty then
last_trailer := Void
else
last_trailer := s
end
last_trailer := s
end
feature {NONE} -- Implementation
@@ -333,7 +350,7 @@ feature {NONE} -- Implementation
-- Input Stream
;note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -62,14 +62,19 @@ feature -- Input
i > end_pos
loop
read_character
a_string.put (last_character, i)
if end_of_input then
Result := i
if last_character_available then
a_string.put (last_character, i)
if end_of_input then
Result := i
-- Jump out of the loop.
i := end_pos + 1
else
i := i + 1
end
else
-- reached end of input
-- Jump out of the loop.
i := end_pos + 1
else
i := i + 1
end
end
if not end_of_input then
@@ -107,13 +112,20 @@ feature -- Input
i > end_pos
loop
read_character
a_string.extend (last_character)
l_count := l_count + 1
if end_of_input then
if last_character_available then
a_string.extend (last_character)
l_count := l_count + 1
if end_of_input then
-- Jump out of the loop.
i := end_pos + 1
else
i := i + 1
end
else
-- reached end of input
-- Jump out of the loop.
i := end_pos + 1
else
i := i + 1
end
end
last_appended_count := l_count
@@ -194,6 +206,15 @@ feature -- Access
deferred
end
last_character_available: BOOLEAN
-- Is `last_character' available? i.e read?
--| with chunked encoding, we may reach the end and the `last_character'
--| should not be used.
--| to redefine in descendant if needed
do
Result := True
end
last_appended_count: INTEGER
-- Count of characters actually read by last `append_to_string' call.

View File

@@ -0,0 +1,3 @@
all::
build_win64.bat

View File

@@ -16,3 +16,4 @@ link.exe %LINK_FLAGS% /DLL %E_libFCGI_OUTDIR%\fcgi_stdio.obj %E_libFCGI_OUTDIR%
copy %E_libFCGI_OUTDIR%\libfcgi.* %~dp0..\spec\lib\windows\msc
endlocal
exit 0

View File

@@ -16,3 +16,4 @@ link.exe %LINK_FLAGS% /DLL %E_libFCGI_OUTDIR%\fcgi_stdio.obj %E_libFCGI_OUTDIR%
copy %E_libFCGI_OUTDIR%\libfcgi.* %~dp0..\spec\lib\win64\msc
endlocal
exit 0

View File

@@ -0,0 +1,20 @@
setlocal
echo off
if "%ISE_PLATFORM%" == "win64" goto build_win64
goto build_win32
goto end
:build_win64
echo Building libfcgi for win64
%~dp0\build_win64.bat
goto end
:build_win32
echo Building libfcgi for win32
%~dp0\build_win32.bat
goto end
:end
endlocal
exit 0

View File

@@ -68,10 +68,28 @@ feature {FCGI_IMP} -- Internal
feof (v: POINTER): INTEGER
-- FCGI_feof()
-- 0 means EOF not detected.
external
"C inline use %"fcgi_stdio.h%""
alias
"FCGI_feof"
"return FCGI_feof($v);"
end
ferror (v: POINTER): INTEGER
-- FCGI_ferror()
-- 0 means no error.
external
"C inline use %"fcgi_stdio.h%""
alias
"return FCGI_ferror($v);"
end
clearerr (v: POINTER)
-- FCGI_clearerr().
external
"C inline use %"fcgi_stdio.h%""
alias
"FCGI_clearerr($v)"
end
feature {NONE} -- Input
@@ -108,27 +126,27 @@ feature -- Error
feature -- Access
stdout: POINTER
-- FCGI_stdout() return pointer on output FCGI_FILE
-- FCGI_stdout return pointer on output FCGI_FILE
external
"C inline use %"fcgi_stdio.h%""
alias
"FCGI_stdout"
"return FCGI_stdout;"
end
stdin: POINTER
-- FCGI_stdin() return pointer on input FCGI_FILE
-- FCGI_stdin return pointer on input FCGI_FILE
external
"C inline use %"fcgi_stdio.h%""
alias
"FCGI_stdin"
"return FCGI_stdin;"
end
stderr: POINTER
-- FCGI_stderr() return pointer on error FCGI_FILE
-- FCGI_stderr return pointer on error FCGI_FILE
external
"C inline use %"fcgi_stdio.h%""
alias
"FCGI_stderr"
"return FCGI_stderr;"
end
note

View File

@@ -32,7 +32,12 @@ feature -- Access
fcgi_end_of_input: BOOLEAN
do
Result := fcgi.feof (fcgi.stdin) = 0
Result := fcgi.feof (fcgi.stdin) /= 0 --| in fact, True if feof (..) = EOF
end
fcgi_clearerr
do
fcgi.clearerr (fcgi.stdin)
end
feature -- FCGI Connection
@@ -52,7 +57,7 @@ feature -- FCGI Connection
eif_environ = (char**) environ;
]"
end
fcgi_finish
-- Finish current request from HTTP server started from
-- the most recent call to `fcgi_accept'.
@@ -175,7 +180,7 @@ feature -- I/O Routines
--RFO end
note
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"
copyright: "Copyright (c) 1984-2013, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -68,10 +68,28 @@ feature {FCGI_IMP} -- Internal
feof (v: POINTER): INTEGER
-- FCGI_feof()
-- 0 means EOF not detected.
external
"C inline use %"fcgi_stdio.h%""
alias
"FCGI_feof"
"return FCGI_feof($v);"
end
ferror (v: POINTER): INTEGER
-- FCGI_ferror()
-- 0 means no error.
external
"C inline use %"fcgi_stdio.h%""
alias
"return FCGI_ferror($v);"
end
clearerr (v: POINTER)
-- FCGI_clearerr().
external
"C inline use %"fcgi_stdio.h%""
alias
"FCGI_clearerr($v)"
end
feature {NONE} -- Input
@@ -108,27 +126,27 @@ feature -- Error
feature -- Access
stdout: POINTER
-- FCGI_stdout() return pointer on output FCGI_FILE
-- FCGI_stdout return pointer on output FCGI_FILE
external
"C inline use %"fcgi_stdio.h%""
alias
"FCGI_stdout"
"return FCGI_stdout;"
end
stdin: POINTER
-- FCGI_stdin() return pointer on input FCGI_FILE
-- FCGI_stdin return pointer on input FCGI_FILE
external
"C inline use %"fcgi_stdio.h%""
alias
"FCGI_stdin"
"return FCGI_stdin;"
end
stderr: POINTER
-- FCGI_stderr() return pointer on error FCGI_FILE
-- FCGI_stderr return pointer on error FCGI_FILE
external
"C inline use %"fcgi_stdio.h%""
alias
"FCGI_stderr"
"return FCGI_stderr;"
end
note

View File

@@ -32,7 +32,12 @@ feature -- Access
fcgi_end_of_input: BOOLEAN
do
Result := fcgi.feof (fcgi.stdin) = 0
Result := fcgi.feof (fcgi.stdin) /= 0 --| in fact, True if feof (..) = EOF
end
fcgi_clearerr
do
fcgi.clearerr (fcgi.stdin)
end
feature -- FCGI Connection

View File

@@ -65,12 +65,30 @@ feature {FCGI_IMP} -- Internal
feof (v: POINTER): INTEGER
-- FCGI_feof()
-- 0 means EOF not detected.
external
"dll libfcgi.dll signature (EIF_POINTER): EIF_INTEGER use fcgi_stdio.h "
alias
"FCGI_feof"
end
ferror (v: POINTER): INTEGER
-- FCGI_ferror()
-- 0 means no error.
external
"dll libfcgi.dll signature (EIF_POINTER): EIF_INTEGER use fcgi_stdio.h "
alias
"FCGI_ferror"
end
clearerr (v: POINTER)
-- FCGI_clearerr().
external
"dll libfcgi.dll signature (EIF_POINTER) use fcgi_stdio.h "
alias
"FCGI_clearerr"
end
feature {NONE} -- Input
fread (v: POINTER; a_size: INTEGER; n: INTEGER; fp: POINTER): INTEGER
@@ -123,29 +141,28 @@ feature {NONE} -- Output
feature -- Access
stdout: POINTER
-- FCGI_stdout() return pointer on output FCGI_FILE
-- FCGI_stdout return pointer on output FCGI_FILE
external
"C inline use %"fcgi_stdio.h%""
alias
"FCGI_stdout"
"return FCGI_stdout;"
end
stdin: POINTER
-- FCGI_stdin() return pointer on input FCGI_FILE
-- FCGI_stdin return pointer on input FCGI_FILE
external
"C inline use %"fcgi_stdio.h%""
alias
"FCGI_stdin"
"return FCGI_stdin;"
end
stderr: POINTER
-- FCGI_stderr() return pointer on error FCGI_FILE
-- FCGI_stderr return pointer on error FCGI_FILE
external
"C inline use %"fcgi_stdio.h%""
alias
"FCGI_stderr"
"return FCGI_stderr;"
end
note
copyright: "Copyright (c) 1984-2011, Eiffel Software and others"

View File

@@ -30,7 +30,12 @@ feature -- Access
fcgi_end_of_input: BOOLEAN
do
Result := fcgi.feof (fcgi.stdin) = 0
Result := fcgi.feof (fcgi.stdin) /= 0 --| in fact, True if feof (..) = EOF
end
fcgi_clearerr
do
fcgi.clearerr (fcgi.stdin)
end
-- updated_environ_variables: HASH_TABLE [STRING, STRING]

View File

@@ -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="libfcgi" uuid="3F4BCF74-3503-4533-9D74-5A65EC4CA3C4" library_target="libfcgi">
<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="libfcgi" uuid="3F4BCF74-3503-4533-9D74-5A65EC4CA3C4" library_target="libfcgi">
<target name="libfcgi">
<root all_classes="true"/>
<file_rule>
@@ -46,16 +46,16 @@
</file_rule>
<file_rule>
<exclude>/fake$</exclude>
<exclude>/windows$</exclude>
<exclude>/mac$</exclude>
<exclude>/windows$</exclude>
<condition>
<platform value="unix"/>
</condition>
</file_rule>
<file_rule>
<exclude>/linux$</exclude>
<exclude>/fake$</exclude>
<exclude>/windows$</exclude>
<exclude>/linux$</exclude>
<condition>
<platform value="macintosh"/>
</condition>

View File

@@ -55,16 +55,14 @@ feature -- Access
Result := "</body>%N</html>%N"
end
print_environment_variables (vars: HASH_TABLE [STRING, STRING])
print_environment_variables (vars: TABLE_ITERABLE [READABLE_STRING_8, READABLE_STRING_GENERAL])
local
utf: UTF_CONVERTER
do
from
vars.start
until
vars.after
across
vars as ic
loop
fcgi.put_string ("<li><strong>" + vars.key_for_iteration + "</strong> = " + vars.item_for_iteration + "</li>%N")
vars.forth
fcgi.put_string ("<li><strong>" + utf.utf_32_string_to_utf_8_string_8 (ic.key.as_string_8) + "</strong> = " + ic.item + "</li>%N")
end
end

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View 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

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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$"

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>")

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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

View 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

View 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'été 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'été 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'été 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

View File

@@ -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

View File

@@ -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

View File

@@ -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"/>

View File

@@ -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"/>

View File

@@ -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"

View File

@@ -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"/>

View File

@@ -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"/>

Some files were not shown because too many files have changed in this diff Show More