Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c83b9d4231 | ||
|
|
69b5ce637e | ||
|
|
485a3812d9 | ||
|
|
88dec34a1e | ||
|
|
a928f27b1a | ||
|
|
7ba678d726 | ||
|
|
2371ad4bd1 | ||
|
|
146b78e5b0 | ||
|
|
273a55d93c | ||
|
|
2e920f063a | ||
|
|
3b8261ff08 | ||
|
|
a530bbebb4 | ||
|
|
d41dbb9f47 | ||
|
|
a57e041003 | ||
|
|
5d9752f257 | ||
|
|
d4d988e532 | ||
|
|
ce11a3c0fc | ||
|
|
4eb743fa58 |
0
.travis.yml
Normal file
0
.travis.yml
Normal file
6097
CHANGELOG.md
Normal file
6097
CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load Diff
23
README.md
23
README.md
@@ -41,10 +41,10 @@ Tasks and issues are managed with github issue system
|
||||
* Forum/group post: https://groups.google.com/forum/#!forum/eiffel-web-framework
|
||||
|
||||
## Requirements
|
||||
* Compiling from EiffelStudio 13.11 to 15.05 and more recent version of the compiler.
|
||||
* Currently being developped using EiffelStudio 15.01 (on Windows, Linux)
|
||||
* Tested using EiffelStudio 15.01 with "jenkins" CI server (not anymore compatible with 6.8 due to use of `TABLE_ITERABLE')
|
||||
* The code have to allow __void-safe__ compilation and non void-safe system (see [more about void-safety](http://docs.eiffel.com/book/method/void-safe-programming-eiffel) )
|
||||
* Compiling from EiffelStudio 16.05 to 17.05 and more recent version of the compiler.
|
||||
* Currently being developped using EiffelStudio 17.01 (on Windows, Linux)
|
||||
* Tested using EiffelStudio 17.01 with "jenkins" CI server.
|
||||
* The code have to allow __void-safe__ compilation and non void-safe system (see [more about void-safety](https://www.eiffel.org/doc/eiffel/Void-safe%20programming%20in%20Eiffel)
|
||||
|
||||
## How to get the source code?
|
||||
|
||||
@@ -65,12 +65,12 @@ Using git
|
||||
* __router__: URL dispatching/routing based on uri, uri_template, or custom [read more](library/server/wsf/router)
|
||||
|
||||
### protocol
|
||||
* __http__: HTTP related classes, constants for status code, content types, ... [read more](library/protocol/http)
|
||||
* __uri_template__: URI Template library (parsing and expander) [read more](library/protocol/uri_template)
|
||||
* __CONNEG__: Content negotiation library (Content-type Negociation) [read more](library/protocol/content_negotiation)
|
||||
* __http__: HTTP related classes, constants for status code, content types, ... [read more](library/network/protocol/http)
|
||||
* __uri_template__: URI Template library (parsing and expander) [read more](library/network/protocol/uri_template)
|
||||
* __CONNEG__: Content negotiation library (Content-type Negociation) [read more](library/network/protocol/content_negotiation)
|
||||
|
||||
### client
|
||||
* __http_client__: simple HTTP client based on cURL [read more](library/client/http_client)
|
||||
* __http_client__: simple HTTP client based on cURL [read more](library/network/http_client)
|
||||
|
||||
### text
|
||||
* __encoder__: Various simpler encoders: base64, url-encoder, xml entities, html entities [read more](library/text/encoder)
|
||||
@@ -78,10 +78,6 @@ Using git
|
||||
### Others
|
||||
* error: very simple/basic library to handle error
|
||||
|
||||
## External libraries under 'contrib'
|
||||
* [Eiffel Web Nino](contrib/library/server/nino)
|
||||
* ..
|
||||
|
||||
## Draft folder = call for contribution ##
|
||||
|
||||
## Examples
|
||||
@@ -106,5 +102,4 @@ Keep track of development and community news.
|
||||
* Have a question that's not a feature request or bug report? [Ask on the mailing list](http://groups.google.com/group/eiffel-web-framework)
|
||||
|
||||
|
||||
For more information please have a look at the related wiki:
|
||||
* https://github.com/EiffelWebFramework/EWF/wiki
|
||||
For more information please have a look at the related [workbook documentation](docs/workbook)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="filter" uuid="52FF4B77-0614-4D8B-9B96-C07EC852793E">
|
||||
<target name="common">
|
||||
<target name="common" abstract="true">
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
|
||||
@@ -205,7 +205,7 @@ feature {NONE} -- Implementation
|
||||
loop
|
||||
s.append (" - ")
|
||||
s.append (c.item.url_encoded_name)
|
||||
t := c.item.generating_type
|
||||
t := c.item.generating_type.name
|
||||
if t.same_string ("WSF_STRING") then
|
||||
else
|
||||
s.append_character (' ')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="filter" uuid="52FF4B77-0614-4D8B-9B96-C07EC852793E">
|
||||
<target name="common">
|
||||
<target name="common" abstract="true">
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
|
||||
@@ -84,7 +84,7 @@ feature {NONE} -- Initialization
|
||||
create l_methods
|
||||
l_methods.enable_options
|
||||
l_methods.enable_get
|
||||
router.handle_with_request_methods ("/user/{userid}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent l_options_filter.execute), l_methods)
|
||||
router.handle ("/user/{userid}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent l_options_filter.execute), l_methods)
|
||||
end
|
||||
|
||||
initialize_json
|
||||
@@ -99,7 +99,7 @@ feature {NONE} -- Implementation
|
||||
-- Port number
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Olivier Ligot, Jocelyn Fiat and others"
|
||||
copyright: "2011-2017, Olivier Ligot, Jocelyn Fiat and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -42,7 +42,7 @@ feature -- Basic operations
|
||||
id : STRING
|
||||
do
|
||||
if attached req.orig_path_info as orig_path then
|
||||
id := get_user_id_from_path (orig_path)
|
||||
id := get_user_id_from_path (orig_path.as_string_32)
|
||||
if attached retrieve_user (id) as l_user then
|
||||
if l_user ~ req.execution_variable ("user") then
|
||||
compute_response_get (req, res, l_user)
|
||||
@@ -92,6 +92,6 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Olivier Ligot, Jocelyn Fiat and others"
|
||||
copyright: "2011-2017, Olivier Ligot, Jocelyn Fiat and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="restbucks" uuid="2773FEAA-448F-410E-BEDE-9298C4749066">
|
||||
<target name="restbucks_common">
|
||||
<target name="restbucks_common" abstract="true">
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
|
||||
@@ -85,7 +85,6 @@ feature {NONE} -- Initialization
|
||||
create_order (sess: HTTP_CLIENT_SESSION) : HTTP_CLIENT_RESPONSE
|
||||
local
|
||||
s: READABLE_STRING_8
|
||||
j: JSON_PARSER
|
||||
context : HTTP_CLIENT_REQUEST_CONTEXT
|
||||
do
|
||||
s := "[
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="restbucks" uuid="2773FEAA-448F-410E-BEDE-9298C4749066">
|
||||
<target name="restbucks_common">
|
||||
<target name="restbucks_common" abstract="true">
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
|
||||
@@ -87,7 +87,7 @@ feature -- Access: order status
|
||||
end
|
||||
|
||||
Order_states : ARRAY [STRING]
|
||||
-- List of valid status states
|
||||
-- List of valid status states.
|
||||
once
|
||||
Result := <<
|
||||
status_unset,
|
||||
|
||||
@@ -27,7 +27,7 @@ feature -- Access
|
||||
end
|
||||
|
||||
Milk_types: ARRAY [STRING]
|
||||
-- List of valid Milk types
|
||||
-- List of valid Milk types.
|
||||
once
|
||||
Result := <<"skim", "semi", "whole">>
|
||||
end
|
||||
|
||||
@@ -4,7 +4,8 @@ note
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class ORDER_HANDLER
|
||||
class
|
||||
ORDER_HANDLER
|
||||
|
||||
inherit
|
||||
|
||||
@@ -537,7 +538,6 @@ feature {NONE} -- Conversion
|
||||
|
||||
order_to_json (obj: ORDER): JSON_OBJECT
|
||||
local
|
||||
j_order: JSON_OBJECT
|
||||
j_item: JSON_OBJECT
|
||||
ja: JSON_ARRAY
|
||||
do
|
||||
|
||||
@@ -334,7 +334,6 @@ feature {NONE} -- Conversion
|
||||
|
||||
order_to_json (obj: ORDER): JSON_OBJECT
|
||||
local
|
||||
j_order: JSON_OBJECT
|
||||
j_item: JSON_OBJECT
|
||||
ja: JSON_ARRAY
|
||||
do
|
||||
|
||||
@@ -12,8 +12,6 @@ inherit
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_location: PATH)
|
||||
local
|
||||
d: DIRECTORY
|
||||
do
|
||||
location := a_location
|
||||
ensure_directory_exists (a_location)
|
||||
@@ -67,7 +65,6 @@ feature -- Access
|
||||
|
||||
save (a_entry_type: TYPE [detachable ANY]; a_entry: detachable ANY; cl_entry_id: CELL [detachable READABLE_STRING_GENERAL])
|
||||
local
|
||||
f: RAW_FILE
|
||||
l_id: detachable READABLE_STRING_GENERAL
|
||||
p: PATH
|
||||
do
|
||||
|
||||
@@ -19,8 +19,6 @@ create
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
local
|
||||
b: SED_MEMORY_READER_WRITER
|
||||
do
|
||||
create collections.make (0)
|
||||
end
|
||||
@@ -86,8 +84,6 @@ feature {NONE} -- Implementation
|
||||
next_identifier (a_entry_type: TYPE [detachable ANY]): STRING_8
|
||||
local
|
||||
i: INTEGER
|
||||
f: RAW_FILE
|
||||
s: STRING
|
||||
tb: detachable STRING_TABLE [detachable ANY]
|
||||
do
|
||||
tb := collections.item (a_entry_type)
|
||||
|
||||
@@ -54,7 +54,7 @@ feature -- Execution
|
||||
if attached {WSF_STRING} req.item ("user") as u then
|
||||
--| If yes, say hello world #name
|
||||
|
||||
l_user_name := (create {HTML_ENCODER}).decoded_string (u.value)
|
||||
l_user_name := (create {HTML_ENCODER}).general_decoded_string (u.value)
|
||||
|
||||
s := "<p>Hello " + mesg.html_encoded_string (l_user_name) + "!</p>"
|
||||
s.append ("Display a <a href=%"/users/" + u.url_encoded_value + "/message/%">message</a></p>")
|
||||
|
||||
@@ -86,7 +86,7 @@ feature -- Access
|
||||
html_decoded_string (v: READABLE_STRING_32): READABLE_STRING_32
|
||||
do
|
||||
if v.is_valid_as_string_8 then
|
||||
Result := (create {HTML_ENCODER}).decoded_string (v)
|
||||
Result := (create {HTML_ENCODER}).general_decoded_string (v)
|
||||
else
|
||||
Result := v
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="upload_image" uuid="F2400BE8-D8EB-48EB-B4E4-5D4377062A7F">
|
||||
<target name="upload_image_common">
|
||||
<target name="upload_image_common" abstract="true">
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
</library>
|
||||
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri-safe.ecf"/>
|
||||
<cluster name="src" location=".\src\">
|
||||
<cluster name="implementation" location="$|implementation" recursive="true" hidden="true"/>
|
||||
<cluster name="spec_null" location="$|spec\null\" recursive="true"/>
|
||||
<cluster name="spec_net" location="$|spec\net\">
|
||||
<condition>
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
</library>
|
||||
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri.ecf"/>
|
||||
<cluster name="src" location=".\src\">
|
||||
<cluster name="implementation" location="$|implementation" recursive="true" hidden="true"/>
|
||||
<cluster name="spec_null" location="$|spec\null\" recursive="true"/>
|
||||
<cluster name="spec_net" location="$|spec\net\">
|
||||
<condition>
|
||||
|
||||
@@ -196,73 +196,8 @@ feature -- Settings
|
||||
Result := session.is_insecure
|
||||
end
|
||||
|
||||
feature {NONE} -- Utilities
|
||||
|
||||
append_parameters_to_url (a_parameters: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_32]; a_url: STRING)
|
||||
-- Append parameters `a_parameters' to `a_url'
|
||||
require
|
||||
a_url_attached: a_url /= Void
|
||||
local
|
||||
l_first_param: BOOLEAN
|
||||
do
|
||||
if a_parameters.count > 0 then
|
||||
if a_url.index_of ('?', 1) > 0 then
|
||||
l_first_param := False
|
||||
elseif a_url.index_of ('&', 1) > 0 then
|
||||
l_first_param := False
|
||||
else
|
||||
l_first_param := True
|
||||
end
|
||||
|
||||
from
|
||||
a_parameters.start
|
||||
until
|
||||
a_parameters.after
|
||||
loop
|
||||
if l_first_param then
|
||||
a_url.append_character ('?')
|
||||
else
|
||||
a_url.append_character ('&')
|
||||
end
|
||||
a_url.append (urlencode (a_parameters.key_for_iteration))
|
||||
a_url.append_character ('=')
|
||||
a_url.append (urlencode (a_parameters.item_for_iteration))
|
||||
l_first_param := False
|
||||
a_parameters.forth
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Utilities: encoding
|
||||
|
||||
url_encoder: URL_ENCODER
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
urlencode (s: READABLE_STRING_32): READABLE_STRING_8
|
||||
-- URL encode `s'
|
||||
do
|
||||
Result := url_encoder.encoded_string (s)
|
||||
end
|
||||
|
||||
urldecode (s: READABLE_STRING_8): READABLE_STRING_32
|
||||
-- URL decode `s'
|
||||
do
|
||||
Result := url_encoder.decoded_string (s)
|
||||
end
|
||||
|
||||
stripslashes (s: STRING): STRING
|
||||
do
|
||||
Result := s.string
|
||||
Result.replace_substring_all ("\%"", "%"")
|
||||
Result.replace_substring_all ("\'", "'")
|
||||
Result.replace_substring_all ("\/", "/")
|
||||
Result.replace_substring_all ("\\", "\")
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -13,7 +13,7 @@ note
|
||||
Note that any value set in this context class overrides conflicting value eventually
|
||||
set in associated HTTP_CLIENT_SESSION.
|
||||
|
||||
Warning: for now [2012-May], you can have only one of the following data
|
||||
Warning: for now [2012-05-31], you can have only one of the following data
|
||||
- form_parameters
|
||||
- or upload_data
|
||||
- or upload_filename
|
||||
@@ -142,16 +142,16 @@ feature -- Element change
|
||||
end
|
||||
end
|
||||
|
||||
add_query_parameter (k: READABLE_STRING_32; v: READABLE_STRING_32)
|
||||
add_query_parameter (k: READABLE_STRING_GENERAL; v: READABLE_STRING_GENERAL)
|
||||
-- Add a query parameter `k=v'.
|
||||
do
|
||||
query_parameters.force (v, k)
|
||||
query_parameters.force (v.to_string_32, k.to_string_32)
|
||||
end
|
||||
|
||||
add_form_parameter (k: READABLE_STRING_32; v: READABLE_STRING_32)
|
||||
add_form_parameter (k: READABLE_STRING_GENERAL; v: READABLE_STRING_GENERAL)
|
||||
-- Add a form parameter `k'= `v'.
|
||||
do
|
||||
form_parameters.force (v, k)
|
||||
form_parameters.force (v.to_string_32, k.to_string_32)
|
||||
end
|
||||
|
||||
set_credentials_required (b: BOOLEAN)
|
||||
@@ -236,18 +236,62 @@ feature -- Status setting
|
||||
end
|
||||
end
|
||||
|
||||
feature -- URL helpers
|
||||
|
||||
append_query_parameters_to_url (a_url: STRING)
|
||||
-- Append parameters `a_parameters' to `a_url'
|
||||
require
|
||||
a_url_attached: a_url /= Void
|
||||
local
|
||||
l_first_param: BOOLEAN
|
||||
do
|
||||
if
|
||||
attached query_parameters as l_query_parameters and then
|
||||
not l_query_parameters.is_empty
|
||||
then
|
||||
if a_url.index_of ('?', 1) > 0 then
|
||||
l_first_param := False
|
||||
elseif a_url.index_of ('&', 1) > 0 then
|
||||
l_first_param := False
|
||||
else
|
||||
l_first_param := True
|
||||
end
|
||||
|
||||
across
|
||||
query_parameters as ic
|
||||
loop
|
||||
if l_first_param then
|
||||
a_url.append_character ('?')
|
||||
else
|
||||
a_url.append_character ('&')
|
||||
end
|
||||
l_first_param := False
|
||||
uri_percent_encoder.append_query_name_encoded_string_to (ic.key, a_url)
|
||||
a_url.append_character ('=')
|
||||
uri_percent_encoder.append_query_value_encoded_string_to (ic.item, a_url)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Conversion helpers
|
||||
|
||||
query_parameters_to_url_encoded_string: STRING_8
|
||||
-- `query_parameters' as url-encoded string.
|
||||
do
|
||||
Result := parameters_to_url_encoded_string (query_parameters)
|
||||
Result := parameters_to_uri_percent_encoded_string (query_parameters)
|
||||
end
|
||||
|
||||
form_parameters_to_x_www_form_url_encoded_string: STRING_8
|
||||
-- `form_parameters' as x-www-form-urlencoded string.
|
||||
do
|
||||
Result := parameters_to_x_www_form_urlencoded_string (form_parameters)
|
||||
end
|
||||
|
||||
form_parameters_to_url_encoded_string: STRING_8
|
||||
-- `form_parameters' as url-encoded string.
|
||||
obsolete "Use form_parameters_to_x_www_form_url_encoded_string [2017-05-31]"
|
||||
do
|
||||
Result := parameters_to_url_encoded_string (form_parameters)
|
||||
Result := form_parameters_to_x_www_form_url_encoded_string
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
@@ -271,6 +315,52 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
end
|
||||
|
||||
parameters_to_uri_percent_encoded_string (ht: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_32]): STRING_8
|
||||
-- Build query urlencoded string using parameters from `ht'.
|
||||
do
|
||||
create Result.make (64)
|
||||
across
|
||||
ht as ic
|
||||
loop
|
||||
if not Result.is_empty then
|
||||
Result.append_character ('&')
|
||||
end
|
||||
uri_percent_encoder.append_query_name_encoded_string_to (ic.key, Result)
|
||||
Result.append_character ('=')
|
||||
uri_percent_encoder.append_query_value_encoded_string_to (ic.item, Result)
|
||||
end
|
||||
end
|
||||
|
||||
parameters_to_x_www_form_urlencoded_string (ht: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_32]): STRING_8
|
||||
-- Build x-www-form-urlencoded string using parameters from `ht'.
|
||||
do
|
||||
create Result.make (64)
|
||||
from
|
||||
ht.start
|
||||
until
|
||||
ht.after
|
||||
loop
|
||||
if not Result.is_empty then
|
||||
Result.append_character ('&')
|
||||
end
|
||||
Result.append (x_www_form_url_encoder.encoded_string (ht.key_for_iteration))
|
||||
Result.append_character ('=')
|
||||
Result.append (x_www_form_url_encoder.encoded_string (ht.item_for_iteration))
|
||||
ht.forth
|
||||
end
|
||||
end
|
||||
|
||||
x_www_form_url_encoder: X_WWW_FORM_URL_ENCODER
|
||||
-- Shared x-www-form-urlencoded encoder.
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
uri_percent_encoder: URI_PERCENT_ENCODER
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
url_encoder: URL_ENCODER
|
||||
-- Shared URL encoder.
|
||||
once
|
||||
@@ -278,7 +368,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -60,28 +60,10 @@ feature -- Access
|
||||
|
||||
url (a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): STRING_8
|
||||
-- Url computed from Current and `ctx' data.
|
||||
local
|
||||
s: STRING_8
|
||||
url_encoder: URL_ENCODER
|
||||
do
|
||||
Result := base_url + a_path
|
||||
if ctx /= Void then
|
||||
create s.make_empty
|
||||
create url_encoder
|
||||
across
|
||||
ctx.query_parameters as q
|
||||
loop
|
||||
if not s.is_empty then
|
||||
s.append_character ('&')
|
||||
end
|
||||
s.append (url_encoder.encoded_string (q.key))
|
||||
s.append_character ('=')
|
||||
s.append (url_encoder.encoded_string (q.item))
|
||||
end
|
||||
if not s.is_empty then
|
||||
Result.append_character ('?')
|
||||
Result.append (s)
|
||||
end
|
||||
ctx.append_query_parameters_to_url (Result)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -420,7 +402,7 @@ feature -- Element change
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -0,0 +1,628 @@
|
||||
note
|
||||
description: "[
|
||||
Component to handle percent encoding
|
||||
|
||||
WARNING: THIS IS A COPY FROM $ISE_LIBRARY/library/text/uri library.
|
||||
In the future, http_client will use directly the `uri` library.
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
EIS: "name=Percent-encoding", "protocol=URI", "src=http://en.wikipedia.org/wiki/Percent-encoding"
|
||||
|
||||
class
|
||||
URI_PERCENT_ENCODER
|
||||
|
||||
feature -- Percent encoding
|
||||
|
||||
append_percent_encoded_string_to (s: READABLE_STRING_GENERAL; a_result: STRING_GENERAL)
|
||||
-- Append `s' as percent-encoded value to `a_result'
|
||||
local
|
||||
i,n: INTEGER
|
||||
do
|
||||
from
|
||||
i := 1
|
||||
n := s.count
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
append_encoded_character_code_to (s.code (i), a_result)
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
append_query_name_encoded_string_to (s: READABLE_STRING_GENERAL; a_result: STRING_GENERAL)
|
||||
-- Append `s' as encoded for URI query name to `a_result'
|
||||
local
|
||||
i,n: INTEGER
|
||||
do
|
||||
from
|
||||
i := 1
|
||||
n := s.count
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
append_query_name_encoded_character_code_to (s.code (i), a_result)
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
append_query_value_encoded_string_to (s: READABLE_STRING_GENERAL; a_result: STRING_GENERAL)
|
||||
-- Append `s' as encoded for URI query value to `a_result'.
|
||||
local
|
||||
i,n: INTEGER
|
||||
do
|
||||
from
|
||||
i := 1
|
||||
n := s.count
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
append_query_value_encoded_character_code_to (s.code (i), a_result)
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
append_path_segment_encoded_string_to (s: READABLE_STRING_GENERAL; a_result: STRING_GENERAL)
|
||||
-- Append `a_string' as encoded for URI path segment to `a_result'
|
||||
local
|
||||
i,n: INTEGER
|
||||
do
|
||||
from
|
||||
i := 1
|
||||
n := s.count
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
append_path_segment_encoded_character_code_to (s.code (i), a_result)
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
append_www_form_url_encoded_string_to (s: READABLE_STRING_GENERAL; a_result: STRING_GENERAL)
|
||||
-- Append `a_string' as www-form-urlencoded value to `a_result'.
|
||||
-- The main difference with `append_percent_encoded_string_to` is the encoding of space using '+'.
|
||||
local
|
||||
i,n: INTEGER
|
||||
do
|
||||
from
|
||||
i := 1
|
||||
n := s.count
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
inspect s.code (i)
|
||||
when 32 then -- space: 32 ' '
|
||||
a_result.append_code (43) -- 43 '+'
|
||||
else
|
||||
append_encoded_character_code_to (s.code (i), a_result)
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- URI building helpers
|
||||
|
||||
append_encoded_character_code_to (c: NATURAL_32; a_result: STRING_GENERAL)
|
||||
-- Append character code `c' as query name encoded content into `a_result'.
|
||||
do
|
||||
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
|
||||
end
|
||||
|
||||
append_query_name_encoded_character_code_to (c: NATURAL_32; a_result: STRING_GENERAL)
|
||||
-- Append character code `a_code' as query name encoded content into `a_result'.
|
||||
do
|
||||
inspect c
|
||||
when 61 then -- equal sign: =
|
||||
append_percent_encoded_character_code_to (c, a_result)
|
||||
else
|
||||
append_query_value_encoded_character_code_to (c, a_result)
|
||||
end
|
||||
end
|
||||
|
||||
append_query_value_encoded_character_code_to (c: NATURAL_32; a_result: STRING_GENERAL)
|
||||
-- Append character code `a_code' as query value encoded content into `a_result'.
|
||||
do
|
||||
inspect c
|
||||
when 32 then -- Space
|
||||
a_result.append_code (43) -- 43 '+'
|
||||
when
|
||||
39, -- '
|
||||
58, 64, -- reserved =+ gen-delims: : @
|
||||
33, 36, 40, 41, 42, -- reserved =+ sub-delims: ! $ ( ) *
|
||||
44, 59, 61 -- reserved = sub-delims: , ; =
|
||||
then
|
||||
a_result.append_code (c)
|
||||
when
|
||||
47, -- slash: /
|
||||
63 -- question mark ?
|
||||
then
|
||||
a_result.append_code (c)
|
||||
else
|
||||
append_encoded_character_code_to (c, a_result)
|
||||
end
|
||||
end
|
||||
|
||||
append_path_segment_encoded_character_code_to (c: NATURAL_32; a_result: STRING_GENERAL)
|
||||
-- Append character code `a_code' as query name encoded content into `a_result'.
|
||||
do
|
||||
append_encoded_character_code_to (c, a_result)
|
||||
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
|
||||
|
||||
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
|
||||
-- Keep the percent encoded char for non string 32.
|
||||
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
|
||||
|
||||
note
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, 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
|
||||
@@ -82,9 +82,6 @@ feature -- Execution
|
||||
|
||||
--| URL
|
||||
l_url := url
|
||||
if ctx /= Void then
|
||||
append_parameters_to_url (ctx.query_parameters, l_url)
|
||||
end
|
||||
|
||||
if session.is_header_sent_verbose then
|
||||
io.error.put_string ("> Sending:%N")
|
||||
@@ -171,7 +168,7 @@ feature -- Execution
|
||||
then
|
||||
if l_ct.starts_with ("application/x-www-form-urlencoded") then
|
||||
-- Content-Type is already application/x-www-form-urlencoded
|
||||
l_upload_data := ctx.form_parameters_to_url_encoded_string
|
||||
l_upload_data := ctx.form_parameters_to_x_www_form_url_encoded_string
|
||||
elseif l_ct.starts_with ("multipart/form-data") then
|
||||
l_use_curl_form := True
|
||||
else
|
||||
@@ -179,7 +176,7 @@ feature -- Execution
|
||||
l_use_curl_form := True
|
||||
end
|
||||
else
|
||||
l_upload_data := ctx.form_parameters_to_url_encoded_string
|
||||
l_upload_data := ctx.form_parameters_to_x_www_form_url_encoded_string
|
||||
end
|
||||
else
|
||||
l_use_curl_form := True
|
||||
@@ -199,6 +196,14 @@ feature -- Execution
|
||||
)
|
||||
l_form_data.forth
|
||||
end
|
||||
if l_upload_filename /= Void then
|
||||
curl.formadd_string_string (l_form, l_last,
|
||||
{CURL_FORM_CONSTANTS}.curlform_copyname, "file",
|
||||
{CURL_FORM_CONSTANTS}.curlform_file, l_upload_filename,
|
||||
{CURL_FORM_CONSTANTS}.curlform_end
|
||||
)
|
||||
l_upload_filename := Void
|
||||
end
|
||||
l_last.release_item
|
||||
curl_easy.setopt_form (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_httppost, l_form)
|
||||
end
|
||||
|
||||
@@ -41,7 +41,7 @@ feature -- Custom
|
||||
local
|
||||
req: HTTP_CLIENT_REQUEST
|
||||
do
|
||||
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, a_method, Current, ctx)
|
||||
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (url (a_path, ctx), a_method, Current, ctx)
|
||||
Result := req.response
|
||||
end
|
||||
|
||||
@@ -154,7 +154,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
end
|
||||
|
||||
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, a_method, Current, ctx)
|
||||
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (url (a_path, ctx), a_method, Current, ctx)
|
||||
Result := req.response
|
||||
|
||||
if f /= Void then
|
||||
@@ -176,7 +176,7 @@ feature {LIBCURL_HTTP_CLIENT_REQUEST} -- Curl implementation
|
||||
|
||||
|
||||
;note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -9,7 +9,7 @@ class
|
||||
LIBCURL_UPLOAD_FILE_READ_FUNCTION
|
||||
|
||||
obsolete
|
||||
"Use LIBCURL_CUSTOM_FUNCTION [2013-apr-04]"
|
||||
"Use LIBCURL_CUSTOM_FUNCTION [2017-05-31]"
|
||||
|
||||
inherit
|
||||
LIBCURL_DEFAULT_FUNCTION
|
||||
|
||||
@@ -156,7 +156,7 @@ feature -- Access
|
||||
end
|
||||
|
||||
create l_request_uri.make_from_string (l_uri.path)
|
||||
if attached l_uri.query as l_query then
|
||||
if attached l_uri.query as l_query and then not l_query.is_empty then
|
||||
l_request_uri.append_character ('?')
|
||||
l_request_uri.append (l_query)
|
||||
end
|
||||
@@ -198,7 +198,7 @@ feature -- Access
|
||||
attached headers.item ("Content-Type") as l_ct
|
||||
then
|
||||
if l_ct.starts_with ("application/x-www-form-urlencoded") then
|
||||
l_upload_data := ctx.form_parameters_to_url_encoded_string
|
||||
l_upload_data := ctx.form_parameters_to_x_www_form_url_encoded_string
|
||||
elseif l_ct.starts_with ("multipart/form-data") then
|
||||
-- create form using multipart/form-data encoding
|
||||
l_boundary := new_mime_boundary (l_form_data)
|
||||
@@ -208,12 +208,12 @@ feature -- Access
|
||||
-- not supported !
|
||||
-- Send as form-urlencoded
|
||||
headers.extend ("application/x-www-form-urlencoded", "Content-Type")
|
||||
l_upload_data := ctx.form_parameters_to_url_encoded_string
|
||||
l_upload_data := ctx.form_parameters_to_x_www_form_url_encoded_string
|
||||
end
|
||||
else
|
||||
-- Send as form-urlencoded
|
||||
headers.extend ("application/x-www-form-urlencoded", "Content-Type")
|
||||
l_upload_data := ctx.form_parameters_to_url_encoded_string
|
||||
l_upload_data := ctx.form_parameters_to_x_www_form_url_encoded_string
|
||||
end
|
||||
headers.extend (l_upload_data.count.out, "Content-Length")
|
||||
if l_is_chunked_transfer_encoding then
|
||||
@@ -246,7 +246,7 @@ feature -- Access
|
||||
elseif l_upload_filename /= Void then
|
||||
check ctx.has_upload_filename end
|
||||
create l_upload_file.make_with_name (l_upload_filename)
|
||||
if l_upload_file.exists and then l_upload_file.readable then
|
||||
if l_upload_file.exists and then l_upload_file.is_access_readable then
|
||||
if not l_is_chunked_transfer_encoding then
|
||||
headers.extend (l_upload_file.count.out, "Content-Length")
|
||||
end
|
||||
@@ -495,6 +495,7 @@ feature {NONE} -- Helpers
|
||||
across
|
||||
a_form_parameters as ic
|
||||
loop
|
||||
Result.append ("--")
|
||||
Result.append (a_mime_boundary)
|
||||
Result.append (http_end_of_header_line)
|
||||
Result.append ("Content-Disposition: form-data; name=")
|
||||
@@ -519,7 +520,7 @@ feature {NONE} -- Helpers
|
||||
else
|
||||
l_mime_type := "application/octet-stream"
|
||||
end
|
||||
|
||||
Result.append ("--")
|
||||
Result.append (a_mime_boundary)
|
||||
Result.append (http_end_of_header_line)
|
||||
Result.append ("Content-Disposition: form-data; name=%"")
|
||||
@@ -542,6 +543,7 @@ feature {NONE} -- Helpers
|
||||
end
|
||||
Result.append (http_end_of_header_line)
|
||||
end
|
||||
Result.append ("--")
|
||||
Result.append (a_mime_boundary)
|
||||
Result.append ("--") --| end
|
||||
end
|
||||
@@ -907,7 +909,7 @@ feature {NONE} -- Helpers
|
||||
create ran.set_seed (i) -- FIXME: use a real random seed.
|
||||
ran.start
|
||||
ran.forth
|
||||
n := (20 * ran.real_item).truncated_to_integer
|
||||
n := (10 * ran.real_item).truncated_to_integer
|
||||
create Result.make_filled ('-', 3 + n)
|
||||
s := "_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
from
|
||||
|
||||
@@ -67,7 +67,7 @@ feature -- Custom
|
||||
local
|
||||
req: HTTP_CLIENT_REQUEST
|
||||
do
|
||||
create {NET_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, a_method, Current, ctx)
|
||||
create {NET_HTTP_CLIENT_REQUEST} req.make (url (a_path, ctx), a_method, Current, ctx)
|
||||
Result := req.response
|
||||
end
|
||||
|
||||
@@ -167,12 +167,12 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
end
|
||||
|
||||
create {NET_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, a_method, Current, ctx)
|
||||
create {NET_HTTP_CLIENT_REQUEST} req.make (url (a_path, ctx), a_method, Current, ctx)
|
||||
Result := req.response
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -25,7 +25,7 @@ feature -- Custom
|
||||
|
||||
custom (a_method: READABLE_STRING_8; a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
|
||||
do
|
||||
create Result.make (base_url + a_path)
|
||||
create Result.make (url (a_path, ctx))
|
||||
end
|
||||
|
||||
custom_with_upload_data (a_method: READABLE_STRING_8; a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; data: READABLE_STRING_8): HTTP_CLIENT_RESPONSE
|
||||
@@ -98,7 +98,7 @@ feature -- Status report
|
||||
-- Is interface usable?
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -34,6 +34,11 @@ feature -- Tests
|
||||
test_post_with_form_data
|
||||
end
|
||||
|
||||
libcurl_test_post_with_uncommon_form_data
|
||||
do
|
||||
test_post_with_uncommon_form_data
|
||||
end
|
||||
|
||||
libcurl_test_post_with_file
|
||||
do
|
||||
test_post_with_file
|
||||
|
||||
@@ -34,6 +34,11 @@ feature -- Tests
|
||||
test_post_with_form_data
|
||||
end
|
||||
|
||||
net_test_post_with_uncommon_form_data
|
||||
do
|
||||
test_post_with_uncommon_form_data
|
||||
end
|
||||
|
||||
net_test_post_with_file
|
||||
do
|
||||
test_post_with_file
|
||||
@@ -69,4 +74,9 @@ feature -- Tests
|
||||
test_post_with_file_using_chunked_transfer_encoding
|
||||
end
|
||||
|
||||
net_test_get_with_query_parameters
|
||||
do
|
||||
test_get_with_query_parameters
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
note
|
||||
note
|
||||
description: "[
|
||||
Eiffel tests that can be executed by testing tool.
|
||||
]"
|
||||
@@ -21,7 +21,10 @@ feature -- Initialization
|
||||
on_prepare
|
||||
do
|
||||
Precursor
|
||||
global_requestbin_path := new_requestbin_path
|
||||
global_requestbin_path := "/s0jkhhs0"
|
||||
if global_requestbin_path = Void then
|
||||
global_requestbin_path := new_requestbin_path
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Factory
|
||||
@@ -49,6 +52,9 @@ feature -- Requestbin
|
||||
i := l_content.substring_index ("%"name%":", 1)
|
||||
if i > 0 then
|
||||
j := l_content.index_of (',', i + 1)
|
||||
if j = 0 then
|
||||
j := l_content.index_of ('}', i + 1)
|
||||
end
|
||||
if j > 0 then
|
||||
Result := l_content.substring (i + 7, j - 1)
|
||||
Result.adjust
|
||||
@@ -61,6 +67,7 @@ feature -- Requestbin
|
||||
if not Result.starts_with ("/") then
|
||||
Result.prepend_character ('/')
|
||||
end
|
||||
print ("new_requestbin_path => http://requestb.in" + Result + "?inspect%N")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -108,8 +115,55 @@ feature -- Factory
|
||||
-- check requestbin to ensure the form parameters are correctly received
|
||||
sess := new_session ("http://requestb.in")
|
||||
create l_ctx.make
|
||||
l_ctx.form_parameters.extend ("First Value", "First Key")
|
||||
l_ctx.form_parameters.extend ("Second Value", "Second Key")
|
||||
l_ctx.add_form_parameter ("First Key", "First Value")
|
||||
l_ctx.add_form_parameter ("Second Key", "Second Value")
|
||||
l_ctx.add_form_parameter ("unicode", {STRING_32} "Hello / 你好 !")
|
||||
l_ctx.add_form_parameter ({STRING_32} "Field 你好 !", "How are you?")
|
||||
create h.make_empty
|
||||
if
|
||||
attached sess.post (requestbin_path, l_ctx, "") as res and then
|
||||
attached res.headers as hds
|
||||
then
|
||||
across
|
||||
hds as c
|
||||
loop
|
||||
h.append (c.item.name + ": " + c.item.value + "%R%N")
|
||||
end
|
||||
end
|
||||
print (h)
|
||||
else
|
||||
assert ("Has requestbin path", False)
|
||||
end
|
||||
end
|
||||
|
||||
test_post_with_uncommon_form_data
|
||||
local
|
||||
sess: HTTP_CLIENT_SESSION
|
||||
h: STRING_8
|
||||
l_ctx: HTTP_CLIENT_REQUEST_CONTEXT
|
||||
do
|
||||
if attached global_requestbin_path as requestbin_path then
|
||||
|
||||
-- POST REQUEST WITH FORM DATA
|
||||
-- check requestbin to ensure the form parameters are correctly received
|
||||
sess := new_session ("http://requestb.in")
|
||||
create l_ctx.make
|
||||
|
||||
l_ctx.add_form_parameter ("title", "Eiffel World!") -- space and !
|
||||
l_ctx.add_form_parameter ("path", "foo/bar") -- slash
|
||||
l_ctx.add_form_parameter ("unreserved", ":!@[]{}()*") -- ...
|
||||
l_ctx.add_form_parameter ("reserved", "+=?&_#_") -- ...
|
||||
l_ctx.add_form_parameter ("a=b", "a=b") -- equal sign
|
||||
l_ctx.add_form_parameter ("test", "!$&'()*") --
|
||||
l_ctx.add_form_parameter ("lst[a][b]", "[123][456]") -- brackets
|
||||
l_ctx.add_form_parameter ("pos{1,2}", "loc{a,b}") -- curly brackets
|
||||
l_ctx.add_form_parameter ("?foo", "?bar") -- question mark
|
||||
l_ctx.add_form_parameter ("?", "?") -- question mark
|
||||
l_ctx.add_form_parameter ("&bar", "&bar") -- ampersand
|
||||
l_ctx.add_form_parameter ("&", "&") -- ampersand
|
||||
|
||||
assert ("form data well generated", l_ctx.form_parameters_to_x_www_form_url_encoded_string.same_string ("title=Eiffel+World!&path=foo%%2Fbar&unreserved=%%3A!%%40%%5B%%5D%%7B%%7D()*&reserved=%%2B%%3D%%3F%%26_%%23_&a%%3Db=a%%3Db&test=!%%24%%26'()*&lst%%5Ba%%5D%%5Bb%%5D=%%5B123%%5D%%5B456%%5D&pos%%7B1%%2C2%%7D=loc%%7Ba%%2Cb%%7D&%%3Ffoo=%%3Fbar&%%3F=%%3F&%%26bar=%%26bar&%%26=%%26"))
|
||||
|
||||
create h.make_empty
|
||||
if
|
||||
attached sess.post (requestbin_path, l_ctx, "") as res and then
|
||||
@@ -143,7 +197,7 @@ feature -- Factory
|
||||
l_ctx.set_upload_filename ("test.txt")
|
||||
create h.make_empty
|
||||
if
|
||||
attached sess.post (requestbin_path, l_ctx, "") as res and then
|
||||
attached sess.post (requestbin_path, l_ctx, Void) as res and then
|
||||
attached res.headers as hds
|
||||
then
|
||||
across
|
||||
@@ -202,7 +256,7 @@ feature -- Factory
|
||||
-- set filename to a local file
|
||||
sess := new_session ("http://requestb.in")
|
||||
create l_ctx.make
|
||||
l_ctx.set_upload_data ("This is a test for http client.%N")
|
||||
l_ctx.set_upload_data ("name=This is a test for http client.%N")
|
||||
create h.make_empty
|
||||
if
|
||||
attached sess.put (requestbin_path, l_ctx, Void) as res and then
|
||||
@@ -232,10 +286,12 @@ feature -- Factory
|
||||
-- check requestbin to ensure the file and form parameters are correctly received
|
||||
-- set filename to a local file
|
||||
sess := new_session ("http://requestb.in")
|
||||
-- sess := new_session ("http://localhost:9090")
|
||||
create l_ctx.make
|
||||
l_ctx.set_upload_filename ("logo.jpg")
|
||||
l_ctx.form_parameters.extend ("First Value", "First Key")
|
||||
l_ctx.form_parameters.extend ("Second Value", "Second Key")
|
||||
-- l_ctx.set_upload_filename ("logo.jpg")
|
||||
l_ctx.set_upload_filename ("test.txt")
|
||||
l_ctx.add_form_parameter ("First", "Value")
|
||||
l_ctx.add_form_parameter ("Second", "and last value")
|
||||
create h.make_empty
|
||||
if
|
||||
attached sess.post (requestbin_path, l_ctx, Void) as res and then
|
||||
@@ -297,6 +353,7 @@ feature -- Factory
|
||||
sess := new_session ("http://google.com")
|
||||
create h.make_empty
|
||||
if attached sess.get ("/", Void) as res and then attached res.headers as hds then
|
||||
assert("was redirected", res.redirections_count > 0)
|
||||
across
|
||||
hds as c
|
||||
loop
|
||||
@@ -328,6 +385,53 @@ feature -- Factory
|
||||
end
|
||||
end
|
||||
|
||||
test_get_with_query_parameters
|
||||
local
|
||||
sess: HTTP_CLIENT_SESSION
|
||||
h: STRING_8
|
||||
l_ctx: HTTP_CLIENT_REQUEST_CONTEXT
|
||||
q: STRING
|
||||
do
|
||||
if attached global_requestbin_path as requestbin_path then
|
||||
|
||||
-- GET REQUEST WITH A FILE AND FORM DATA
|
||||
-- check requestbin to ensure the file and form parameters are correctly received
|
||||
-- set filename to a local file
|
||||
sess := new_session ("http://requestb.in")
|
||||
create l_ctx.make
|
||||
l_ctx.add_query_parameter ("?", "?first&arg")
|
||||
l_ctx.add_query_parameter ("title", "Eiffel World!")
|
||||
l_ctx.add_query_parameter ("path", "foo/bar")
|
||||
l_ctx.add_query_parameter ("reserved", "+=&?")
|
||||
l_ctx.add_query_parameter ("unreserved", ":!@'()*")
|
||||
l_ctx.add_query_parameter ("unsafe", "%"[]{}")
|
||||
l_ctx.add_query_parameter ("test", "!$&'()*")
|
||||
l_ctx.add_query_parameter ("a&b", "a&b")
|
||||
l_ctx.add_query_parameter ("lst[a][b]", "[abc][123]")
|
||||
l_ctx.add_query_parameter ("foo(a,b)", "bar(1,2)*pi")
|
||||
create q.make_empty
|
||||
l_ctx.append_query_parameters_to_url (q)
|
||||
assert("query", q.same_string ("??=?first%%26arg&title=Eiffel+World!&path=foo/bar&reserved=%%2B=%%26?&unreserved=:!@'()*&unsafe=%%22%%5B%%5D%%7B%%7D&test=!$%%26'()*&a%%26b=a%%26b&lst%%5Ba%%5D%%5Bb%%5D=%%5Babc%%5D%%5B123%%5D&foo(a,b)=bar(1,2)*pi"))
|
||||
|
||||
|
||||
create h.make_empty
|
||||
if
|
||||
attached sess.get (requestbin_path, l_ctx) as res and then
|
||||
attached res.headers as hds
|
||||
then
|
||||
across
|
||||
hds as c
|
||||
loop
|
||||
h.append (c.item.name + ": " + c.item.value + "%R%N")
|
||||
end
|
||||
end
|
||||
print (h)
|
||||
else
|
||||
assert ("Has requestbin path", False)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<file_rule>
|
||||
<exclude>/http_stream_socket_ext.e$</exclude>
|
||||
<condition>
|
||||
<version type="compiler" max="16.9.9.9124"/>
|
||||
<version type="compiler" max="17.02"/>
|
||||
</condition>
|
||||
</file_rule>
|
||||
<cluster name="disabled_ssl_network" location="$|no_ssl\" recursive="true">
|
||||
@@ -114,6 +114,11 @@
|
||||
</condition>
|
||||
</cluster>
|
||||
</cluster>
|
||||
<cluster name="network_until_17_01" location=".\src\until_17_01\">
|
||||
<condition>
|
||||
<version type="compiler" min="16.9.9.9124" max="17.02"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
</target>
|
||||
<target name="http_network_ssl" extends="http_network">
|
||||
<variable name="ssl_enabled" value="true"/>
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<file_rule>
|
||||
<exclude>/http_stream_socket_ext.e$</exclude>
|
||||
<condition>
|
||||
<version type="compiler" max="16.9.9.9124"/>
|
||||
<version type="compiler" max="17.02"/>
|
||||
</condition>
|
||||
</file_rule>
|
||||
<cluster name="disabled_ssl_network" location="$|no_ssl\" recursive="true">
|
||||
@@ -114,6 +114,11 @@
|
||||
</condition>
|
||||
</cluster>
|
||||
</cluster>
|
||||
<cluster name="network_until_17_01" location=".\src\until_17_01\">
|
||||
<condition>
|
||||
<version type="compiler" min="16.9.9.9124" max="17.02"/>
|
||||
</condition>
|
||||
</cluster>
|
||||
</target>
|
||||
<target name="http_network_ssl" extends="http_network">
|
||||
<variable name="ssl_enabled" value="true"/>
|
||||
|
||||
@@ -36,13 +36,13 @@ feature -- Input
|
||||
-- Make result available in `last_character'.
|
||||
-- No exception raised!
|
||||
do
|
||||
read_to_managed_pointer_noexception (socket_buffer, 0, character_8_bytes)
|
||||
read_to_managed_pointer_noexception (read_socket_buffer, 0, character_8_bytes)
|
||||
if was_error then
|
||||
-- Socket error already set.
|
||||
elseif bytes_read /= character_8_bytes then
|
||||
socket_error := "Peer closed connection"
|
||||
else
|
||||
last_character := socket_buffer.read_character (0)
|
||||
last_character := read_socket_buffer.read_character (0)
|
||||
socket_error := Void
|
||||
end
|
||||
end
|
||||
@@ -208,8 +208,8 @@ feature -- Output
|
||||
put_character_noexception (c: CHARACTER)
|
||||
-- Write character `c' to socket.
|
||||
do
|
||||
socket_buffer.put_character (c, 0)
|
||||
put_managed_pointer_noexception (socket_buffer, 0, character_8_bytes)
|
||||
put_socket_buffer.put_character (c, 0)
|
||||
put_managed_pointer_noexception (put_socket_buffer, 0, character_8_bytes)
|
||||
end
|
||||
|
||||
put_string_8_noexception (s: READABLE_STRING_8)
|
||||
@@ -244,7 +244,7 @@ feature -- Status report
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -2,12 +2,20 @@ note
|
||||
description: "[
|
||||
Extension to HTTPD_STREAM_SOCKET to support backward compatibility.
|
||||
|
||||
TO BE REMOVED IN THE FUTURE, WHEN 16.05 IS OLD.
|
||||
TO BE REMOVED IN THE FUTURE, When there is no need to support older compilers.
|
||||
]"
|
||||
|
||||
deferred class
|
||||
HTTP_STREAM_SOCKET_EXT
|
||||
|
||||
feature {NONE} -- No-Exception network operation
|
||||
|
||||
note
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
|
||||
@@ -51,6 +51,20 @@ feature -- Access
|
||||
deferred
|
||||
end
|
||||
|
||||
socket_buffer: MANAGED_POINTER
|
||||
deferred
|
||||
end
|
||||
|
||||
read_socket_buffer: MANAGED_POINTER
|
||||
do
|
||||
Result := socket_buffer
|
||||
end
|
||||
|
||||
put_socket_buffer: MANAGED_POINTER
|
||||
do
|
||||
Result := socket_buffer
|
||||
end
|
||||
|
||||
feature -- Socket Recv and Send timeout.
|
||||
|
||||
set_recv_timeout (a_timeout_seconds: INTEGER)
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
note
|
||||
description: "[
|
||||
Extension to HTTPD_STREAM_SOCKET to support backward compatibility.
|
||||
|
||||
TO BE REMOVED IN THE FUTURE, WHEN 17.01 IS OLD.
|
||||
]"
|
||||
|
||||
deferred class
|
||||
HTTP_STREAM_SOCKET_EXT
|
||||
|
||||
feature -- Access
|
||||
|
||||
socket_buffer: MANAGED_POINTER
|
||||
deferred
|
||||
end
|
||||
|
||||
read_socket_buffer: MANAGED_POINTER
|
||||
do
|
||||
Result := socket_buffer
|
||||
end
|
||||
|
||||
put_socket_buffer: MANAGED_POINTER
|
||||
do
|
||||
Result := socket_buffer
|
||||
end
|
||||
|
||||
feature {NONE} -- No-Exception network operation
|
||||
|
||||
end
|
||||
@@ -114,14 +114,14 @@ feature -- Obsolete query
|
||||
|
||||
include_max_age: BOOLEAN
|
||||
obsolete
|
||||
"Use `max_age > 0' [April-2016]"
|
||||
"Use `max_age > 0' [2017-05-31]"
|
||||
do
|
||||
Result := max_age > 0
|
||||
end
|
||||
|
||||
include_expires: BOOLEAN
|
||||
obsolete
|
||||
"Use `expires /= Void' [April-2016]"
|
||||
"Use `expires /= Void' [2017-05-31]"
|
||||
do
|
||||
Result := expiration /= Void
|
||||
end
|
||||
@@ -133,7 +133,7 @@ feature -- Obsolete element change
|
||||
-- Set `expires to void'
|
||||
-- Set-Cookie will include only Max-Age attribute and not Expires.
|
||||
obsolete
|
||||
"Uset `set_max_age' and `unset_*' features to add or remove the attributes from the response header [April-2016]"
|
||||
"Uset `set_max_age' and `unset_*' features to add or remove the attributes from the response header [2017-05-31]"
|
||||
do
|
||||
max_age := 1
|
||||
expiration := Void
|
||||
@@ -147,7 +147,7 @@ feature -- Obsolete element change
|
||||
-- Set `expiration to a default date'
|
||||
-- Set-Cookie will include only Expires attribute and not Max_Age.
|
||||
obsolete
|
||||
"Use `set_expiration' and `unset_*' features to add or remove the attribute from the response header [April-2016]"
|
||||
"Use `set_expiration' and `unset_*' features to add or remove the attribute from the response header [2017-05-31]"
|
||||
do
|
||||
max_age := -1
|
||||
set_expiration_date (create {DATE_TIME}.make_now_utc)
|
||||
@@ -343,7 +343,7 @@ feature {NONE} -- Constants
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2016, Jocelyn Fiat, Eiffel Software and others"
|
||||
copyright: "2011-2017, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -54,7 +54,7 @@ feature {NONE} -- Initialization
|
||||
create date_time.make_from_epoch (n.as_integer_32)
|
||||
end
|
||||
|
||||
make_from_string (s: READABLE_STRING_8)
|
||||
make_from_string (s: READABLE_STRING_GENERAL)
|
||||
-- Create from string representation `s'
|
||||
-- Supports: RFC 1123 and RFC 850
|
||||
-- Tolerant with: GMT+offset and GMT-offset
|
||||
@@ -350,7 +350,7 @@ feature -- Helper routines.
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
string_to_date_time (s: READABLE_STRING_8): detachable DATE_TIME
|
||||
string_to_date_time (s: READABLE_STRING_GENERAL): detachable DATE_TIME
|
||||
-- String representation of `dt' using the RFC 1123
|
||||
-- HTTP-date = rfc1123-date | rfc850-date | asctime-date
|
||||
-- rfc1123-date = wkday "," SP date1 SP time SP "GMT"
|
||||
@@ -377,8 +377,8 @@ feature {NONE} -- Implementation
|
||||
note
|
||||
EIS: "name=RFC2616", "protocol=URI", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html"
|
||||
local
|
||||
t: STRING_8
|
||||
l_ddd, l_mmm: detachable STRING_8
|
||||
t: STRING_32
|
||||
l_ddd, l_mmm: detachable STRING_32
|
||||
l_dd, l_yyyy, l_hh, l_mi, l_ss, l_ff2: INTEGER
|
||||
l_mo: INTEGER
|
||||
l_gmt_offset: INTEGER -- minutes
|
||||
@@ -565,7 +565,7 @@ feature {NONE} -- Implementation
|
||||
t.extend (s[i].as_upper)
|
||||
i := i + 1
|
||||
end
|
||||
if
|
||||
if
|
||||
t.same_string ("GMT") -- for instance: GMT+0002
|
||||
or t.same_string ("UTC") -- for instance: UTC+0002
|
||||
or t.is_empty -- for instance: +0002
|
||||
@@ -622,7 +622,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
end
|
||||
|
||||
ansi_c_string_to_date_time (s: READABLE_STRING_8): detachable DATE_TIME
|
||||
ansi_c_string_to_date_time (s: READABLE_STRING_GENERAL): detachable DATE_TIME
|
||||
-- String representation of `dt' using the RFC 1123
|
||||
-- asctime-date = wkday SP date3 SP time SP 4DIGIT
|
||||
-- date3 = month SP ( 2DIGIT | ( SP 1DIGIT ))
|
||||
@@ -638,8 +638,8 @@ feature {NONE} -- Implementation
|
||||
note
|
||||
EIS: "name=RFC2616", "protocol=URI", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html"
|
||||
local
|
||||
t: STRING_8
|
||||
l_ddd, l_mmm: detachable STRING_8
|
||||
t: STRING_32
|
||||
l_ddd, l_mmm: detachable STRING_32
|
||||
l_dd, l_yyyy, l_hh, l_mi, l_ss, l_ff2: INTEGER
|
||||
l_mo: INTEGER
|
||||
l_gmt_offset: INTEGER -- minutes
|
||||
@@ -681,18 +681,18 @@ feature {NONE} -- Implementation
|
||||
-- Tolerant to full month name ..
|
||||
l_mmm.keep_head (3)
|
||||
end
|
||||
if l_mmm.same_string ("JAN") then l_mo := 01
|
||||
elseif l_mmm.same_string ("FEB") then l_mo := 02
|
||||
elseif l_mmm.same_string ("MAR") then l_mo := 03
|
||||
elseif l_mmm.same_string ("APR") then l_mo := 04
|
||||
elseif l_mmm.same_string ("MAY") then l_mo := 05
|
||||
elseif l_mmm.same_string ("JUN") then l_mo := 06
|
||||
elseif l_mmm.same_string ("JUL") then l_mo := 07
|
||||
elseif l_mmm.same_string ("AUG") then l_mo := 08
|
||||
elseif l_mmm.same_string ("SEP") then l_mo := 09
|
||||
elseif l_mmm.same_string ("OCT") then l_mo := 10
|
||||
elseif l_mmm.same_string ("NOV") then l_mo := 11
|
||||
elseif l_mmm.same_string ("DEC") then l_mo := 12
|
||||
if l_mmm.same_string_general ("JAN") then l_mo := 01
|
||||
elseif l_mmm.same_string_general ("FEB") then l_mo := 02
|
||||
elseif l_mmm.same_string_general ("MAR") then l_mo := 03
|
||||
elseif l_mmm.same_string_general ("APR") then l_mo := 04
|
||||
elseif l_mmm.same_string_general ("MAY") then l_mo := 05
|
||||
elseif l_mmm.same_string_general ("JUN") then l_mo := 06
|
||||
elseif l_mmm.same_string_general ("JUL") then l_mo := 07
|
||||
elseif l_mmm.same_string_general ("AUG") then l_mo := 08
|
||||
elseif l_mmm.same_string_general ("SEP") then l_mo := 09
|
||||
elseif l_mmm.same_string_general ("OCT") then l_mo := 10
|
||||
elseif l_mmm.same_string_general ("NOV") then l_mo := 11
|
||||
elseif l_mmm.same_string_general ("DEC") then l_mo := 12
|
||||
else err := True
|
||||
end
|
||||
else
|
||||
@@ -875,7 +875,7 @@ feature {NONE} -- Implementation
|
||||
invariant
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Eiffel Software and others"
|
||||
copyright: "2011-2017, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -118,7 +118,7 @@ feature -- Access
|
||||
header_named_value (a_name: READABLE_STRING_8): like item
|
||||
-- First header item found for `a_name' if any
|
||||
obsolete
|
||||
"Use `item' [2014-03]"
|
||||
"Use `item' [2017-05-31]"
|
||||
do
|
||||
Result := item (a_name)
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="ws_client" uuid="AF6EDC56-D7B4-4E1F-A62B-40EBED3D93DF">
|
||||
<target name="common">
|
||||
<target name="common" abstract="true">
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="echo_websocket_server" uuid="C9B3DA5F-DF0D-4C0F-924A-130B5C1E6604">
|
||||
<target name="common">
|
||||
<target name="common" abstract="true">
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
|
||||
@@ -55,7 +55,7 @@ feature -- Access
|
||||
|
||||
body: like content
|
||||
obsolete
|
||||
"Use `content' [June/2015]"
|
||||
"Use `content'. [2017-05-31]"
|
||||
do
|
||||
Result := body
|
||||
end
|
||||
@@ -69,6 +69,19 @@ feature -- Status report
|
||||
across to_addresses as ic all is_valid_address (ic.item) end
|
||||
end
|
||||
|
||||
has_header (a_header_name: READABLE_STRING_8): BOOLEAN
|
||||
-- Has additional header `a_header_name'?
|
||||
-- Warning: it checks only `additional_header_lines'!
|
||||
local
|
||||
h_colon: STRING
|
||||
do
|
||||
if attached additional_header_lines as lst then
|
||||
create h_colon.make_from_string (a_header_name)
|
||||
h_colon.append_character (':')
|
||||
Result := across lst as ic some ic.item.starts_with (h_colon) end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Change
|
||||
|
||||
set_date (d: like date)
|
||||
@@ -158,21 +171,6 @@ feature -- Header manipulation
|
||||
lst.force (a_line)
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
has_header (a_header_name: READABLE_STRING_8): BOOLEAN
|
||||
-- Has additional header `a_header_name'?
|
||||
-- Warning: it checks only `additional_header_lines'!
|
||||
local
|
||||
h_colon: STRING
|
||||
do
|
||||
if attached additional_header_lines as lst then
|
||||
create h_colon.make_from_string (a_header_name)
|
||||
h_colon.append_character (':')
|
||||
Result := across lst as ic some ic.item.starts_with (h_colon) end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Reset
|
||||
|
||||
reset
|
||||
@@ -209,8 +207,6 @@ feature -- Conversion
|
||||
end
|
||||
|
||||
header: STRING_8
|
||||
local
|
||||
hdate: HTTP_DATE
|
||||
do
|
||||
create Result.make (20)
|
||||
if attached reply_to_address as l_reply_to then
|
||||
@@ -259,8 +255,7 @@ feature -- Conversion
|
||||
Result.append (subject)
|
||||
Result.append_character ('%N')
|
||||
Result.append ("Date: ")
|
||||
create hdate.make_from_date_time (date)
|
||||
hdate.append_to_rfc1123_string (Result)
|
||||
;(create {HTTP_DATE}.make_from_date_time (date)).append_to_rfc1123_string (Result)
|
||||
Result.append_character ('%N')
|
||||
if attached additional_header_lines as l_lines and then
|
||||
not l_lines.is_empty
|
||||
@@ -285,11 +280,8 @@ feature -- Helpers
|
||||
Result := add.has ('@')
|
||||
end
|
||||
|
||||
invariant
|
||||
-- invariant_clause: True
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -43,11 +43,8 @@ feature {NONE} -- Initialization
|
||||
feature -- Status
|
||||
|
||||
is_available: BOOLEAN
|
||||
local
|
||||
f: RAW_FILE
|
||||
do
|
||||
create f.make_with_path (executable_path)
|
||||
Result := f.exists
|
||||
Result := (create {RAW_FILE}.make_with_path (executable_path)).exists
|
||||
end
|
||||
|
||||
feature -- Change
|
||||
@@ -108,7 +105,7 @@ feature -- Basic operation
|
||||
if attached arguments as l_args then
|
||||
args := l_args.twin
|
||||
else
|
||||
if attached {RAW_FILE} new_temporary_file (generator) as f then
|
||||
if attached new_temporary_file (generator) as f then
|
||||
f.create_read_write
|
||||
f.put_string (a_email.message)
|
||||
f.close
|
||||
@@ -196,10 +193,8 @@ feature {NONE} -- Implementation
|
||||
result_creatable: Result.is_creatable
|
||||
end
|
||||
|
||||
invariant
|
||||
|
||||
note
|
||||
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -4,9 +4,8 @@ note
|
||||
|
||||
Note: it is based on EiffelNet {SMTP_PROTOCOL} implementation, and may not be complete.
|
||||
]"
|
||||
author: "$Author: jfiat $"
|
||||
date: "$Date: 2015-06-30 11:07:17 +0200 (mar., 30 juin 2015) $"
|
||||
revision: "$Revision: 97586 $"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
NOTIFICATION_SMTP_MAILER
|
||||
@@ -57,15 +56,12 @@ feature {NONE} -- Initialization
|
||||
|
||||
initialize
|
||||
-- Initialize service.
|
||||
local
|
||||
l_address_factory: INET_ADDRESS_FACTORY
|
||||
do
|
||||
if attached username as u then
|
||||
create smtp_protocol.make (smtp_host, u)
|
||||
else
|
||||
-- Get local host name needed in creation of SMTP_PROTOCOL.
|
||||
create l_address_factory
|
||||
create smtp_protocol.make (smtp_host, l_address_factory.create_localhost.host_name)
|
||||
create smtp_protocol.make (smtp_host, (create {INET_ADDRESS_FACTORY}).create_localhost.host_name)
|
||||
end
|
||||
if smtp_port > 0 then
|
||||
smtp_protocol.set_default_port (smtp_port)
|
||||
@@ -98,9 +94,7 @@ feature -- Basic operation
|
||||
local
|
||||
l_email: EMAIL
|
||||
h: STRING
|
||||
k,v: STRING
|
||||
i: INTEGER
|
||||
hdate: HTTP_DATE
|
||||
do
|
||||
create l_email.make_with_entry (a_email.from_address, addresses_to_header_line_value (a_email.to_addresses))
|
||||
if attached a_email.reply_to_address as l_reply_to then
|
||||
@@ -117,8 +111,7 @@ feature -- Basic operation
|
||||
l_email.add_header_entry ({EMAIL_CONSTANTS}.H_subject, a_email.subject)
|
||||
|
||||
create h.make_empty
|
||||
create hdate.make_from_date_time (a_email.date)
|
||||
hdate.append_to_rfc1123_string (h)
|
||||
;(create {HTTP_DATE}.make_from_date_time (a_email.date)).append_to_rfc1123_string (h)
|
||||
l_email.add_header_entry ("Date", h)
|
||||
|
||||
if attached a_email.additional_header_lines as lst then
|
||||
@@ -128,9 +121,7 @@ feature -- Basic operation
|
||||
h := ic.item
|
||||
i := h.index_of (':', 1)
|
||||
if i > 0 then
|
||||
k := h.head (i - 1)
|
||||
v := h.substring (i + 1, h.count)
|
||||
l_email.add_header_entry (k, v)
|
||||
l_email.add_header_entry (h.head (i - 1), h.substring (i + 1, h.count))
|
||||
else
|
||||
check is_header_line: False end
|
||||
end
|
||||
@@ -181,7 +172,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
note
|
||||
description: "Store emails in specific folder."
|
||||
date: "$Date: 2017-03-08 10:34:57 +0100 (mer., 08 mars 2017) $"
|
||||
revision: "$Revision: 99935 $"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
NOTIFICATION_EMAIL_DIRECTORY_STORAGE
|
||||
@@ -41,7 +41,7 @@ feature -- Storage
|
||||
-- Store `a_email'.
|
||||
local
|
||||
retried: BOOLEAN
|
||||
f,w: RAW_FILE
|
||||
w: RAW_FILE
|
||||
dt: DATE_TIME
|
||||
p: PATH
|
||||
fn: STRING
|
||||
@@ -72,8 +72,7 @@ feature -- Storage
|
||||
p := p.extended (fn)
|
||||
|
||||
from
|
||||
create f.make_with_path (p)
|
||||
w := new_file_opened_for_writing (f)
|
||||
w := new_file_opened_for_writing (create {RAW_FILE}.make_with_path (p))
|
||||
until
|
||||
w /= Void or i > 100
|
||||
loop
|
||||
@@ -113,14 +112,15 @@ feature -- Storage
|
||||
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
|
||||
if
|
||||
not retried and then
|
||||
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
|
||||
ensure
|
||||
|
||||
@@ -47,7 +47,7 @@ feature -- Change
|
||||
across
|
||||
ax_to_sreg_map as c
|
||||
loop
|
||||
ask_info (c.key.to_string_32, is_required)
|
||||
ask_info (c.key, is_required)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -204,18 +204,18 @@ feature {OPENID_CONSUMER_VALIDATION} -- Implementation
|
||||
l_types as t
|
||||
loop
|
||||
s := xml_content (t.item)
|
||||
if s.same_string ("http://openid.net/sreg/1.0") then
|
||||
if s.same_string_general ("http://openid.net/sreg/1.0") then
|
||||
r_sreg_supported := True
|
||||
elseif s.same_string ("http://openid.net/extensions/sreg/1.1") then
|
||||
elseif s.same_string_general ("http://openid.net/extensions/sreg/1.1") then
|
||||
r_sreg_supported := True
|
||||
elseif s.same_string ("http://openid.net/srv/ax/1.0") then
|
||||
elseif s.same_string_general ("http://openid.net/srv/ax/1.0") then
|
||||
r_ax_supported := True
|
||||
elseif s.same_string ("http://specs.openid.net/auth/2.0/signon") then
|
||||
elseif s.same_string_general ("http://specs.openid.net/auth/2.0/signon") then
|
||||
r_version := 2
|
||||
elseif s.same_string ("http://specs.openid.net/auth/2.0/server") then
|
||||
elseif s.same_string_general ("http://specs.openid.net/auth/2.0/server") then
|
||||
r_version := 2
|
||||
r_identifier_select := True
|
||||
elseif s.same_string ("http://openid.net/signon/1.1") then
|
||||
elseif s.same_string_general ("http://openid.net/signon/1.1") then
|
||||
r_version := 1
|
||||
end
|
||||
end
|
||||
@@ -494,7 +494,7 @@ feature {NONE} -- Implementation
|
||||
|
||||
feature -- Helper
|
||||
|
||||
xml_content (e: XML_ELEMENT): STRING_8
|
||||
xml_content (e: XML_ELEMENT): STRING_32
|
||||
do
|
||||
create Result.make_empty
|
||||
if attached e.contents as lst then
|
||||
|
||||
@@ -89,10 +89,10 @@ feature -- Basic operation
|
||||
create ret.make_from_string (return_url)
|
||||
create tb.make (5)
|
||||
if attached values as q_lst then
|
||||
if attached item_by_name ("openid.claimed_id", q_lst) as q_claimed_id then
|
||||
l_claimed_id := q_claimed_id.as_string_8
|
||||
elseif attached item_by_name ("openid.identity", q_lst) as l_id then
|
||||
l_claimed_id := l_id
|
||||
if attached item_by_name ("openid.claimed_id", q_lst) as q_claimed_id and then q_claimed_id.is_valid_as_string_8 then
|
||||
l_claimed_id := q_claimed_id.to_string_8
|
||||
elseif attached item_by_name ("openid.identity", q_lst) as l_id and then l_id.is_valid_as_string_8 then
|
||||
l_claimed_id := l_id.to_string_8
|
||||
end
|
||||
identity := l_claimed_id
|
||||
tb.force (item_by_name ("openid.assoc_handle", q_lst), "openid.assoc_handle")
|
||||
@@ -117,7 +117,7 @@ feature -- Basic operation
|
||||
|
||||
if
|
||||
attached item_by_name ("openid.return_to", q_lst) as q_return_to and then
|
||||
not return_url.same_string (q_return_to)
|
||||
not return_url.same_string_general (q_return_to)
|
||||
then
|
||||
-- The return_to url must match the url of current request.
|
||||
-- I'm assuing that noone will set the returnUrl to something that doesn't make sense.
|
||||
@@ -217,7 +217,7 @@ feature -- Basic operation
|
||||
if s.same_string ({STRING_32} "ns.ax") and v.same_string ({STRING_32} "http://openid.net/srv/ax/1.0") then
|
||||
l_alias := "ax."
|
||||
else
|
||||
if v.same_string ("http://openid.net/srv/ax/1.0") then
|
||||
if v.same_string_general ("http://openid.net/srv/ax/1.0") then
|
||||
l_alias := s.substring (("ns.").count + 1, s.count).to_string_8 + "."
|
||||
end
|
||||
end
|
||||
@@ -235,8 +235,8 @@ feature -- Basic operation
|
||||
loop
|
||||
s := c.item
|
||||
if
|
||||
s.starts_with (k_value)
|
||||
or s.starts_with (k_type)
|
||||
s.starts_with_general (k_value)
|
||||
or s.starts_with_general (k_type)
|
||||
then
|
||||
ax_keys.force ("openid." + s)
|
||||
end
|
||||
@@ -251,17 +251,17 @@ feature -- Basic operation
|
||||
loop
|
||||
s := c.item
|
||||
if attached item_by_name (s, lst) as v then
|
||||
if s.starts_with (k_value) then
|
||||
if s.starts_with_general (k_value) then
|
||||
k := s.substring (k_value.count + 1, s.count)
|
||||
i := k.index_of ('.', 1)
|
||||
if i > 1 then
|
||||
k.keep_head (i - 1)
|
||||
end
|
||||
if attached item_by_name (k_type + k, lst) as l_type then
|
||||
if l_type.starts_with ("http://axschema.org/") then
|
||||
if l_type.starts_with_general ("http://axschema.org/") then
|
||||
check ("http://axschema.org/").count = 20 end
|
||||
attributes.force (v, l_type.substring (21, l_type.count))
|
||||
elseif l_type.starts_with ("http://schema.openid.net/") then
|
||||
elseif l_type.starts_with_general ("http://schema.openid.net/") then
|
||||
check ("http://schema.openid.net/").count = 25 end
|
||||
attributes.force (v, l_type.substring (26, l_type.count))
|
||||
else
|
||||
|
||||
@@ -137,7 +137,7 @@ feature -- Status report
|
||||
-- String that should be displayed in debugger to represent `Current'.
|
||||
do
|
||||
create Result.make_empty
|
||||
Result.append (type)
|
||||
Result.append_string_general (type)
|
||||
Result.append (" ")
|
||||
if attached login as l_login then
|
||||
Result.append ("login=[")
|
||||
|
||||
@@ -2,8 +2,8 @@ note
|
||||
description: "[
|
||||
Standalone Web Server connector.
|
||||
]"
|
||||
date: "$Date: 2016-08-06 13:34:52 +0200 (sam., 06 août 2016) $"
|
||||
revision: "$Revision: 99106 $"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WGI_STANDALONE_CONNECTOR [G -> WGI_EXECUTION create make end]
|
||||
@@ -110,7 +110,7 @@ feature -- Callbacks
|
||||
|
||||
on_launched_actions: ACTION_SEQUENCE [TUPLE [WGI_STANDALONE_CONNECTOR [WGI_EXECUTION]]]
|
||||
-- Actions triggered when launched.
|
||||
-- WARNING: only supported for now with SCOOP concurrency mode. [2016-oct-07]
|
||||
-- WARNING: only supported for now with SCOOP concurrency mode. [2016-10-07]
|
||||
|
||||
feature -- Event
|
||||
|
||||
@@ -201,7 +201,7 @@ feature -- Server
|
||||
-- Shutdown web server listening.
|
||||
do
|
||||
if launched then
|
||||
-- FIXME jfiat [2015/03/27] : prevent multiple calls (otherwise it hangs)
|
||||
-- FIXME: prevent multiple calls (otherwise it hangs) [2015-03-27]
|
||||
separate_shutdown_server_on_controller (controller)
|
||||
end
|
||||
end
|
||||
@@ -213,7 +213,7 @@ feature -- Events
|
||||
require
|
||||
obs.started -- SCOOP wait condition.
|
||||
do
|
||||
-- FIXME: this works only with SCOOP concurrency mode. [2016-oct-07]
|
||||
-- FIXME: this works only with SCOOP concurrency mode. [2016-10-07]
|
||||
if obs.port > 0 then
|
||||
on_launched (obs.port)
|
||||
end
|
||||
@@ -282,9 +282,8 @@ feature {NONE} -- Implementation: element change
|
||||
cfg.set_is_secure (b)
|
||||
end
|
||||
|
||||
|
||||
note
|
||||
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -94,7 +94,7 @@ feature {NONE} -- Implementation
|
||||
require
|
||||
a_value_not_is_empty: a_value /= Void
|
||||
do
|
||||
a_output.append (a_name)
|
||||
a_output.append_string_general (a_name)
|
||||
a_output.append_character ('=')
|
||||
a_output.append_string_general (a_value)
|
||||
a_output.append_character ('%N')
|
||||
@@ -103,7 +103,7 @@ feature {NONE} -- Implementation
|
||||
append_variable_to_debug_output (a_name: READABLE_STRING_8; a_value: detachable READABLE_STRING_GENERAL; a_output: STRING_32)
|
||||
do
|
||||
if a_value /= Void then
|
||||
a_output.append (a_name)
|
||||
a_output.append_string_general (a_name)
|
||||
a_output.append_character ('=')
|
||||
a_output.append_string_general (a_value)
|
||||
a_output.append_character ('%N')
|
||||
@@ -354,7 +354,7 @@ invariant
|
||||
request_method_set: not request_method.is_empty
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -54,7 +54,7 @@ feature -- Access
|
||||
|
||||
force_single_threaded: BOOLEAN assign set_force_single_threaded
|
||||
obsolete
|
||||
"Use directly `max_concurrent_connections = 1` [Feb/2017]"
|
||||
"Use directly `max_concurrent_connections = 1` [2017-05-31]"
|
||||
do
|
||||
Result := max_concurrent_connections <= 1
|
||||
end
|
||||
@@ -202,7 +202,7 @@ feature -- Element change
|
||||
-- Force server to handle incoming request in a single thread.
|
||||
-- i.e set max_concurrent_connections to 1!
|
||||
obsolete
|
||||
"Use set_max_concurrent_connections (1) [June/2016]"
|
||||
"Use set_max_concurrent_connections (1) [2017-05-31]"
|
||||
do
|
||||
if v then
|
||||
set_max_concurrent_connections (1)
|
||||
@@ -210,8 +210,8 @@ feature -- Element change
|
||||
set_max_concurrent_connections (default_max_concurrent_connections)
|
||||
end
|
||||
ensure
|
||||
force_single_threaded_set: v implies max_concurrent_connections <= 1
|
||||
not_single_threaded: not v implies max_concurrent_connections > 1
|
||||
force_single_threaded_set: v implies max_concurrent_connections <= 1
|
||||
not_single_threaded: not v implies max_concurrent_connections > 1
|
||||
end
|
||||
|
||||
set_is_verbose (b: BOOLEAN)
|
||||
@@ -340,7 +340,7 @@ feature -- SSL Helpers
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -60,6 +60,7 @@ feature -- Execution
|
||||
req: WGI_REQUEST_FROM_TABLE
|
||||
res: detachable WGI_RESPONSE_STREAM
|
||||
rescued: BOOLEAN
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
if not rescued then
|
||||
a_input.reset
|
||||
@@ -68,14 +69,14 @@ feature -- Execution
|
||||
service.execute (req, res)
|
||||
res.push
|
||||
else
|
||||
if attached (create {EXCEPTION_MANAGER}).last_exception as e and then attached e.exception_trace as l_trace then
|
||||
if attached (create {EXCEPTION_MANAGER}).last_exception as e and then attached e.trace as l_trace then
|
||||
if res /= Void then
|
||||
if not res.status_is_set then
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.internal_server_error, Void)
|
||||
end
|
||||
if res.message_writable then
|
||||
res.put_string ("<pre>")
|
||||
res.put_string (l_trace)
|
||||
res.put_string (utf.string_32_to_utf_8_string_8 (l_trace))
|
||||
res.put_string ("</pre>")
|
||||
end
|
||||
res.push
|
||||
@@ -105,7 +106,7 @@ invariant
|
||||
fcgi_attached: fcgi /= Void
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Eiffel Software and others"
|
||||
copyright: "2011-2017, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -122,7 +122,7 @@ feature {NONE} -- Initialization
|
||||
then
|
||||
secure_settings := [l_secure_prot, opts.option_string_32_value ("secure_certificate", Void), opts.option_string_32_value ("secure_certificate_key", Void)]
|
||||
elseif
|
||||
-- OBSOLETE: backward compatible with old settings name [oct/2016].
|
||||
-- OBSOLETE: backward compatible with old settings name [2017-05-31].
|
||||
opts.option_boolean_value ("ssl_enabled", is_secure) and then
|
||||
attached opts.option_string_32_value ("ssl_protocol", "tls_1_2") as ssl_prot
|
||||
then
|
||||
@@ -141,7 +141,7 @@ feature {NONE} -- Initialization
|
||||
force_single_threaded
|
||||
-- Set `single_threaded' to True.
|
||||
obsolete
|
||||
"Use set_max_concurrent_connections (1) [Feb/2017]"
|
||||
"Use set_max_concurrent_connections (1) [2017-05-31]"
|
||||
do
|
||||
set_max_concurrent_connections (1)
|
||||
ensure
|
||||
@@ -238,7 +238,7 @@ feature {NONE} -- Implementation
|
||||
|
||||
single_threaded: BOOLEAN
|
||||
obsolete
|
||||
"Use max_concurrent_connections <= 1 [Feb/2017]"
|
||||
"Use max_concurrent_connections <= 1 [2017-05-31]"
|
||||
do
|
||||
Result := max_concurrent_connections <= 1
|
||||
end
|
||||
@@ -277,7 +277,7 @@ feature -- Status report
|
||||
end
|
||||
|
||||
;note
|
||||
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -166,7 +166,8 @@ feature -- Basic Operation
|
||||
if is_verbose then
|
||||
log ("%NReceive <====================", debug_level)
|
||||
if attached req.raw_header_data as rhd then
|
||||
log (rhd, debug_level)
|
||||
check raw_header_is_valid_as_string_8: rhd.is_valid_as_string_8 end
|
||||
log (rhd.to_string_8, debug_level)
|
||||
end
|
||||
end
|
||||
if
|
||||
@@ -189,7 +190,8 @@ feature -- Basic Operation
|
||||
end
|
||||
-- Sending the server's opening handshake
|
||||
create l_sha1.make
|
||||
l_sha1.update_from_string (l_ws_key + magic_guid)
|
||||
check l_ws_key_is_valid_as_string_8: l_ws_key.is_valid_as_string_8 end
|
||||
l_sha1.update_from_string (l_ws_key.to_string_8 + magic_guid)
|
||||
l_key := Base64_encoder.encoded_string (digest (l_sha1))
|
||||
res.header.add_header_key_value ("Upgrade", "websocket")
|
||||
res.header.add_header_key_value ("Connection", "Upgrade")
|
||||
@@ -795,7 +797,7 @@ feature {NONE} -- Debug
|
||||
|
||||
|
||||
note
|
||||
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -69,7 +69,7 @@ feature -- Basic operations
|
||||
s.append (c.item.url_encoded_name)
|
||||
s.append_character (' ')
|
||||
s.append_character ('{')
|
||||
s.append (c.item.generating_type)
|
||||
s.append (c.item.generating_type.name)
|
||||
s.append_character ('}')
|
||||
s.append_character ('=')
|
||||
s.append (c.item.debug_output.as_string_8)
|
||||
@@ -80,7 +80,7 @@ feature -- Basic operations
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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)"
|
||||
licensing_options: "http://www.eiffel.com/licensing"
|
||||
copying: "[
|
||||
|
||||
@@ -245,7 +245,7 @@ feature {NONE} -- Implementation
|
||||
s.append_character (' ')
|
||||
if attached c.item as l_item then
|
||||
s.append_character ('{')
|
||||
s.append (l_item.generating_type)
|
||||
s.append (l_item.generating_type.name)
|
||||
s.append_character ('}')
|
||||
|
||||
s.append_character (' ')
|
||||
@@ -316,7 +316,7 @@ feature {NONE} -- Implementation
|
||||
else
|
||||
a_output.append (c.item.url_encoded_name)
|
||||
end
|
||||
t := c.item.generating_type
|
||||
t := c.item.generating_type.name
|
||||
if t.same_string ("WSF_STRING") then
|
||||
else
|
||||
a_output.append_character (' ')
|
||||
@@ -420,7 +420,7 @@ feature -- Constants
|
||||
invariant
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -108,13 +108,11 @@ feature -- Basic operations
|
||||
handle_precondition_failed (req, res)
|
||||
else
|
||||
if attached req.http_if_unmodified_since as l_if_unmodified_since then
|
||||
if l_if_unmodified_since.is_string_8 then
|
||||
create l_date.make_from_string (l_if_unmodified_since.as_string_8)
|
||||
if not l_date.has_error then
|
||||
if a_handler.modified_since (req, l_date.date_time) then
|
||||
handle_precondition_failed (req, res)
|
||||
l_failed := True
|
||||
end
|
||||
create l_date.make_from_string (l_if_unmodified_since)
|
||||
if not l_date.has_error then
|
||||
if a_handler.modified_since (req, l_date.date_time) then
|
||||
handle_precondition_failed (req, res)
|
||||
l_failed := True
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -128,13 +126,11 @@ feature -- Basic operations
|
||||
handle_if_none_match_failed (req, res, a_handler)
|
||||
else
|
||||
if attached req.http_if_modified_since as l_if_modified_since then
|
||||
if l_if_modified_since.is_string_8 then
|
||||
create l_date.make_from_string (l_if_modified_since.as_string_8)
|
||||
if not l_date.has_error then
|
||||
if not a_handler.modified_since (req, l_date.date_time) then
|
||||
handle_not_modified (req, res, a_handler)
|
||||
l_failed := True
|
||||
end
|
||||
create l_date.make_from_string (l_if_modified_since)
|
||||
if not l_date.has_error then
|
||||
if not a_handler.modified_since (req, l_date.date_time) then
|
||||
handle_not_modified (req, res, a_handler)
|
||||
l_failed := True
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -408,7 +404,7 @@ feature -- Error reporting
|
||||
if req.is_content_type_accepted ({HTTP_MIME_TYPES}.text_html) then
|
||||
s := "<html lang=%"en%"><head>"
|
||||
s.append ("<title>")
|
||||
s.append (html_encoder.encoded_string (req.request_uri))
|
||||
s.append (html_encoder.general_encoded_string (req.request_uri))
|
||||
s.append ("Error " + a_status_code.out + " (" + l_msg + ")")
|
||||
s.append ("</title>%N")
|
||||
s.append ("[
|
||||
@@ -434,7 +430,7 @@ feature -- Error reporting
|
||||
s.append ("</div>")
|
||||
s.append ("The current location for this resource is <a href=%"" + a_locations.first.string + "%">here</a>")
|
||||
s.append ("Error " + a_status_code.out + " (" + l_msg + ")</div>")
|
||||
s.append ("<div id=%"message%">Error " + a_status_code.out + " (" + l_msg + "): <code>" + html_encoder.encoded_string (req.request_uri) + "</code></div>")
|
||||
s.append ("<div id=%"message%">Error " + a_status_code.out + " (" + l_msg + "): <code>" + html_encoder.general_encoded_string (req.request_uri) + "</code></div>")
|
||||
s.append ("<div id=%"footer%"></div>")
|
||||
s.append ("</body>%N")
|
||||
s.append ("</html>%N")
|
||||
@@ -587,7 +583,7 @@ feature -- Error reporting
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Colin Adams, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -158,7 +158,7 @@ feature -- Access
|
||||
deferred
|
||||
end
|
||||
|
||||
matching_etag (req: WSF_REQUEST; a_etag: READABLE_STRING_32; a_strong: BOOLEAN): BOOLEAN
|
||||
matching_etag (req: WSF_REQUEST; a_etag: READABLE_STRING_GENERAL; a_strong: BOOLEAN): BOOLEAN
|
||||
-- Is `a_etag' a match for resource requested in `req'?
|
||||
-- If `a_strong' then the strong comparison function must be used.
|
||||
require
|
||||
|
||||
@@ -147,8 +147,11 @@ feature {WSF_RESPONSE} -- Output
|
||||
l_description.append ("</ul>")
|
||||
end
|
||||
|
||||
if doc_url_supported and then attached {WSF_STRING} request.query_parameter ("api") as l_api then
|
||||
l_api_resource := l_api.value
|
||||
if
|
||||
doc_url_supported and then attached {WSF_STRING} request.query_parameter ("api") as l_api and then
|
||||
l_api.value.is_valid_as_string_8
|
||||
then
|
||||
l_api_resource := l_api.value.to_string_8
|
||||
if l_api_resource.is_empty then
|
||||
l_api_resource := Void
|
||||
end
|
||||
@@ -324,7 +327,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -29,6 +29,8 @@ feature -- Element change
|
||||
|
||||
set_next (a_next: like next)
|
||||
-- Set `next' to `a_next'
|
||||
require
|
||||
a_next_is_not_current: a_next /= Current
|
||||
do
|
||||
next := a_next
|
||||
ensure
|
||||
|
||||
@@ -20,7 +20,7 @@ feature -- Mapping helper: uri
|
||||
map_uri_with_request_methods (a_uri: READABLE_STRING_8; h: WSF_URI_HANDLER; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
-- Map `h' as handler for `a_uri' for request methods `rqst_methods'.
|
||||
obsolete
|
||||
"Use directly `map_uri' [June/2015]"
|
||||
"Use directly `map_uri' [2017-05-31]"
|
||||
do
|
||||
map_uri (a_uri, h, rqst_methods)
|
||||
end
|
||||
@@ -44,7 +44,7 @@ feature -- Mapping helper: uri agent
|
||||
map_uri_agent_with_request_methods (a_uri: READABLE_STRING_8; proc: PROCEDURE [TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
-- Map `proc' as handler for `a_uri' for request methods `rqst_methods'.
|
||||
obsolete
|
||||
"Use directly `map_uri_agent' [June/2015]"
|
||||
"Use directly `map_uri_agent' [2017-05-31]"
|
||||
do
|
||||
map_uri_agent (a_uri, proc, rqst_methods)
|
||||
end
|
||||
@@ -58,7 +58,7 @@ feature -- Mapping helper: uri agent
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -23,7 +23,7 @@ feature -- Mapping helper: uri template
|
||||
map_uri_template_with_request_methods (a_tpl: READABLE_STRING_8; h: WSF_URI_TEMPLATE_HANDLER; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
-- Map `h' as handler for `a_tpl' for request methods `rqst_methods'.
|
||||
obsolete
|
||||
"Use directly `map_uri_template' [June/2015]"
|
||||
"Use directly `map_uri_template' [2017-05-31]"
|
||||
require
|
||||
a_tpl_attached: a_tpl /= Void
|
||||
h_attached: h /= Void
|
||||
@@ -54,7 +54,7 @@ feature -- Mapping helper: uri template agent
|
||||
map_uri_template_agent_with_request_methods (a_tpl: READABLE_STRING_8; proc: PROCEDURE [TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
-- Map `proc' as handler for `a_tpl' for request methods `rqst_methods'.
|
||||
obsolete
|
||||
"Use directly `map_uri_template_agent' [June/2015]"
|
||||
"Use directly `map_uri_template_agent' [2017-05-31]"
|
||||
require
|
||||
a_tpl_attached: a_tpl /= Void
|
||||
proc_attached: proc /= Void
|
||||
@@ -72,7 +72,7 @@ feature -- Mapping helper: uri template agent
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -187,9 +187,9 @@ feature -- Execution
|
||||
|
||||
execute (a_start_path: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
p: STRING_32
|
||||
p: STRING_8
|
||||
do
|
||||
create p.make_from_string (req.path_info)
|
||||
create p.make_from_string (req.percent_encoded_path_info)
|
||||
if p.starts_with_general (a_start_path) then
|
||||
p.remove_head (a_start_path.count)
|
||||
else
|
||||
@@ -203,7 +203,7 @@ feature -- Execution
|
||||
execute (a_start_path, req, res)
|
||||
end
|
||||
|
||||
process_uri (uri: READABLE_STRING_32; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
process_uri (uri: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
f: RAW_FILE
|
||||
fn: like resource_filename
|
||||
@@ -497,7 +497,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
end
|
||||
|
||||
resource_filename (uri: READABLE_STRING_32): PATH
|
||||
resource_filename (uri: READABLE_STRING_GENERAL): PATH
|
||||
local
|
||||
s: like uri_path_to_filename
|
||||
do
|
||||
@@ -544,7 +544,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
end
|
||||
|
||||
uri_path_to_filename (fn: READABLE_STRING_32): STRING_32
|
||||
uri_path_to_filename (fn: READABLE_STRING_GENERAL): STRING_32
|
||||
-- Real filename from url-path `fn'
|
||||
--| Find a better design for this piece of code
|
||||
--| Eventually in a spec/$ISE_PLATFORM/ specific cluster
|
||||
@@ -552,7 +552,7 @@ feature {NONE} -- Implementation
|
||||
n: INTEGER
|
||||
do
|
||||
n := fn.count
|
||||
create Result.make_from_string (fn)
|
||||
create Result.make_from_string_general (fn)
|
||||
if n > 0 and then Result.item (Result.count) = {CHARACTER_32} '/' then
|
||||
Result.remove_tail (1)
|
||||
n := n - 1
|
||||
@@ -595,7 +595,7 @@ feature {NONE} -- implementation: date time
|
||||
Result := timestamp_to_date (f.date)
|
||||
end
|
||||
|
||||
http_date_format_to_date (s: READABLE_STRING_8): detachable DATE_TIME
|
||||
http_date_format_to_date (s: READABLE_STRING_GENERAL): detachable DATE_TIME
|
||||
-- String representation of `dt' using the RFC 1123
|
||||
-- HTTP-date = rfc1123-date | rfc850-date | asctime-date
|
||||
-- rfc1123-date = wkday "," SP date1 SP time SP "GMT"
|
||||
|
||||
@@ -77,7 +77,7 @@ feature -- Mapping
|
||||
map_with_request_methods (a_mapping: WSF_ROUTER_MAPPING; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
-- Map `a_mapping' for request methods `rqst_methods'.
|
||||
obsolete
|
||||
"Use directly `map' [June/2015]"
|
||||
"Use directly `map' [2017-05-31]"
|
||||
require
|
||||
a_mapping_attached: a_mapping /= Void
|
||||
do
|
||||
@@ -135,7 +135,7 @@ feature -- Mapping handler
|
||||
-- Map the mapping created by factory `f' for resource `a_resource'
|
||||
-- and only for request methods `rqst_methods'
|
||||
obsolete
|
||||
"Use directly `handle' [June/2015]"
|
||||
"Use directly `handle' [2017-05-31]"
|
||||
require
|
||||
a_resource_attached: a_resource /= Void
|
||||
f_attached: f /= Void
|
||||
@@ -166,7 +166,7 @@ feature -- Basic operations
|
||||
-- And return the associated handler if mapping found and handler executed.
|
||||
--| Violates CQS
|
||||
obsolete
|
||||
"Use `dispatch' [2013-mar-21]"
|
||||
"Use `dispatch' [2017-05-31]"
|
||||
require
|
||||
req_attached: req /= Void
|
||||
res_attached: res /= Void
|
||||
@@ -601,7 +601,7 @@ invariant
|
||||
pre_execution_actions_attached: pre_execution_actions /= Void
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -45,7 +45,7 @@ feature -- Status report
|
||||
across
|
||||
mtds as c
|
||||
loop
|
||||
s.append_string (c.item)
|
||||
s.append_string_general (c.item)
|
||||
s.append_string (" ")
|
||||
end
|
||||
s.append_string ("]")
|
||||
@@ -65,7 +65,7 @@ invariant
|
||||
mapping_attached: mapping /= Void
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -50,8 +50,14 @@ feature -- Status report
|
||||
|
||||
debug_output: READABLE_STRING_GENERAL
|
||||
-- String that should be displayed in debugger to represent `Current'.
|
||||
local
|
||||
s: STRING_32
|
||||
do
|
||||
Result := description + {STRING_32} " : " + associated_resource.to_string_32
|
||||
create s.make_empty
|
||||
s.append (description)
|
||||
s.append_string_general (" : ")
|
||||
s.append_string_general (associated_resource)
|
||||
Result := s
|
||||
end
|
||||
|
||||
feature -- Status
|
||||
@@ -78,7 +84,7 @@ feature -- Status
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -24,7 +24,7 @@ feature -- Mapping helper: starts_with
|
||||
|
||||
map_starts_with_request_methods (a_uri: READABLE_STRING_8; h: WSF_STARTS_WITH_CONTEXT_HANDLER [C]; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
obsolete
|
||||
"Use directly `map_starts_with' [June-2015]"
|
||||
"Use directly `map_starts_with' [2017-05-31]"
|
||||
require
|
||||
a_uri_attached: a_uri /= Void
|
||||
h_attached: h /= Void
|
||||
@@ -44,7 +44,7 @@ feature -- Mapping helper: starts_with agent
|
||||
|
||||
map_starts_with_agent_with_request_methods (a_uri: READABLE_STRING_8; proc: PROCEDURE [TUPLE [start_path: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
obsolete
|
||||
"Use directly `map_starts_with_agent' [June-2015]"
|
||||
"Use directly `map_starts_with_agent' [2017-05-31]"
|
||||
require
|
||||
a_uri_attached: a_uri /= Void
|
||||
proc_attached: proc /= Void
|
||||
@@ -53,7 +53,7 @@ feature -- Mapping helper: starts_with agent
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -24,7 +24,7 @@ feature -- Mapping helper: uri
|
||||
|
||||
map_uri_with_request_methods (a_uri: READABLE_STRING_8; h: WSF_URI_CONTEXT_HANDLER [C]; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
obsolete
|
||||
"Use directly `map_uri' [June-2015]"
|
||||
"Use directly `map_uri' [2017-05-31]"
|
||||
require
|
||||
a_uri_attached: a_uri /= Void
|
||||
h_attached: h /= Void
|
||||
@@ -44,7 +44,7 @@ feature -- Mapping helper: uri agent
|
||||
|
||||
map_uri_agent_with_request_methods (a_uri: READABLE_STRING_8; proc: PROCEDURE [TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
obsolete
|
||||
"Use directly `map_uri_agent' [June-2015]"
|
||||
"Use directly `map_uri_agent' [2017-05-31]"
|
||||
require
|
||||
a_uri_attached: a_uri /= Void
|
||||
proc_attached: proc /= Void
|
||||
@@ -53,7 +53,7 @@ feature -- Mapping helper: uri agent
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -24,7 +24,7 @@ feature -- Mapping helper: uri
|
||||
|
||||
map_uri_template_with_request_methods (a_tpl: READABLE_STRING_8; h: WSF_URI_TEMPLATE_CONTEXT_HANDLER [C]; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
obsolete
|
||||
"Use directly `make_uri_template' [June/2015]"
|
||||
"Use directly `make_uri_template' [2017-05-31]"
|
||||
require
|
||||
a_tpl_attached: a_tpl /= Void
|
||||
h_attached: h /= Void
|
||||
@@ -44,7 +44,7 @@ feature -- Mapping helper: uri agent
|
||||
|
||||
map_uri_template_agent_with_request_methods (a_tpl: READABLE_STRING_8; proc: PROCEDURE [TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||
obsolete
|
||||
"Use directly `make_uri_template_agent' [June/2015]"
|
||||
"Use directly `make_uri_template_agent' [2017-05-31]"
|
||||
require
|
||||
a_tpl_attached: a_tpl /= Void
|
||||
proc_attached: proc /= Void
|
||||
@@ -53,7 +53,7 @@ feature -- Mapping helper: uri agent
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -32,8 +32,12 @@ feature {NONE} -- Initialization
|
||||
elseif attached {WSF_STRING} req.query_parameter (cookie_name) as q_uuid then
|
||||
l_uuid := q_uuid.value
|
||||
end
|
||||
if l_uuid /= Void and then session_exists (l_uuid) then
|
||||
uuid := l_uuid
|
||||
if
|
||||
l_uuid /= Void and then
|
||||
l_uuid.is_valid_as_string_8 and then
|
||||
session_exists (l_uuid)
|
||||
then
|
||||
uuid := l_uuid.to_string_8
|
||||
load
|
||||
else
|
||||
is_pending := True
|
||||
@@ -128,7 +132,7 @@ feature {NONE} -- Storage
|
||||
|
||||
manager: WSF_SESSION_MANAGER
|
||||
|
||||
session_exists (a_uuid: like uuid): BOOLEAN
|
||||
session_exists (a_uuid: READABLE_STRING_GENERAL): BOOLEAN
|
||||
do
|
||||
Result := manager.session_exists (a_uuid)
|
||||
end
|
||||
@@ -183,7 +187,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -30,7 +30,7 @@ feature {NONE} -- Initialization
|
||||
|
||||
feature -- Access
|
||||
|
||||
session_exists (a_session_uuid: READABLE_STRING_8): BOOLEAN
|
||||
session_exists (a_session_uuid: READABLE_STRING_GENERAL): 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: READABLE_STRING_8): detachable WSF_SESSION_DATA
|
||||
session_data (a_session_uuid: READABLE_STRING_GENERAL): detachable WSF_SESSION_DATA
|
||||
local
|
||||
f: RAW_FILE
|
||||
do
|
||||
@@ -153,7 +153,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -16,7 +16,7 @@ feature -- Access
|
||||
|
||||
uuid: READABLE_STRING_8
|
||||
obsolete
|
||||
"Use `id' which is more general [2014-03]"
|
||||
"Use `id' which is more general [2017-05-31]"
|
||||
deferred
|
||||
end
|
||||
|
||||
@@ -116,7 +116,7 @@ feature -- Control
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -9,11 +9,11 @@ deferred class
|
||||
|
||||
feature -- Access
|
||||
|
||||
session_exists (a_uuid: READABLE_STRING_8): BOOLEAN
|
||||
session_exists (a_uuid: READABLE_STRING_GENERAL): BOOLEAN
|
||||
deferred
|
||||
end
|
||||
|
||||
session_data (a_uuid: READABLE_STRING_8): detachable WSF_SESSION_DATA
|
||||
session_data (a_uuid: READABLE_STRING_GENERAL): detachable WSF_SESSION_DATA
|
||||
deferred
|
||||
end
|
||||
|
||||
@@ -28,7 +28,7 @@ feature -- Persistence
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -52,14 +52,14 @@ feature -- Status report
|
||||
|
||||
feature -- Query
|
||||
|
||||
string_representation: STRING_32
|
||||
string_representation: READABLE_STRING_32
|
||||
-- String representation of Current
|
||||
-- if possible
|
||||
do
|
||||
if attached value as v then
|
||||
Result := v.generating_type
|
||||
Result := generating_type.name_32
|
||||
else
|
||||
Result := "Void"
|
||||
Result := {STRING_32} "Void"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -71,7 +71,7 @@ feature -- Visitor
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -69,7 +69,7 @@ feature -- Access
|
||||
|
||||
frozen string_values: like values
|
||||
obsolete
|
||||
"Use `values' [2012-May-31]"
|
||||
"Use `values' [2017-05-31]"
|
||||
do
|
||||
Result := values
|
||||
end
|
||||
@@ -81,7 +81,7 @@ feature -- Access
|
||||
|
||||
frozen first_string_value: WSF_STRING
|
||||
obsolete
|
||||
"Use `first_value' [2012-May-31]"
|
||||
"Use `first_value' [2017-05-31]"
|
||||
do
|
||||
Result := first_value
|
||||
end
|
||||
@@ -179,7 +179,7 @@ invariant
|
||||
string_values_not_empty: values.count >= 1
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -126,17 +126,10 @@ feature -- Helper
|
||||
Result := value.same_string_general (a_other)
|
||||
end
|
||||
|
||||
is_case_insensitive_equal (a_other: READABLE_STRING_8): BOOLEAN
|
||||
is_case_insensitive_equal (a_other: READABLE_STRING_GENERAL): BOOLEAN
|
||||
-- Does `a_other' represent the same case insensitive string as `Current'?
|
||||
local
|
||||
v: like value
|
||||
do
|
||||
v := value
|
||||
if v = a_other then
|
||||
Result := True
|
||||
elseif v.is_valid_as_string_8 then
|
||||
Result := v.is_case_insensitive_equal (a_other)
|
||||
end
|
||||
Result := value.is_case_insensitive_equal_general (a_other)
|
||||
end
|
||||
|
||||
feature -- Conversion
|
||||
@@ -154,7 +147,7 @@ feature -- Visitor
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -2,8 +2,8 @@ note
|
||||
description: "[
|
||||
Table which can contain value indexed by a key
|
||||
]"
|
||||
date: "$Date: 2015-11-05 21:52:56 +0100 (jeu., 05 nov. 2015) $"
|
||||
revision: "$Revision: 98081 $"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WSF_TABLE
|
||||
@@ -86,7 +86,7 @@ feature -- Access
|
||||
|
||||
frozen first_key: like first_name
|
||||
obsolete
|
||||
"Use first_name [2012-May-31]"
|
||||
"Use first_name [2017-05-31]"
|
||||
do
|
||||
Result := first_name
|
||||
end
|
||||
@@ -130,7 +130,7 @@ feature -- Conversion
|
||||
end
|
||||
|
||||
as_array_of_string: detachable ARRAY [READABLE_STRING_32]
|
||||
-- Return an array of STRING if possible., otherwise Void
|
||||
-- Return an array of STRING if possible, otherwise Void.
|
||||
local
|
||||
i,n: INTEGER
|
||||
nb: INTEGER
|
||||
@@ -145,6 +145,10 @@ feature -- Conversion
|
||||
if attached {WSF_STRING} value (i.out) as s then
|
||||
Result.put (s.value, i)
|
||||
nb := nb + 1
|
||||
--FIXME elseif attached {WSF_STRING} value (name + "[" + i.out + "]") as s then
|
||||
--
|
||||
-- Result.put (s.value, i)
|
||||
-- nb := nb + 1
|
||||
else
|
||||
Result := Void
|
||||
end
|
||||
@@ -232,7 +236,7 @@ feature -- Visitor
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -94,7 +94,7 @@ feature -- Status report
|
||||
|
||||
feature -- Conversion
|
||||
|
||||
string_representation: STRING_32
|
||||
string_representation: READABLE_STRING_32
|
||||
do
|
||||
Result := filename
|
||||
end
|
||||
@@ -250,7 +250,7 @@ feature -- Element change
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -70,7 +70,7 @@ feature -- Query
|
||||
end
|
||||
end
|
||||
|
||||
string_representation: STRING_32
|
||||
string_representation: READABLE_STRING_32
|
||||
-- String representation of Current
|
||||
-- if possible
|
||||
-- note: unicode value.
|
||||
@@ -89,7 +89,7 @@ feature -- Helper
|
||||
result_true_only_for_string: Result implies is_string
|
||||
end
|
||||
|
||||
is_case_insensitive_equal (a_other: READABLE_STRING_8): BOOLEAN
|
||||
is_case_insensitive_equal (a_other: READABLE_STRING_GENERAL): BOOLEAN
|
||||
-- Does `a_other' represent the same case insensitive string as `Current'?
|
||||
do
|
||||
if is_string then
|
||||
@@ -130,7 +130,7 @@ feature -- Visitor
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -83,7 +83,7 @@ feature {WSF_RESPONSE} -- Output
|
||||
else
|
||||
--| Other response codes are possible, such as 301 Moved permananently,
|
||||
--| 302 Found and 410 Gone. But these require handlers to implement,
|
||||
--| so no other code can be given at this point.
|
||||
--| so no other code can be given at this point.
|
||||
msg := not_found_message (req)
|
||||
end
|
||||
res.send (msg)
|
||||
@@ -98,7 +98,7 @@ feature {NONE} -- Implementation
|
||||
do
|
||||
create Result.make (req)
|
||||
end
|
||||
|
||||
|
||||
method_not_allowed_message (req: WSF_REQUEST): detachable WSF_METHOD_NOT_ALLOWED_RESPONSE
|
||||
require
|
||||
req_attached: req /= Void
|
||||
@@ -125,13 +125,13 @@ feature {NONE} -- Implementation
|
||||
l_is_hidden := l_doc_mapping.documentation (i.request_methods).is_hidden
|
||||
end
|
||||
if not l_is_hidden then
|
||||
create s.make_from_string (i.mapping.associated_resource)
|
||||
create s.make_from_string_general (i.mapping.associated_resource)
|
||||
if attached i.request_methods as mtds then
|
||||
s.append (" [ ")
|
||||
across
|
||||
mtds as mtds_c
|
||||
loop
|
||||
s.append (mtds_c.item)
|
||||
s.append_string_general (mtds_c.item)
|
||||
s.append_character (' ')
|
||||
end
|
||||
s.append ("]")
|
||||
@@ -169,7 +169,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
if not l_is_hidden then
|
||||
ok := True
|
||||
create s.make_from_string (i.mapping.associated_resource)
|
||||
create s.make_from_string_general (i.mapping.associated_resource)
|
||||
if attached i.request_methods as mtds then
|
||||
ok := False
|
||||
s.append (" [ ")
|
||||
@@ -179,7 +179,7 @@ feature {NONE} -- Implementation
|
||||
if m = Void or else m.is_case_insensitive_equal (c.item) then
|
||||
ok := True
|
||||
end
|
||||
s.append (c.item)
|
||||
s.append_string_general (c.item)
|
||||
s.append_character (' ')
|
||||
end
|
||||
s.append ("]")
|
||||
@@ -196,7 +196,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -94,7 +94,7 @@ feature -- Access
|
||||
|
||||
file_name: READABLE_STRING_8
|
||||
obsolete
|
||||
"Use `file_path.name' for unicode support [2013-may]"
|
||||
"Use `file_path.name' for unicode support [2017-05-31]"
|
||||
do
|
||||
Result := file_path.utf_8_name
|
||||
end
|
||||
@@ -230,7 +230,7 @@ invariant
|
||||
status_code_set: status_code /= 0
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -165,7 +165,7 @@ feature -- Access
|
||||
|
||||
file_name: READABLE_STRING_8
|
||||
obsolete
|
||||
"Use `file_path.name' for unicode support [2013-may]"
|
||||
"Use `file_path.name' for unicode support [2017-05-31]"
|
||||
do
|
||||
Result := file_path.utf_8_name
|
||||
end
|
||||
@@ -320,7 +320,7 @@ feature {NONE} -- Implementation: output
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -101,9 +101,9 @@ feature {WSF_RESPONSE} -- Output
|
||||
do
|
||||
create l_messages
|
||||
h := header
|
||||
if
|
||||
not attached recognized_methods as l_recognized_methods
|
||||
or else l_recognized_methods.has (request.request_method.as_upper)
|
||||
if
|
||||
not attached recognized_methods as l_recognized_methods
|
||||
or else l_recognized_methods.has (request.request_method.as_upper)
|
||||
then
|
||||
res.set_status_code (l_messages.method_not_allowed)
|
||||
else
|
||||
@@ -130,7 +130,7 @@ feature {WSF_RESPONSE} -- Output
|
||||
if request.is_content_type_accepted ({HTTP_MIME_TYPES}.text_html) then
|
||||
s := "<html lang=%"en%"><head>"
|
||||
s.append ("<title>")
|
||||
s.append (html_encoder.encoded_string (request.request_uri))
|
||||
s.append (html_encoder.general_encoded_string (request.request_uri))
|
||||
s.append (l_html_error_code_text + "!!")
|
||||
s.append ("</title>%N")
|
||||
s.append (
|
||||
@@ -160,7 +160,7 @@ feature {WSF_RESPONSE} -- Output
|
||||
s.append (l_html_error_code_text + "</div>")
|
||||
s.append ("<div id=%"message%">" + l_html_error_code_text + ": the request method <code>")
|
||||
s.append (request.request_method)
|
||||
s.append ("</code> is inappropriate for the URL for <code>" + html_encoder.encoded_string (request.request_uri) + "</code>.</div>")
|
||||
s.append ("</code> is inappropriate for the URL for <code>" + html_encoder.general_encoded_string (request.request_uri) + "</code>.</div>")
|
||||
if attached suggested_methods as lst and then not lst.is_empty then
|
||||
s.append ("<div id=%"suggestions%"><strong>Allowed methods:</strong>")
|
||||
across
|
||||
@@ -186,17 +186,17 @@ feature {WSF_RESPONSE} -- Output
|
||||
l_text := l_loc
|
||||
end
|
||||
s.append ("<li>")
|
||||
s.append ("<a href=%"" + l_loc + "%">" + html_encoder.encoded_string (l_text.to_string_32) + "</a>")
|
||||
s.append ("<a href=%"" + l_loc + "%">" + html_encoder.general_encoded_string (l_text) + "</a>")
|
||||
elseif l_text /= Void then
|
||||
|
||||
s.append ("<li>")
|
||||
s.append (html_encoder.encoded_string (l_text.to_string_32))
|
||||
s.append (html_encoder.general_encoded_string (l_text))
|
||||
s.append ("</li>%N")
|
||||
end
|
||||
if (l_loc /= Void or l_text /= Void) then
|
||||
if attached lst.item.description as l_desc then
|
||||
s.append ("<br/> - ")
|
||||
s.append (html_encoder.encoded_string (l_desc.to_string_32))
|
||||
s.append (html_encoder.general_encoded_string (l_desc))
|
||||
s.append ("%N")
|
||||
end
|
||||
s.append ("</li>%N")
|
||||
@@ -221,7 +221,7 @@ feature {WSF_RESPONSE} -- Output
|
||||
else
|
||||
s := l_html_error_code_text + ": the request method "
|
||||
s.append (request.request_method)
|
||||
s.append (" is inappropriate for the URL for '" + html_encoder.encoded_string (request.request_uri) + "'.%N")
|
||||
s.append (" is inappropriate for the URL for '" + html_encoder.general_encoded_string (request.request_uri) + "'.%N")
|
||||
if attached suggested_methods as lst and then not lst.is_empty then
|
||||
s.append ("Allowed methods:")
|
||||
across
|
||||
@@ -327,7 +327,7 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -76,7 +76,7 @@ feature {WSF_RESPONSE} -- Output
|
||||
if request.is_content_type_accepted ({HTTP_MIME_TYPES}.text_html) then
|
||||
s := "<html lang=%"en%"><head>"
|
||||
s.append ("<title>")
|
||||
s.append (html_encoder.encoded_string (request.request_uri))
|
||||
s.append (html_encoder.general_encoded_string (request.request_uri))
|
||||
s.append ("Error 404 (Not Found)")
|
||||
s.append ("</title>%N")
|
||||
s.append ("[
|
||||
@@ -101,7 +101,7 @@ feature {WSF_RESPONSE} -- Output
|
||||
s.append ("<div class=%"inner2%"></div>")
|
||||
s.append ("</div>")
|
||||
s.append ("Error 404 (Not Found)</div>")
|
||||
s.append ("<div id=%"message%">Error 404 (Not Found): <code>" + html_encoder.encoded_string (request.request_uri) + "</code></div>")
|
||||
s.append ("<div id=%"message%">Error 404 (Not Found): <code>" + html_encoder.general_encoded_string (request.request_uri) + "</code></div>")
|
||||
if attached suggested_items as lst and then not lst.is_empty then
|
||||
s.append ("<div id=%"suggestions%"><strong>Perhaps you are looking for:</strong><ul>")
|
||||
from
|
||||
@@ -116,17 +116,17 @@ feature {WSF_RESPONSE} -- Output
|
||||
l_text := l_loc
|
||||
end
|
||||
s.append ("<li>")
|
||||
s.append ("<a href=%"" + l_loc + "%">" + html_encoder.encoded_string (l_text.to_string_32) + "</a>")
|
||||
s.append ("<a href=%"" + l_loc + "%">" + html_encoder.general_encoded_string (l_text) + "</a>")
|
||||
elseif l_text /= Void then
|
||||
|
||||
s.append ("<li>")
|
||||
s.append (html_encoder.encoded_string (l_text.to_string_32))
|
||||
s.append (html_encoder.general_encoded_string (l_text))
|
||||
s.append ("</li>%N")
|
||||
end
|
||||
if (l_loc /= Void or l_text /= Void) then
|
||||
if attached lst.item.description as l_desc then
|
||||
s.append ("<br/> - ")
|
||||
s.append (html_encoder.encoded_string (l_desc.to_string_32))
|
||||
s.append (html_encoder.general_encoded_string (l_desc))
|
||||
s.append ("%N")
|
||||
end
|
||||
s.append ("</li>%N")
|
||||
@@ -198,7 +198,7 @@ feature {WSF_RESPONSE} -- Output
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -61,7 +61,7 @@ feature {WSF_RESPONSE} -- Output
|
||||
if request.is_content_type_accepted ({HTTP_MIME_TYPES}.text_html) then
|
||||
s := "<html lang=%"en%"><head>"
|
||||
s.append ("<title>")
|
||||
s.append (html_encoder.encoded_string (request.request_uri))
|
||||
s.append (html_encoder.general_encoded_string (request.request_uri))
|
||||
s.append ("Error 412 (Precondition Failed)")
|
||||
s.append ("</title>%N")
|
||||
s.append ("[
|
||||
@@ -84,7 +84,7 @@ feature {WSF_RESPONSE} -- Output
|
||||
s.append ("<div class=%"inner2%"></div>")
|
||||
s.append ("</div>")
|
||||
s.append ("Error 412 (Precondition Failed)</div>")
|
||||
s.append ("<div id=%"message%">Error 412 (Precondition Failed): <code>" + html_encoder.encoded_string (request.request_uri) + "</code></div>")
|
||||
s.append ("<div id=%"message%">Error 412 (Precondition Failed): <code>" + html_encoder.general_encoded_string (request.request_uri) + "</code></div>")
|
||||
if attached body as b then
|
||||
s.append ("<div>")
|
||||
s.append (b)
|
||||
@@ -116,7 +116,7 @@ feature {WSF_RESPONSE} -- Output
|
||||
|
||||
note
|
||||
|
||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -346,7 +346,7 @@ feature -- Helper
|
||||
is_request_method (m: READABLE_STRING_GENERAL): BOOLEAN
|
||||
-- Is `m' the Current request_method?
|
||||
do
|
||||
Result := request_method.is_case_insensitive_equal (m.as_string_8)
|
||||
Result := m.is_case_insensitive_equal (request_method)
|
||||
end
|
||||
|
||||
is_put_request_method: BOOLEAN
|
||||
@@ -691,7 +691,7 @@ feature -- Access: CGI Meta variables
|
||||
do
|
||||
meta_variables_table.force (new_string_value (a_name, a_value), a_name)
|
||||
ensure
|
||||
param_set: attached {WSF_STRING} meta_variable (a_name) as val and then val.url_encoded_value.same_string (a_value)
|
||||
param_set: attached {WSF_STRING} meta_variable (a_name) as val and then a_value.same_string_general (val.url_encoded_value)
|
||||
end
|
||||
|
||||
unset_meta_variable (a_name: READABLE_STRING_GENERAL)
|
||||
@@ -842,7 +842,7 @@ feature -- Access: CGI meta parameters - 1.1
|
||||
if pi.is_empty then
|
||||
l_result := ""
|
||||
elseif pi.count = 1 and then pi[1] = '/' then
|
||||
l_result := "/"
|
||||
l_result := "/"
|
||||
else
|
||||
r := request_uri
|
||||
i := r.index_of ('?', 1)
|
||||
@@ -2110,7 +2110,7 @@ invariant
|
||||
wgi_request.content_type /= Void implies content_type /= Void
|
||||
|
||||
note
|
||||
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||
copyright: "2011-2017, 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
|
||||
|
||||
@@ -38,7 +38,7 @@ feature -- Element change
|
||||
v: READABLE_STRING_8
|
||||
do
|
||||
if a_text /= Void then
|
||||
v := html_encoded_string (a_text.to_string_32)
|
||||
v := html_encoded_string (a_text)
|
||||
across
|
||||
options as o
|
||||
loop
|
||||
@@ -69,7 +69,7 @@ feature -- Element change
|
||||
v: READABLE_STRING_8
|
||||
do
|
||||
if a_text /= Void then
|
||||
v := html_encoded_string (a_text.to_string_32)
|
||||
v := html_encoded_string (a_text)
|
||||
across
|
||||
options as o
|
||||
loop
|
||||
|
||||
@@ -10,17 +10,19 @@ class
|
||||
inherit
|
||||
WSF_FORM_SELECTABLE_ITEM
|
||||
|
||||
SHARED_HTML_ENCODER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_value: like value; a_text: detachable like text)
|
||||
make (a_value: READABLE_STRING_GENERAL; a_text: detachable like text)
|
||||
-- Initialize `Current'.
|
||||
do
|
||||
value := a_value
|
||||
value := a_value.as_string_32
|
||||
if a_text = Void then
|
||||
text := a_value
|
||||
text := html_encoder.general_encoded_string (a_value)
|
||||
else
|
||||
text := a_text
|
||||
end
|
||||
@@ -30,9 +32,9 @@ feature -- Status
|
||||
|
||||
is_selected: BOOLEAN
|
||||
|
||||
is_same_value (v: READABLE_STRING_32): BOOLEAN
|
||||
is_same_value (v: READABLE_STRING_GENERAL): BOOLEAN
|
||||
do
|
||||
Result := value.same_string (v)
|
||||
Result := value.same_string_general (v)
|
||||
end
|
||||
|
||||
is_same_text (v: like text): BOOLEAN
|
||||
|
||||
@@ -12,7 +12,7 @@ feature -- Status report
|
||||
deferred
|
||||
end
|
||||
|
||||
is_same_value (v: READABLE_STRING_32): BOOLEAN
|
||||
is_same_value (v: READABLE_STRING_GENERAL): BOOLEAN
|
||||
deferred
|
||||
end
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@ class
|
||||
|
||||
feature -- Converter
|
||||
|
||||
html_encoded_string (s: READABLE_STRING_32): READABLE_STRING_8
|
||||
html_encoded_string (s: READABLE_STRING_GENERAL): READABLE_STRING_8
|
||||
do
|
||||
Result := html_encoder.encoded_string (s)
|
||||
Result := html_encoder.general_encoded_string (s)
|
||||
end
|
||||
|
||||
html_encoder: HTML_ENCODER
|
||||
|
||||
@@ -16,27 +16,27 @@ feature -- Access
|
||||
-- indicate that the form shouldn’t be validated when submitted.
|
||||
-- it's only applicable to input type=submit or image.
|
||||
|
||||
formaction: detachable READABLE_STRING_32
|
||||
formaction: detachable READABLE_STRING_8
|
||||
-- formaction specifies the file or application that will submit the form.
|
||||
-- It has the same effect as the action attribute on the form element and
|
||||
-- can only be used with a submit or image button (type="submit" or type="image").
|
||||
-- When the form is submitted, the browser first checks for a formaction attribute;
|
||||
-- if that isn’t present, it proceeds to look for an action attribute on the form.
|
||||
|
||||
formenctype: detachable READABLE_STRING_32
|
||||
formenctype: detachable READABLE_STRING_8
|
||||
-- formenctype details how the form data is encoded with the POST method type.
|
||||
-- It has the same effect as the enctype attribute on the form element and
|
||||
-- can only be used with a submit or image button (type="submit" or type="image").
|
||||
-- The default value if not included is application/x-www-formurlencoded.
|
||||
--! At the moment the value is not validated.
|
||||
|
||||
formmethod: detachable READABLE_STRING_32
|
||||
formmethod: detachable READABLE_STRING_8
|
||||
-- formmethod specifies which HTTP method (GET, POST, PUT, DELETE) will be used to submit the form data.
|
||||
-- It has the same effect as the method attribute on the form element and can only be used with a
|
||||
-- submit or image button (type="submit" or type="image").
|
||||
--!At the moment the value is not validated.
|
||||
|
||||
formtarget: detachable READABLE_STRING_32
|
||||
formtarget: detachable READABLE_STRING_8
|
||||
-- formtarget specifies the target window for the form results.
|
||||
-- It has the same effect as the target attribute on the form element and can only be used with a submit or image button (type="submit" or type="image").
|
||||
|
||||
@@ -60,39 +60,47 @@ feature -- Element Change
|
||||
formnovalidate_false: not formnovalidate
|
||||
end
|
||||
|
||||
set_formaction (a_action: READABLE_STRING_32)
|
||||
set_formaction (a_action: READABLE_STRING_GENERAL)
|
||||
-- Set `formaction' with `a_action'.
|
||||
-- Example:<input type="submit" value="Submit" formaction="/users">
|
||||
require
|
||||
is_valid_as_string_8: a_action.is_valid_as_string_8
|
||||
do
|
||||
formaction := a_action
|
||||
formaction := a_action.to_string_8
|
||||
ensure
|
||||
formaction_set: attached formaction as l_action implies l_action = a_action
|
||||
end
|
||||
|
||||
set_formenctype (a_enctype: READABLE_STRING_32)
|
||||
set_formenctype (a_enctype: READABLE_STRING_GENERAL)
|
||||
-- Set `formenctype' with `a_enctype'.
|
||||
-- Example: <input type="submit" value="Submit" formenctype="application/x-www-form-urlencoded">
|
||||
require
|
||||
is_valid_as_string_8: a_enctype.is_valid_as_string_8
|
||||
do
|
||||
formenctype := a_enctype
|
||||
formenctype := a_enctype.to_string_8
|
||||
ensure
|
||||
formenctype_set: attached formenctype as l_enctype implies l_enctype = a_enctype
|
||||
end
|
||||
|
||||
set_formmethod (a_method: READABLE_STRING_32)
|
||||
set_formmethod (a_method: READABLE_STRING_GENERAL)
|
||||
-- Set `formmethod' with `a_method'.
|
||||
-- Example: <input type="submit" value="Submit" formmethod="POST">
|
||||
--! require is_valid_method: [PUT, POST, DELETE, GET, ...]
|
||||
require
|
||||
is_valid_as_string_8: a_method.is_valid_as_string_8
|
||||
do
|
||||
formmethod := a_method
|
||||
formmethod := a_method.to_string_8
|
||||
ensure
|
||||
formmethod_set: attached formmethod as l_method implies l_method = a_method
|
||||
end
|
||||
|
||||
set_formtarget (a_target: READABLE_STRING_32)
|
||||
set_formtarget (a_target: READABLE_STRING_GENERAL)
|
||||
-- Set `formtarget' with `a_target'.
|
||||
-- Example: <input type="submit" value="Submit" formtarget="_self">
|
||||
require
|
||||
is_valid_as_string_8: a_target.is_valid_as_string_8
|
||||
do
|
||||
formtarget := a_target
|
||||
formtarget := a_target.to_string_8
|
||||
ensure
|
||||
formtarget_set: attached formtarget as l_target implies l_target = a_target
|
||||
end
|
||||
|
||||
@@ -184,7 +184,7 @@ feature -- Change
|
||||
end
|
||||
|
||||
extend_text (t: READABLE_STRING_8)
|
||||
obsolete "Use extend_html_text (..) 2013-Sept-06"
|
||||
obsolete "Use extend_html_text (..) [2017-05-31]"
|
||||
do
|
||||
extend_html_text (t)
|
||||
end
|
||||
|
||||
@@ -111,9 +111,9 @@ feature -- Execution
|
||||
i := l_raw_header.substring_index ("%R%N", 1)
|
||||
if i > 0 then
|
||||
-- Skip the first status line.
|
||||
create h.make_from_raw_header_data (l_raw_header.substring (i + 2, l_raw_header.count))
|
||||
create h.make_from_raw_header_data (l_raw_header.substring (i + 2, l_raw_header.count).as_string_8_conversion) -- NOTE: it is string 8 per nature.
|
||||
else
|
||||
create h.make_from_raw_header_data (l_raw_header)
|
||||
create h.make_from_raw_header_data (l_raw_header.as_string_8_conversion)
|
||||
end
|
||||
if attached l_remote_uri.host as l_remote_host then
|
||||
if l_remote_uri.port > 0 then
|
||||
|
||||
47
library/text/encoder/src/x_www_form_url_encoder.e
Normal file
47
library/text/encoder/src/x_www_form_url_encoder.e
Normal file
@@ -0,0 +1,47 @@
|
||||
note
|
||||
description: "Summary description for {X_WWW_FORM_URL_ENCODER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
X_WWW_FORM_URL_ENCODER
|
||||
|
||||
inherit
|
||||
URL_ENCODER
|
||||
redefine
|
||||
append_percent_encoded_ascii_character_code_to
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: character encoding
|
||||
|
||||
append_percent_encoded_ascii_character_code_to (a_code: NATURAL_32; a_result: STRING_GENERAL)
|
||||
-- <Precursor>
|
||||
-- Note: space is encoded with '+' for x-www-form-urlencoding.
|
||||
do
|
||||
inspect a_code
|
||||
when
|
||||
32 -- 32 ' '
|
||||
then
|
||||
a_result.append_code (43) -- 43 '+'
|
||||
when
|
||||
33, 39, -- ! '
|
||||
40, 41, 42 -- ( ) *
|
||||
then
|
||||
a_result.append_code (a_code) -- Keep slash
|
||||
else
|
||||
Precursor (a_code, a_result)
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 2011-2017, 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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user