Class renaming for content_negotiation
Splitted SERVER_CONTENT_NEGOTIATION in 4 differents classes for each kind of negotiation Changed to use ITERABLE over LIST for supported variants arguments Factorized some code for http parameter parsing such as q=1.0;note="blabla" and so on Integrated within EWF
This commit is contained in:
@@ -1,249 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {CONNEG_SERVER_SIDE}. Utility class to support Server Side Content Negotiation "
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
description: "[
|
|
||||||
Reference : http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12.1
|
|
||||||
Server-driven Negotiation : If the selection of the best representation for a response is made by an algorithm located at the server,
|
|
||||||
it is called server-driven negotiation. Selection is based on the available representations of the response (the dimensions over which it can vary; e.g. language, content-coding, etc.)
|
|
||||||
and the contents of particular header fields in the request message or on other information pertaining to the request (such as the network address of the client).
|
|
||||||
Server-driven negotiation is advantageous when the algorithm for selecting from among the available representations is difficult to describe to the user agent,
|
|
||||||
or when the server desires to send its "best guess" to the client along with the first response (hoping to avoid the round-trip delay of a subsequent request if the "best guess" is good enough for the user).
|
|
||||||
In order to improve the server's guess, the user agent MAY include request header fields (Accept, Accept-Language, Accept-Encoding, etc.) which describe its preferences for such a response.
|
|
||||||
]"
|
|
||||||
EIS: "name=server driven negotiation", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12.", "protocol=uri"
|
|
||||||
|
|
||||||
class
|
|
||||||
CONNEG_SERVER_SIDE
|
|
||||||
|
|
||||||
inherit
|
|
||||||
REFACTORING_HELPER
|
|
||||||
|
|
||||||
create
|
|
||||||
make
|
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
|
||||||
|
|
||||||
make (a_mediatype_dft: READABLE_STRING_8; a_language_dft: READABLE_STRING_8; a_charset_dft: READABLE_STRING_8; a_encoding_dft: READABLE_STRING_8)
|
|
||||||
-- Initialize Current with default Media type, language, charset and encoding.
|
|
||||||
do
|
|
||||||
initialize
|
|
||||||
set_default_media_type (a_mediatype_dft)
|
|
||||||
set_default_language (a_language_dft)
|
|
||||||
set_default_charset (a_charset_dft)
|
|
||||||
set_default_encoding (a_encoding_dft)
|
|
||||||
ensure
|
|
||||||
default_media_type_set: default_media_type = a_mediatype_dft
|
|
||||||
default_language_set: default_language = a_language_dft
|
|
||||||
default_charset_set: default_charset = a_charset_dft
|
|
||||||
default_encoding_set: default_encoding = a_encoding_dft
|
|
||||||
end
|
|
||||||
|
|
||||||
initialize
|
|
||||||
-- Initialize Current
|
|
||||||
do
|
|
||||||
create accept_media_type_parser
|
|
||||||
create any_header_parser
|
|
||||||
create accept_language_parser
|
|
||||||
end
|
|
||||||
|
|
||||||
accept_media_type_parser: HTTP_ACCEPT_MEDIA_TYPE_PARSER
|
|
||||||
-- MIME
|
|
||||||
|
|
||||||
any_header_parser: HTTP_ANY_ACCEPT_HEADER_PARSER
|
|
||||||
-- Charset and Encoding
|
|
||||||
|
|
||||||
accept_language_parser: HTTP_ACCEPT_LANGUAGE_PARSER
|
|
||||||
-- Language
|
|
||||||
|
|
||||||
feature -- Access: Server Side Defaults Formats
|
|
||||||
|
|
||||||
default_media_type: READABLE_STRING_8
|
|
||||||
-- Media type which is acceptable for the response.
|
|
||||||
|
|
||||||
default_language: READABLE_STRING_8
|
|
||||||
-- Natural language that is preferred as a response to the request.
|
|
||||||
|
|
||||||
default_charset: READABLE_STRING_8
|
|
||||||
-- Character set that is acceptable for the response.
|
|
||||||
|
|
||||||
default_encoding: READABLE_STRING_8
|
|
||||||
-- Content-coding that is acceptable in the response.
|
|
||||||
|
|
||||||
feature -- Change Element
|
|
||||||
|
|
||||||
set_default_media_type (a_mediatype: READABLE_STRING_8)
|
|
||||||
-- Set `default_media_type' with `a_mediatype'
|
|
||||||
do
|
|
||||||
default_media_type := a_mediatype
|
|
||||||
ensure
|
|
||||||
default_media_type_set: a_mediatype = default_media_type
|
|
||||||
end
|
|
||||||
|
|
||||||
set_default_language (a_language: READABLE_STRING_8)
|
|
||||||
-- Set `default_language' with `a_language'
|
|
||||||
do
|
|
||||||
default_language := a_language
|
|
||||||
ensure
|
|
||||||
default_language_set: a_language = default_language
|
|
||||||
end
|
|
||||||
|
|
||||||
set_default_charset (a_charset: READABLE_STRING_8)
|
|
||||||
-- Set `default_charset' with `a_charset'
|
|
||||||
do
|
|
||||||
default_charset := a_charset
|
|
||||||
ensure
|
|
||||||
default_charset_set: a_charset = default_charset
|
|
||||||
end
|
|
||||||
|
|
||||||
set_default_encoding (a_encoding: READABLE_STRING_8)
|
|
||||||
-- Set `default_encoding' with `a_encoding'
|
|
||||||
do
|
|
||||||
default_encoding := a_encoding
|
|
||||||
ensure
|
|
||||||
default_encoding_set: a_encoding = default_encoding
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Media Type Negotiation
|
|
||||||
|
|
||||||
media_type_preference (a_mime_types_supported: LIST [READABLE_STRING_8]; a_header: detachable READABLE_STRING_8): HTTP_ACCEPT_MEDIA_TYPE_VARIANTS
|
|
||||||
-- `a_mime_types_supported' represent media types supported by the server.
|
|
||||||
-- `a_header represent' the Accept header, ie, the client preferences.
|
|
||||||
-- Return which media type to use for representation in a response, if the server supports
|
|
||||||
-- the requested media type, or empty in other case.
|
|
||||||
note
|
|
||||||
EIS: "name=media type", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1", "protocol=uri"
|
|
||||||
local
|
|
||||||
l_mime_match: READABLE_STRING_8
|
|
||||||
do
|
|
||||||
create Result.make
|
|
||||||
Result.set_supported_variants (a_mime_types_supported)
|
|
||||||
if a_header = Void or else a_header.is_empty then
|
|
||||||
-- the request has no Accept header, ie the header is empty, in this case we use the default format
|
|
||||||
Result.set_acceptable (True)
|
|
||||||
Result.set_variant_value (default_media_type)
|
|
||||||
else
|
|
||||||
Result.set_vary_header_value
|
|
||||||
|
|
||||||
-- select the best match, server support, client preferences
|
|
||||||
l_mime_match := accept_media_type_parser.best_match (a_mime_types_supported, a_header)
|
|
||||||
if l_mime_match.is_empty then
|
|
||||||
-- The server does not support any of the media types preferred by the client
|
|
||||||
Result.set_acceptable (False)
|
|
||||||
else
|
|
||||||
-- Set the best match
|
|
||||||
Result.set_variant_value (l_mime_match)
|
|
||||||
Result.set_acceptable (True)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Encoding Negotiation
|
|
||||||
|
|
||||||
charset_preference (a_server_charset_supported: LIST [READABLE_STRING_8]; a_header: detachable READABLE_STRING_8): HTTP_ACCEPT_CHARSET_VARIANTS
|
|
||||||
-- `a_server_charset_supported' represent a list of character sets supported by the server.
|
|
||||||
-- `a_header' represents the Accept-Charset header, ie, the client preferences.
|
|
||||||
-- Return which Charset to use in a response, if the server supports
|
|
||||||
-- the requested Charset, or empty in other case.
|
|
||||||
note
|
|
||||||
EIS: "name=charset", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.2", "protocol=uri"
|
|
||||||
local
|
|
||||||
l_charset_match: READABLE_STRING_8
|
|
||||||
do
|
|
||||||
create Result.make
|
|
||||||
Result.set_supported_variants (a_server_charset_supported)
|
|
||||||
if a_header = Void or else a_header.is_empty then
|
|
||||||
-- the request has no Accept-Charset header, ie the header is empty, in this case use default charset encoding
|
|
||||||
Result.set_acceptable (True)
|
|
||||||
Result.set_variant_value (default_charset)
|
|
||||||
else
|
|
||||||
Result.set_vary_header_value
|
|
||||||
|
|
||||||
-- select the best match, server support, client preferences
|
|
||||||
l_charset_match := any_header_parser.best_match (a_server_charset_supported, a_header)
|
|
||||||
if l_charset_match.is_empty then
|
|
||||||
-- The server does not support any of the compression types prefered by the client
|
|
||||||
Result.set_acceptable (False)
|
|
||||||
else
|
|
||||||
-- Set the best match
|
|
||||||
Result.set_variant_value (l_charset_match)
|
|
||||||
Result.set_acceptable (True)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Compression Negotiation
|
|
||||||
|
|
||||||
encoding_preference (a_server_encoding_supported: LIST [READABLE_STRING_8]; a_header_value: detachable READABLE_STRING_8): HTTP_ACCEPT_ENCODING_VARIANTS
|
|
||||||
-- `a_server_encoding_supported' represent a list of encoding supported by the server.
|
|
||||||
-- `a_header_value' represent the Accept-Encoding header, ie, the client preferences.
|
|
||||||
-- Return which Encoding to use in a response, if the server supports
|
|
||||||
-- the requested Encoding, or empty in other case.
|
|
||||||
note
|
|
||||||
EIS: "name=encoding", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3", "protocol=uri"
|
|
||||||
local
|
|
||||||
l_compression_match: READABLE_STRING_8
|
|
||||||
do
|
|
||||||
create Result.make
|
|
||||||
Result.set_supported_variants (a_server_encoding_supported)
|
|
||||||
if a_header_value = Void or else a_header_value.is_empty then
|
|
||||||
-- the request has no Accept-Encoding header, ie the header is empty, in this case do not compress representations
|
|
||||||
Result.set_acceptable (True)
|
|
||||||
Result.set_variant_value (default_encoding)
|
|
||||||
else
|
|
||||||
Result.set_vary_header_value
|
|
||||||
|
|
||||||
-- select the best match, server support, client preferences
|
|
||||||
l_compression_match := any_header_parser.best_match (a_server_encoding_supported, a_header_value)
|
|
||||||
if l_compression_match.is_empty then
|
|
||||||
-- The server does not support any of the compression types prefered by the client
|
|
||||||
Result.set_acceptable (False)
|
|
||||||
else
|
|
||||||
-- Set the best match
|
|
||||||
Result.set_variant_value (l_compression_match)
|
|
||||||
Result.set_acceptable (True)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Language Negotiation
|
|
||||||
|
|
||||||
language_preference (a_server_language_supported: LIST [READABLE_STRING_8]; a_header_value: detachable READABLE_STRING_8): HTTP_ACCEPT_LANGUAGE_VARIANTS
|
|
||||||
-- `a_server_language_supported' represent a list of languages supported by the server.
|
|
||||||
-- `a_header_value' represent the Accept-Language header, ie, the client preferences.
|
|
||||||
-- Return which Language to use in a response, if the server supports
|
|
||||||
-- the requested Language, or empty in other case.
|
|
||||||
note
|
|
||||||
EIS: "name=language", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4", "protocol=uri"
|
|
||||||
|
|
||||||
local
|
|
||||||
l_language_match: READABLE_STRING_8
|
|
||||||
do
|
|
||||||
create Result.make
|
|
||||||
Result.set_supported_variants (a_server_language_supported)
|
|
||||||
|
|
||||||
if a_header_value = Void or else a_header_value.is_empty then
|
|
||||||
-- the request has no Accept header, ie the header is empty, in this case we use the default format
|
|
||||||
Result.set_acceptable (True)
|
|
||||||
Result.set_variant_value (default_language)
|
|
||||||
else
|
|
||||||
Result.set_vary_header_value
|
|
||||||
|
|
||||||
-- select the best match, server support, client preferences
|
|
||||||
l_language_match := accept_language_parser.best_match (a_server_language_supported, a_header_value)
|
|
||||||
if l_language_match.is_empty then
|
|
||||||
-- The server does not support any of the media types prefered by the client
|
|
||||||
Result.set_acceptable (False)
|
|
||||||
else
|
|
||||||
-- Set the best match
|
|
||||||
Result.set_variant_value (l_language_match)
|
|
||||||
Result.set_acceptable (True)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
note
|
|
||||||
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
note
|
note
|
||||||
description: "[
|
description: "[
|
||||||
{HTTP_ACCEPT_LANGUAGE_PARSER} is encharge to parse language tags defined as follow:
|
{HTTP_ACCEPT_LANGUAGE_UTILITIES} is in charge to parse language tags defined as follow:
|
||||||
|
|
||||||
Accept-Language = "Accept-Language" ":"
|
Accept-Language = "Accept-Language" ":"
|
||||||
1#( language-l_range [ ";" "q" "=" qvalue ] )
|
1#( language-l_range [ ";" "q" "=" qvalue ] )
|
||||||
@@ -15,13 +15,10 @@ note
|
|||||||
EIS: "name=Accept-Language", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4", "protocol=uri"
|
EIS: "name=Accept-Language", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4", "protocol=uri"
|
||||||
|
|
||||||
class
|
class
|
||||||
HTTP_ACCEPT_LANGUAGE_PARSER
|
HTTP_ACCEPT_LANGUAGE_UTILITIES
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
|
HTTP_HEADER_UTILITIES
|
||||||
HTTP_HEADER_PARSER
|
|
||||||
|
|
||||||
REFACTORING_HELPER
|
|
||||||
|
|
||||||
feature -- Parser
|
feature -- Parser
|
||||||
|
|
||||||
@@ -68,29 +65,22 @@ feature -- Parser
|
|||||||
Result := quality_from_list (a_language, accept_language_list (a_ranges))
|
Result := quality_from_list (a_language, accept_language_list (a_ranges))
|
||||||
end
|
end
|
||||||
|
|
||||||
best_match (a_supported: LIST [READABLE_STRING_8]; a_header_value: READABLE_STRING_8): READABLE_STRING_8
|
best_match (a_supported: ITERABLE [READABLE_STRING_8]; a_header_value: READABLE_STRING_8): READABLE_STRING_8
|
||||||
-- Choose the `parse_language' with the highest fitness score and quality ('q') from a list of candidates.
|
-- Choose the `parse_language' with the highest fitness score and quality ('q') from a list of candidates.
|
||||||
local
|
local
|
||||||
l_header_results: LIST [HTTP_ACCEPT_LANGUAGE]
|
l_header_results: LIST [HTTP_ACCEPT_LANGUAGE]
|
||||||
l_weighted_matches: LIST [FITNESS_AND_QUALITY]
|
l_weighted_matches: LIST [FITNESS_AND_QUALITY]
|
||||||
l_res: LIST [READABLE_STRING_8]
|
|
||||||
p_res: HTTP_ACCEPT_LANGUAGE
|
|
||||||
l_fitness_and_quality, l_first_one: detachable FITNESS_AND_QUALITY
|
l_fitness_and_quality, l_first_one: detachable FITNESS_AND_QUALITY
|
||||||
s: READABLE_STRING_8
|
s: READABLE_STRING_8
|
||||||
do
|
do
|
||||||
l_header_results := accept_language_list (a_header_value)
|
l_header_results := accept_language_list (a_header_value)
|
||||||
|
|
||||||
--| weighted matches
|
--| weighted matches
|
||||||
create {ARRAYED_LIST [FITNESS_AND_QUALITY]} l_weighted_matches.make (a_supported.count)
|
create {ARRAYED_LIST [FITNESS_AND_QUALITY]} l_weighted_matches.make (0)
|
||||||
from
|
across a_supported as ic loop
|
||||||
a_supported.start
|
l_fitness_and_quality := fitness_and_quality_from_list (ic.item, l_header_results)
|
||||||
until
|
l_fitness_and_quality.set_entity (entity_value (ic.item))
|
||||||
a_supported.after
|
|
||||||
loop
|
|
||||||
l_fitness_and_quality := fitness_and_quality_from_list (a_supported.item_for_iteration, l_header_results)
|
|
||||||
l_fitness_and_quality.set_entity (entity_value (a_supported.item_for_iteration))
|
|
||||||
l_weighted_matches.force (l_fitness_and_quality)
|
l_weighted_matches.force (l_fitness_and_quality)
|
||||||
a_supported.forth
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--| Keep only top quality+fitness types
|
--| Keep only top quality+fitness types
|
||||||
@@ -177,7 +167,6 @@ feature {NONE} -- Implementation
|
|||||||
l_target: HTTP_ACCEPT_LANGUAGE
|
l_target: HTTP_ACCEPT_LANGUAGE
|
||||||
l_target_type: READABLE_STRING_8
|
l_target_type: READABLE_STRING_8
|
||||||
l_range: HTTP_ACCEPT_LANGUAGE
|
l_range: HTTP_ACCEPT_LANGUAGE
|
||||||
l_keys: LIST [READABLE_STRING_8]
|
|
||||||
l_param_matches: INTEGER
|
l_param_matches: INTEGER
|
||||||
l_element: detachable READABLE_STRING_8
|
l_element: detachable READABLE_STRING_8
|
||||||
l_fitness: INTEGER
|
l_fitness: INTEGER
|
||||||
@@ -201,23 +190,21 @@ feature {NONE} -- Implementation
|
|||||||
or l_target_type.same_string ("*")
|
or l_target_type.same_string ("*")
|
||||||
)
|
)
|
||||||
then
|
then
|
||||||
from
|
l_param_matches := 0
|
||||||
l_param_matches := 0
|
if attached l_target.parameters as l_target_parameters then
|
||||||
l_keys := l_target.keys
|
across
|
||||||
l_keys.start
|
l_target_parameters as ic
|
||||||
until
|
loop
|
||||||
l_keys.after
|
l_element := ic.key
|
||||||
loop
|
if
|
||||||
l_element := l_keys.item_for_iteration
|
not l_element.same_string ("q") and then
|
||||||
if
|
l_range.has_parameter (l_element) and then
|
||||||
not l_element.same_string ("q") and then
|
(attached ic.item as t_item and attached l_range.parameter (l_element) as r_item) and then
|
||||||
l_range.has_key (l_element) and then
|
t_item.same_string (r_item)
|
||||||
(attached l_target.item (l_element) as t_item and attached l_range.item (l_element) as r_item) and then
|
then
|
||||||
t_item.same_string (r_item)
|
l_param_matches := l_param_matches + 1
|
||||||
then
|
end
|
||||||
l_param_matches := l_param_matches + 1
|
|
||||||
end
|
end
|
||||||
l_keys.forth
|
|
||||||
end
|
end
|
||||||
if l_range_type.same_string (l_target_type) then
|
if l_range_type.same_string (l_target_type) then
|
||||||
l_fitness := 100
|
l_fitness := 100
|
||||||
@@ -239,7 +226,7 @@ feature {NONE} -- Implementation
|
|||||||
l_fitness := l_fitness + l_param_matches
|
l_fitness := l_fitness + l_param_matches
|
||||||
if l_fitness > l_best_fitness then
|
if l_fitness > l_best_fitness then
|
||||||
l_best_fitness := l_fitness
|
l_best_fitness := l_fitness
|
||||||
l_element := l_range.item ("q")
|
l_element := l_range.parameter ("q")
|
||||||
if l_element /= Void then
|
if l_element /= Void then
|
||||||
l_best_fit_q := l_element.to_real_64.min (l_target_q)
|
l_best_fit_q := l_element.to_real_64.min (l_target_q)
|
||||||
else
|
else
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
note
|
note
|
||||||
description: "[
|
description: "[
|
||||||
{HTTP_ACCEPT_MEDIA_TYPE_PARSER}. is encharge to parse Accept request-header field defined as follow:
|
{HTTP_ACCEPT_MEDIA_TYPE_UTILITIES}. is encharge to parse Accept request-header field defined as follow:
|
||||||
|
|
||||||
Accept = "Accept" ":"
|
Accept = "Accept" ":"
|
||||||
#( media-range [ accept-params ] )
|
#( media-range [ accept-params ] )
|
||||||
@@ -20,13 +20,10 @@
|
|||||||
EIS: "name=Accept", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1", "protocol=uri"
|
EIS: "name=Accept", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1", "protocol=uri"
|
||||||
|
|
||||||
class
|
class
|
||||||
HTTP_ACCEPT_MEDIA_TYPE_PARSER
|
HTTP_ACCEPT_MEDIA_TYPE_UTILITIES
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
|
HTTP_HEADER_UTILITIES
|
||||||
HTTP_HEADER_PARSER
|
|
||||||
|
|
||||||
REFACTORING_HELPER
|
|
||||||
|
|
||||||
feature -- Parser
|
feature -- Parser
|
||||||
|
|
||||||
@@ -81,7 +78,7 @@ feature -- Parser
|
|||||||
Result := quality_from_list (a_mime_type, res)
|
Result := quality_from_list (a_mime_type, res)
|
||||||
end
|
end
|
||||||
|
|
||||||
best_match (supported: LIST [READABLE_STRING_8]; header: READABLE_STRING_8): READABLE_STRING_8
|
best_match (supported: ITERABLE [READABLE_STRING_8]; header: READABLE_STRING_8): READABLE_STRING_8
|
||||||
-- Choose the mime-type with the highest fitness score and quality ('q') from a list of candidates.
|
-- Choose the mime-type with the highest fitness score and quality ('q') from a list of candidates.
|
||||||
local
|
local
|
||||||
l_header_results: LIST [HTTP_MEDIA_TYPE]
|
l_header_results: LIST [HTTP_MEDIA_TYPE]
|
||||||
@@ -105,17 +102,12 @@ feature -- Parser
|
|||||||
l_res.forth
|
l_res.forth
|
||||||
end
|
end
|
||||||
|
|
||||||
create {ARRAYED_LIST [FITNESS_AND_QUALITY]} weighted_matches.make (supported.count)
|
create {ARRAYED_LIST [FITNESS_AND_QUALITY]} weighted_matches.make (0)
|
||||||
|
|
||||||
from
|
across supported as ic loop
|
||||||
supported.start
|
fitness_and_quality := fitness_and_quality_from_list (ic.item, l_header_results)
|
||||||
until
|
fitness_and_quality.set_entity (entity_value (ic.item))
|
||||||
supported.after
|
|
||||||
loop
|
|
||||||
fitness_and_quality := fitness_and_quality_from_list (supported.item_for_iteration, l_header_results)
|
|
||||||
fitness_and_quality.set_entity (entity_value (supported.item_for_iteration))
|
|
||||||
weighted_matches.force (fitness_and_quality)
|
weighted_matches.force (fitness_and_quality)
|
||||||
supported.forth
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--| Keep only top quality+fitness types
|
--| Keep only top quality+fitness types
|
||||||
@@ -236,13 +228,9 @@ feature {NONE} -- Implementation
|
|||||||
)
|
)
|
||||||
then
|
then
|
||||||
if attached target.parameters as l_keys then
|
if attached target.parameters as l_keys then
|
||||||
from
|
param_matches := 0
|
||||||
param_matches := 0
|
across l_keys as ic loop
|
||||||
l_keys.start
|
element := ic.key
|
||||||
until
|
|
||||||
l_keys.after
|
|
||||||
loop
|
|
||||||
element := l_keys.key_for_iteration
|
|
||||||
if
|
if
|
||||||
not element.same_string ("q") and then
|
not element.same_string ("q") and then
|
||||||
range.has_parameter (element) and then
|
range.has_parameter (element) and then
|
||||||
@@ -251,7 +239,6 @@ feature {NONE} -- Implementation
|
|||||||
then
|
then
|
||||||
param_matches := param_matches + 1
|
param_matches := param_matches + 1
|
||||||
end
|
end
|
||||||
l_keys.forth
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if l_range_type.same_string (l_target_type) then
|
if l_range_type.same_string (l_target_type) then
|
||||||
@@ -9,56 +9,34 @@ note
|
|||||||
EIS: "name=Encoding", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3", "protocol=uri"
|
EIS: "name=Encoding", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3", "protocol=uri"
|
||||||
|
|
||||||
class
|
class
|
||||||
HTTP_ANY_ACCEPT_HEADER_PARSER
|
HTTP_ANY_ACCEPT_HEADER_UTILITIES
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
HTTP_HEADER_PARSER
|
HTTP_HEADER_UTILITIES
|
||||||
|
|
||||||
feature -- Parser
|
feature -- Parser
|
||||||
|
|
||||||
header (a_header: READABLE_STRING_8): HTTP_ANY_ACCEPT_HEADER
|
header (a_header: READABLE_STRING_8): HTTP_ANY_ACCEPT
|
||||||
-- Parses `a_header' charset/encoding into its component parts.
|
-- Parses `a_header' charset/encoding into its component parts.
|
||||||
-- For example, the charset 'iso-8889-5' would get parsed
|
-- For example, the charset 'iso-8889-5' would get parsed
|
||||||
-- into:
|
-- into:
|
||||||
-- ('iso-8889-5', {'q':'1.0'})
|
-- ('iso-8889-5', {'q':'1.0'})
|
||||||
local
|
|
||||||
l_parts: LIST [READABLE_STRING_8]
|
|
||||||
sub_parts: LIST [READABLE_STRING_8]
|
|
||||||
p: READABLE_STRING_8
|
|
||||||
i: INTEGER
|
|
||||||
l_header: READABLE_STRING_8
|
|
||||||
do
|
do
|
||||||
create Result.make
|
create Result.make_from_string (a_header)
|
||||||
l_parts := a_header.split (';')
|
if Result.parameter ("q") = Void then
|
||||||
if l_parts.count = 1 then
|
Result.put_parameter ("1.0", "q")
|
||||||
Result.put ("1.0", "q")
|
|
||||||
else
|
|
||||||
from
|
|
||||||
i := 1
|
|
||||||
until
|
|
||||||
i > l_parts.count
|
|
||||||
loop
|
|
||||||
p := l_parts [i]
|
|
||||||
sub_parts := p.split ('=')
|
|
||||||
if sub_parts.count = 2 then
|
|
||||||
Result.put (trim (sub_parts [2]), trim (sub_parts [1]))
|
|
||||||
end
|
|
||||||
i := i + 1
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
l_header := trim (l_parts [1])
|
|
||||||
Result.set_field (trim (l_header))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
quality (a_field: READABLE_STRING_8; a_commons: READABLE_STRING_8): REAL_64
|
quality (a_field: READABLE_STRING_8; a_header: READABLE_STRING_8): REAL_64
|
||||||
-- Returns the quality 'q' of a charset/encoding when compared against the
|
-- Returns the quality 'q' of a charset/encoding when compared against the
|
||||||
-- a list of charsets/encodings/
|
-- a list of charsets/encodings/
|
||||||
local
|
local
|
||||||
l_commons: LIST [READABLE_STRING_8]
|
l_commons: LIST [READABLE_STRING_8]
|
||||||
res: ARRAYED_LIST [HTTP_ANY_ACCEPT_HEADER]
|
res: ARRAYED_LIST [HTTP_ANY_ACCEPT]
|
||||||
p_res: HTTP_ANY_ACCEPT_HEADER
|
p_res: HTTP_ANY_ACCEPT
|
||||||
do
|
do
|
||||||
l_commons := a_commons.split (',')
|
l_commons := a_header.split (',')
|
||||||
from
|
from
|
||||||
create res.make (10)
|
create res.make (10)
|
||||||
l_commons.start
|
l_commons.start
|
||||||
@@ -72,17 +50,17 @@ feature -- Parser
|
|||||||
Result := quality_from_list (a_field, res)
|
Result := quality_from_list (a_field, res)
|
||||||
end
|
end
|
||||||
|
|
||||||
best_match (a_supported: LIST [READABLE_STRING_8]; a_header: READABLE_STRING_8): READABLE_STRING_8
|
best_match (a_supported: ITERABLE [READABLE_STRING_8]; a_header: READABLE_STRING_8): READABLE_STRING_8
|
||||||
-- Choose the accept with the highest fitness score and quality ('q') from a list of candidates.
|
-- Choose the accept with the highest fitness score and quality ('q') from a list of candidates.
|
||||||
local
|
local
|
||||||
l_header_results: LIST [HTTP_ANY_ACCEPT_HEADER]
|
l_header_results: LIST [HTTP_ANY_ACCEPT]
|
||||||
l_weighted_matches: LIST [FITNESS_AND_QUALITY]
|
l_weighted_matches: LIST [FITNESS_AND_QUALITY]
|
||||||
l_res: LIST [READABLE_STRING_8]
|
l_res: LIST [READABLE_STRING_8]
|
||||||
p_res: HTTP_ANY_ACCEPT_HEADER
|
p_res: HTTP_ANY_ACCEPT
|
||||||
l_fitness_and_quality, l_first_one: detachable FITNESS_AND_QUALITY
|
l_fitness_and_quality, l_first_one: detachable FITNESS_AND_QUALITY
|
||||||
do
|
do
|
||||||
l_res := a_header.split (',')
|
l_res := a_header.split (',')
|
||||||
create {ARRAYED_LIST [HTTP_ANY_ACCEPT_HEADER]} l_header_results.make (l_res.count)
|
create {ARRAYED_LIST [HTTP_ANY_ACCEPT]} l_header_results.make (l_res.count)
|
||||||
from
|
from
|
||||||
l_res.start
|
l_res.start
|
||||||
until
|
until
|
||||||
@@ -92,16 +70,11 @@ feature -- Parser
|
|||||||
l_header_results.force (p_res)
|
l_header_results.force (p_res)
|
||||||
l_res.forth
|
l_res.forth
|
||||||
end
|
end
|
||||||
create {ARRAYED_LIST [FITNESS_AND_QUALITY]} l_weighted_matches.make (a_supported.count)
|
create {ARRAYED_LIST [FITNESS_AND_QUALITY]} l_weighted_matches.make (0)
|
||||||
from
|
across a_supported as ic loop
|
||||||
a_supported.start
|
l_fitness_and_quality := fitness_and_quality_from_list (ic.item, l_header_results)
|
||||||
until
|
l_fitness_and_quality.set_entity (entity_value (ic.item))
|
||||||
a_supported.after
|
|
||||||
loop
|
|
||||||
l_fitness_and_quality := fitness_and_quality_from_list (a_supported.item_for_iteration, l_header_results)
|
|
||||||
l_fitness_and_quality.set_entity (entity_value (a_supported.item_for_iteration))
|
|
||||||
l_weighted_matches.force (l_fitness_and_quality)
|
l_weighted_matches.force (l_fitness_and_quality)
|
||||||
a_supported.forth
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--| Keep only top quality+fitness types
|
--| Keep only top quality+fitness types
|
||||||
@@ -150,7 +123,7 @@ feature -- Parser
|
|||||||
until
|
until
|
||||||
l_header_results.after or l_fitness_and_quality /= Void
|
l_header_results.after or l_fitness_and_quality /= Void
|
||||||
loop
|
loop
|
||||||
if attached l_header_results.item.field as l_field then
|
if attached l_header_results.item.value as l_field then
|
||||||
from
|
from
|
||||||
l_weighted_matches.start
|
l_weighted_matches.start
|
||||||
until
|
until
|
||||||
@@ -184,7 +157,7 @@ feature -- Parser
|
|||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
fitness_and_quality_from_list (a_field: READABLE_STRING_8; a_parsed_charsets: LIST [HTTP_ANY_ACCEPT_HEADER]): FITNESS_AND_QUALITY
|
fitness_and_quality_from_list (a_field: READABLE_STRING_8; a_parsed_charsets: LIST [HTTP_ANY_ACCEPT]): FITNESS_AND_QUALITY
|
||||||
-- Find the best match for a given charset/encoding against a list of charsets/encodings
|
-- Find the best match for a given charset/encoding against a list of charsets/encodings
|
||||||
-- that have already been parsed by parse_common. Returns a
|
-- that have already been parsed by parse_common. Returns a
|
||||||
-- tuple of the fitness value and the value of the 'q' quality parameter of
|
-- tuple of the fitness value and the value of the 'q' quality parameter of
|
||||||
@@ -194,15 +167,15 @@ feature {NONE} -- Implementation
|
|||||||
best_fitness: INTEGER
|
best_fitness: INTEGER
|
||||||
target_q: REAL_64
|
target_q: REAL_64
|
||||||
best_fit_q: REAL_64
|
best_fit_q: REAL_64
|
||||||
target: HTTP_ANY_ACCEPT_HEADER
|
target: HTTP_ANY_ACCEPT
|
||||||
range: HTTP_ANY_ACCEPT_HEADER
|
range: HTTP_ANY_ACCEPT
|
||||||
element: detachable READABLE_STRING_8
|
element: detachable READABLE_STRING_8
|
||||||
l_fitness: INTEGER
|
l_fitness: INTEGER
|
||||||
do
|
do
|
||||||
best_fitness := -1
|
best_fitness := -1
|
||||||
best_fit_q := 0.0
|
best_fit_q := 0.0
|
||||||
target := header (a_field)
|
target := header (a_field)
|
||||||
if attached target.item ("q") as q and then q.is_double then
|
if attached target.parameter ("q") as q and then q.is_double then
|
||||||
target_q := q.to_double
|
target_q := q.to_double
|
||||||
if target_q < 0.0 then
|
if target_q < 0.0 then
|
||||||
target_q := 0.0
|
target_q := 0.0
|
||||||
@@ -212,14 +185,14 @@ feature {NONE} -- Implementation
|
|||||||
else
|
else
|
||||||
target_q := 1.0
|
target_q := 1.0
|
||||||
end
|
end
|
||||||
if attached target.field as l_target_field then
|
if attached target.value as l_target_field then
|
||||||
from
|
from
|
||||||
a_parsed_charsets.start
|
a_parsed_charsets.start
|
||||||
until
|
until
|
||||||
a_parsed_charsets.after
|
a_parsed_charsets.after
|
||||||
loop
|
loop
|
||||||
range := a_parsed_charsets.item_for_iteration
|
range := a_parsed_charsets.item_for_iteration
|
||||||
if attached range.field as l_range_common then
|
if attached range.value as l_range_common then
|
||||||
if l_target_field.same_string (l_range_common) or l_target_field.same_string ("*") or l_range_common.same_string ("*") then
|
if l_target_field.same_string (l_range_common) or l_target_field.same_string ("*") or l_range_common.same_string ("*") then
|
||||||
if l_range_common.same_string (l_target_field) then
|
if l_range_common.same_string (l_target_field) then
|
||||||
l_fitness := 100
|
l_fitness := 100
|
||||||
@@ -228,7 +201,7 @@ feature {NONE} -- Implementation
|
|||||||
end
|
end
|
||||||
if l_fitness > best_fitness then
|
if l_fitness > best_fitness then
|
||||||
best_fitness := l_fitness
|
best_fitness := l_fitness
|
||||||
element := range.item ("q")
|
element := range.parameter ("q")
|
||||||
if element /= Void then
|
if element /= Void then
|
||||||
best_fit_q := element.to_double.min (target_q)
|
best_fit_q := element.to_double.min (target_q)
|
||||||
else
|
else
|
||||||
@@ -243,7 +216,7 @@ feature {NONE} -- Implementation
|
|||||||
create Result.make (best_fitness, best_fit_q)
|
create Result.make (best_fitness, best_fit_q)
|
||||||
end
|
end
|
||||||
|
|
||||||
quality_from_list (a_field: READABLE_STRING_8; a_parsed_common: LIST [HTTP_ANY_ACCEPT_HEADER]): REAL_64
|
quality_from_list (a_field: READABLE_STRING_8; a_parsed_common: LIST [HTTP_ANY_ACCEPT]): REAL_64
|
||||||
-- Find the best match for a given charset/encoding against a list of charsets/encodings that
|
-- Find the best match for a given charset/encoding against a list of charsets/encodings that
|
||||||
-- have already been parsed by parse_charsets(). Returns the 'q' quality
|
-- have already been parsed by parse_charsets(). Returns the 'q' quality
|
||||||
-- parameter of the best match, 0 if no match was found. This function
|
-- parameter of the best match, 0 if no match was found. This function
|
||||||
@@ -252,7 +225,6 @@ feature {NONE} -- Implementation
|
|||||||
Result := fitness_and_quality_from_list (a_field, a_parsed_common).quality
|
Result := fitness_and_quality_from_list (a_field, a_parsed_common).quality
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {HTTP_HEADER_PARSER}."
|
description: "Summary description for {HTTP_HEADER_UTILITIES}."
|
||||||
author: ""
|
author: ""
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
HTTP_HEADER_PARSER
|
HTTP_HEADER_UTILITIES
|
||||||
|
|
||||||
|
inherit
|
||||||
|
REFACTORING_HELPER
|
||||||
|
|
||||||
feature {NONE} -- Helpers
|
feature {NONE} -- Helpers
|
||||||
|
|
||||||
@@ -16,13 +19,13 @@ feature {NONE} -- Helpers
|
|||||||
do
|
do
|
||||||
p := a_str.index_of (';', 1)
|
p := a_str.index_of (';', 1)
|
||||||
if p > 0 then
|
if p > 0 then
|
||||||
Result := trim (a_str.substring (1, p - 1))
|
Result := trimmed_string (a_str.substring (1, p - 1))
|
||||||
else
|
else
|
||||||
Result := trim (a_str.string)
|
Result := trimmed_string (a_str.string)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
trim (a_string: READABLE_STRING_8): STRING_8
|
trimmed_string (a_string: READABLE_STRING_8): STRING_8
|
||||||
-- trim whitespace from the beginning and end of a string
|
-- trim whitespace from the beginning and end of a string
|
||||||
-- `a_string'
|
-- `a_string'
|
||||||
require
|
require
|
||||||
@@ -28,74 +28,50 @@ feature {NONE} -- Initialization
|
|||||||
-- In addition this also guarantees that there is a value for 'q'
|
-- In addition this also guarantees that there is a value for 'q'
|
||||||
-- in the params dictionary, filling it in with a proper default if
|
-- in the params dictionary, filling it in with a proper default if
|
||||||
-- necessary.
|
-- necessary.
|
||||||
require
|
|
||||||
a_accept_language_item_not_empty: not a_accept_language_item.is_empty
|
|
||||||
local
|
local
|
||||||
l_parts: LIST [READABLE_STRING_8]
|
|
||||||
p: READABLE_STRING_8
|
|
||||||
i: INTEGER
|
i: INTEGER
|
||||||
l_tag: STRING_8
|
|
||||||
do
|
do
|
||||||
fixme (generator + ".make_from_string: improve code!!!")
|
fixme (generator + ".make_from_string: improve code!!!")
|
||||||
l_parts := a_accept_language_item.split (';')
|
i := a_accept_language_item.index_of (';', 1)
|
||||||
from
|
if i > 0 then
|
||||||
l_parts.start
|
make_with_language (trimmed_string (a_accept_language_item.substring (1, i - 1)))
|
||||||
make_with_language (trimmed_string (l_parts.item))
|
create parameters.make_from_substring (a_accept_language_item, i + 1, a_accept_language_item.count)
|
||||||
if not l_parts.after then
|
check attached parameters as l_params and then not l_params.has_error end
|
||||||
l_parts.forth
|
else
|
||||||
end
|
make_with_language (trimmed_string (a_accept_language_item))
|
||||||
until
|
|
||||||
l_parts.after
|
|
||||||
loop
|
|
||||||
p := l_parts.item
|
|
||||||
i := p.index_of ('=', 1)
|
|
||||||
if i > 0 then
|
|
||||||
put (trimmed_string (p.substring (i + 1, p.count)), trimmed_string (p.substring (1, i - 1)))
|
|
||||||
else
|
|
||||||
check is_well_formed_parameter: False end
|
|
||||||
end
|
|
||||||
l_parts.forth
|
|
||||||
end
|
end
|
||||||
|
|
||||||
check quality_initialized_to_1: quality = 1.0 end
|
check quality_initialized_to_1: quality = 1.0 end
|
||||||
|
|
||||||
-- Get quality from parameter if any, and format the value as expected.
|
-- Get quality from parameter if any, and format the value as expected.
|
||||||
if attached item ("q") as q then
|
if attached parameter ("q") as q then
|
||||||
if q.same_string ("1") then
|
if q.same_string ("1") then
|
||||||
--| Use 1.0 formatting
|
--| Use 1.0 formatting
|
||||||
put ("1.0", "q")
|
put_parameter ("1.0", "q")
|
||||||
elseif q.is_double and then attached q.to_real_64 as r then
|
elseif q.is_double and then attached q.to_real_64 as r then
|
||||||
if r <= 0.0 then
|
if r <= 0.0 then
|
||||||
quality := 0.0 --| Should it be 1.0 ?
|
quality := 0.0 --| Should it be 1.0 ?
|
||||||
|
put_parameter ("0.0", "q")
|
||||||
elseif r >= 1.0 then
|
elseif r >= 1.0 then
|
||||||
quality := 1.0
|
quality := 1.0
|
||||||
|
put_parameter ("1.0", "q")
|
||||||
else
|
else
|
||||||
quality := r
|
quality := r
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
put ("1.0", "q")
|
put_parameter ("1.0", "q")
|
||||||
quality := 1.0
|
quality := 1.0
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
put ("1.0", "q")
|
put_parameter ("1.0", "q")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
make_with_language (a_lang_tag: READABLE_STRING_8)
|
make_with_language (a_lang_tag: READABLE_STRING_8)
|
||||||
-- Instantiate Current from language tag `a_lang_tag'.
|
-- Instantiate Current from language tag `a_lang_tag'.
|
||||||
local
|
|
||||||
i: INTEGER
|
|
||||||
do
|
do
|
||||||
initialize
|
initialize
|
||||||
|
set_language_range (a_lang_tag)
|
||||||
create language_range.make_from_string (a_lang_tag)
|
|
||||||
i := a_lang_tag.index_of ('-', 1)
|
|
||||||
if i > 0 then
|
|
||||||
language := a_lang_tag.substring (1, i - 1)
|
|
||||||
specialization := a_lang_tag.substring (i + 1, a_lang_tag.count)
|
|
||||||
else
|
|
||||||
language := a_lang_tag
|
|
||||||
end
|
|
||||||
ensure
|
ensure
|
||||||
language_range_set: language_range.same_string (a_lang_tag) and a_lang_tag /= language_range
|
language_range_set: language_range.same_string (a_lang_tag) and a_lang_tag /= language_range
|
||||||
end
|
end
|
||||||
@@ -119,7 +95,7 @@ feature {NONE} -- Initialization
|
|||||||
initialize
|
initialize
|
||||||
-- Initialize Current
|
-- Initialize Current
|
||||||
do
|
do
|
||||||
create params.make (2)
|
create parameters.make (1)
|
||||||
quality := 1.0
|
quality := 1.0
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -148,37 +124,24 @@ feature -- Status report
|
|||||||
Result.append_double (quality)
|
Result.append_double (quality)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Parameters
|
|
||||||
|
|
||||||
item (a_key: STRING): detachable STRING
|
|
||||||
-- Item associated with `a_key', if present
|
|
||||||
-- otherwise default value of type `STRING'
|
|
||||||
do
|
|
||||||
Result := params.item (a_key)
|
|
||||||
end
|
|
||||||
|
|
||||||
keys: LIST [STRING]
|
|
||||||
-- arrays of currents keys
|
|
||||||
local
|
|
||||||
res: ARRAYED_LIST [STRING]
|
|
||||||
do
|
|
||||||
create res.make_from_array (params.current_keys)
|
|
||||||
Result := res
|
|
||||||
end
|
|
||||||
|
|
||||||
params: HASH_TABLE [STRING, STRING]
|
|
||||||
-- dictionary of all the parameters for the media range
|
|
||||||
|
|
||||||
feature -- Status Report
|
|
||||||
|
|
||||||
has_key (a_key: STRING): BOOLEAN
|
|
||||||
-- Is there an item in the table with key `a_key'?
|
|
||||||
do
|
|
||||||
Result := params.has_key (a_key)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Element change
|
feature -- Element change
|
||||||
|
|
||||||
|
set_language_range (a_lang_range: READABLE_STRING_8)
|
||||||
|
local
|
||||||
|
i: INTEGER
|
||||||
|
do
|
||||||
|
create language_range.make_from_string (a_lang_range)
|
||||||
|
i := a_lang_range.index_of ('-', 1)
|
||||||
|
if i > 0 then
|
||||||
|
language := a_lang_range.substring (1, i - 1)
|
||||||
|
specialization := a_lang_range.substring (i + 1, a_lang_range.count)
|
||||||
|
else
|
||||||
|
language := a_lang_range
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
language_range_set: language_range.same_string (a_lang_range) and a_lang_range /= language_range
|
||||||
|
end
|
||||||
|
|
||||||
set_language (a_root_lang: READABLE_STRING_8)
|
set_language (a_root_lang: READABLE_STRING_8)
|
||||||
-- Set `'anguage' with `a_root_lang'
|
-- Set `'anguage' with `a_root_lang'
|
||||||
require
|
require
|
||||||
@@ -199,19 +162,47 @@ feature -- Element change
|
|||||||
specialization_assigned: specialization ~ a_specialization
|
specialization_assigned: specialization ~ a_specialization
|
||||||
end
|
end
|
||||||
|
|
||||||
put (new: STRING; key: STRING)
|
feature -- Parameters: Access
|
||||||
-- Insert `new' with `key' if there is no other item
|
|
||||||
-- associated with the same key. If present, replace
|
parameter (a_key: READABLE_STRING_8): detachable READABLE_STRING_8
|
||||||
-- the old value with `new'
|
-- Parameter associated with `a_key', if present
|
||||||
|
-- otherwise default value of type `STRING'
|
||||||
do
|
do
|
||||||
if params.has_key (key) then
|
if attached parameters as l_params then
|
||||||
params.replace (new, key)
|
Result := l_params.item (a_key)
|
||||||
else
|
|
||||||
params.force (new, key)
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
parameters: detachable HTTP_PARAMETER_TABLE
|
||||||
|
-- Table of all parameters for the media range
|
||||||
|
|
||||||
|
feature -- Parameters: Status report
|
||||||
|
|
||||||
|
has_parameter (a_key: READABLE_STRING_8): BOOLEAN
|
||||||
|
-- Is there an parameter in the parameters table with key `a_key'?
|
||||||
|
do
|
||||||
|
if attached parameters as l_params then
|
||||||
|
Result := l_params.has_key (a_key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Parameters: Change
|
||||||
|
|
||||||
|
put_parameter (a_value: READABLE_STRING_8; a_key: READABLE_STRING_8)
|
||||||
|
-- Insert `a_value' with `a_key' if there is no other item
|
||||||
|
-- associated with the same key. If present, replace
|
||||||
|
-- the old value with `a_value'
|
||||||
|
local
|
||||||
|
l_parameters: like parameters
|
||||||
|
do
|
||||||
|
l_parameters := parameters
|
||||||
|
if l_parameters = Void then
|
||||||
|
create l_parameters.make (1)
|
||||||
|
parameters := l_parameters
|
||||||
|
end
|
||||||
|
l_parameters.force (a_value, a_key)
|
||||||
ensure
|
ensure
|
||||||
has_key: params.has_key (key)
|
is_set: attached parameters as l_params and then (l_params.has_key (a_key) and l_params.has_item (a_value))
|
||||||
has_item: params.has_item (new)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
note
|
||||||
|
description: "Object that represents a results after parsing Accept(-*) headers."
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
HTTP_ANY_ACCEPT
|
||||||
|
|
||||||
|
inherit
|
||||||
|
REFACTORING_HELPER
|
||||||
|
|
||||||
|
DEBUG_OUTPUT
|
||||||
|
|
||||||
|
create
|
||||||
|
make_from_string
|
||||||
|
|
||||||
|
feature -- Initialization
|
||||||
|
|
||||||
|
make_from_string (a_string: READABLE_STRING_8)
|
||||||
|
local
|
||||||
|
l_parts: LIST [READABLE_STRING_8]
|
||||||
|
sub_parts: LIST [READABLE_STRING_8]
|
||||||
|
p: READABLE_STRING_8
|
||||||
|
i: INTEGER
|
||||||
|
do
|
||||||
|
initialize
|
||||||
|
i := a_string.index_of (';', 1)
|
||||||
|
if i > 0 then
|
||||||
|
set_value (trimmed_string (a_string.substring (1, i - 1)))
|
||||||
|
create parameters.make_from_substring (a_string, i + 1, a_string.count)
|
||||||
|
else
|
||||||
|
set_value (trimmed_string (a_string))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
initialize
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
value: READABLE_STRING_8
|
||||||
|
-- Value composing an Accept(-*) header value
|
||||||
|
|
||||||
|
feature -- Access: parameters
|
||||||
|
|
||||||
|
parameter (a_key: READABLE_STRING_8): detachable READABLE_STRING_8
|
||||||
|
-- Item associated with `a_key', if present
|
||||||
|
-- otherwise default value of type `STRING'
|
||||||
|
do
|
||||||
|
if attached parameters as l_parameters then
|
||||||
|
Result := l_parameters.item (a_key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
parameters: detachable HTTP_PARAMETER_TABLE
|
||||||
|
-- Table of all parameters for the media range
|
||||||
|
|
||||||
|
feature -- Status Report
|
||||||
|
|
||||||
|
has_parameter (a_key: READABLE_STRING_8): BOOLEAN
|
||||||
|
-- Is there an item in the table with key `a_key'?
|
||||||
|
do
|
||||||
|
if attached parameters as l_parameters then
|
||||||
|
Result := l_parameters.has_key (a_key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Element change
|
||||||
|
|
||||||
|
set_value (v: READABLE_STRING_8)
|
||||||
|
-- Set `value' with `v'
|
||||||
|
do
|
||||||
|
value := v
|
||||||
|
ensure
|
||||||
|
value_set: attached value as l_value implies l_value.same_string (v)
|
||||||
|
end
|
||||||
|
|
||||||
|
put_parameter (a_value: READABLE_STRING_8; a_key: READABLE_STRING_8)
|
||||||
|
-- Insert `a_value' with `a_key' if there is no other item
|
||||||
|
-- associated with the same key. If present, replace
|
||||||
|
-- the old value with `a_value'
|
||||||
|
local
|
||||||
|
l_parameters: like parameters
|
||||||
|
do
|
||||||
|
l_parameters := parameters
|
||||||
|
if l_parameters = Void then
|
||||||
|
create l_parameters.make (1)
|
||||||
|
parameters := l_parameters
|
||||||
|
end
|
||||||
|
l_parameters.force (a_value, a_key)
|
||||||
|
ensure
|
||||||
|
is_set: attached parameters as l_params and then (l_params.has_key (a_key) and l_params.has_item (a_value))
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status Report
|
||||||
|
|
||||||
|
debug_output: STRING
|
||||||
|
-- String that should be displayed in debugger to represent `Current'.
|
||||||
|
do
|
||||||
|
create Result.make_from_string (value)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Helper
|
||||||
|
|
||||||
|
trimmed_string (s: READABLE_STRING_8): STRING_8
|
||||||
|
-- Copy of `s', where whitespace were stripped from the beginning and end of the string
|
||||||
|
do
|
||||||
|
create Result.make_from_string (s)
|
||||||
|
Result.left_adjust
|
||||||
|
Result.right_adjust
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Object that represents a results after parsing Accept-* headers."
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
HTTP_ANY_ACCEPT_HEADER
|
|
||||||
|
|
||||||
create
|
|
||||||
make
|
|
||||||
|
|
||||||
feature -- Initialization
|
|
||||||
|
|
||||||
make
|
|
||||||
do
|
|
||||||
create params.make (2)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access
|
|
||||||
|
|
||||||
field: detachable STRING
|
|
||||||
|
|
||||||
item (a_key: STRING): detachable STRING
|
|
||||||
-- Item associated with `a_key', if present
|
|
||||||
-- otherwise default value of type `STRING'
|
|
||||||
do
|
|
||||||
Result := params.item (a_key)
|
|
||||||
end
|
|
||||||
|
|
||||||
keys: LIST [STRING]
|
|
||||||
-- arrays of currents keys
|
|
||||||
local
|
|
||||||
res: ARRAYED_LIST [STRING]
|
|
||||||
do
|
|
||||||
create res.make_from_array (params.current_keys)
|
|
||||||
Result := res
|
|
||||||
end
|
|
||||||
|
|
||||||
params: HASH_TABLE [STRING, STRING]
|
|
||||||
-- Table of all parameters for the media range
|
|
||||||
|
|
||||||
feature -- Status Report
|
|
||||||
|
|
||||||
has_key (a_key: STRING): BOOLEAN
|
|
||||||
-- Is there an item in the table with key `a_key'?
|
|
||||||
do
|
|
||||||
Result := params.has_key (a_key)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Element change
|
|
||||||
|
|
||||||
set_field (a_field: STRING)
|
|
||||||
-- Set type with `a_field'
|
|
||||||
do
|
|
||||||
field := a_field
|
|
||||||
ensure
|
|
||||||
field_set: attached field as l_field implies l_field = a_field
|
|
||||||
end
|
|
||||||
|
|
||||||
put (new: STRING; key: STRING)
|
|
||||||
-- Insert `new' with `key' if there is no other item
|
|
||||||
-- associated with the same key. If present, replace
|
|
||||||
-- the old value with `new'
|
|
||||||
do
|
|
||||||
if params.has_key (key) then
|
|
||||||
params.replace (new, key)
|
|
||||||
else
|
|
||||||
params.force (new, key)
|
|
||||||
end
|
|
||||||
ensure
|
|
||||||
has_key: params.has_key (key)
|
|
||||||
has_item: params.has_item (new)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Status Report
|
|
||||||
|
|
||||||
debug_output: STRING
|
|
||||||
-- String that should be displayed in debugger to represent `Current'.
|
|
||||||
do
|
|
||||||
Result := out
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
note
|
|
||||||
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {SERVER_CHARSET_NEGOTIATION}. Utility class to support Server Side Content Negotiation on charset "
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
description: "[
|
||||||
|
Reference : http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12.1
|
||||||
|
Server-driven Negotiation : If the selection of the best representation for a response is made by an algorithm located at the server,
|
||||||
|
it is called server-driven negotiation. Selection is based on the available representations of the response (the dimensions over which it can vary; e.g. language, content-coding, etc.)
|
||||||
|
and the contents of particular header fields in the request message or on other information pertaining to the request (such as the network address of the client).
|
||||||
|
Server-driven negotiation is advantageous when the algorithm for selecting from among the available representations is difficult to describe to the user agent,
|
||||||
|
or when the server desires to send its "best guess" to the client along with the first response (hoping to avoid the round-trip delay of a subsequent request if the "best guess" is good enough for the user).
|
||||||
|
In order to improve the server's guess, the user agent MAY include request header fields (Accept, Accept-Language, Accept-Encoding, etc.) which describe its preferences for such a response.
|
||||||
|
]"
|
||||||
|
EIS: "name=server driven negotiation", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12.", "protocol=uri"
|
||||||
|
|
||||||
|
class
|
||||||
|
SERVER_CHARSET_NEGOTIATION
|
||||||
|
|
||||||
|
inherit
|
||||||
|
REFACTORING_HELPER
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make (a_charset_dft: READABLE_STRING_8)
|
||||||
|
do
|
||||||
|
create accept_charset_utilities
|
||||||
|
set_default_charset (a_charset_dft)
|
||||||
|
ensure
|
||||||
|
default_charset_set: default_charset = a_charset_dft
|
||||||
|
end
|
||||||
|
|
||||||
|
accept_charset_utilities: HTTP_ANY_ACCEPT_HEADER_UTILITIES
|
||||||
|
-- Charset
|
||||||
|
|
||||||
|
feature -- Access: Server Side Defaults Formats
|
||||||
|
|
||||||
|
default_charset: READABLE_STRING_8
|
||||||
|
-- Character set that is acceptable for the response.
|
||||||
|
|
||||||
|
feature -- Change Element
|
||||||
|
|
||||||
|
set_default_charset (a_charset: READABLE_STRING_8)
|
||||||
|
-- Set `default_charset' with `a_charset'
|
||||||
|
do
|
||||||
|
default_charset := a_charset
|
||||||
|
ensure
|
||||||
|
default_charset_set: a_charset = default_charset
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Charset Negotiation
|
||||||
|
|
||||||
|
preference (a_server_charset_supported: ITERABLE [READABLE_STRING_8]; a_header: detachable READABLE_STRING_8): HTTP_ACCEPT_CHARSET_VARIANTS
|
||||||
|
-- `a_server_charset_supported' represent a list of character sets supported by the server.
|
||||||
|
-- `a_header' represents the Accept-Charset header, ie, the client preferences.
|
||||||
|
-- Return which Charset to use in a response, if the server supports
|
||||||
|
-- the requested Charset, or empty in other case.
|
||||||
|
note
|
||||||
|
EIS: "name=charset", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.2", "protocol=uri"
|
||||||
|
local
|
||||||
|
l_charset_match: READABLE_STRING_8
|
||||||
|
do
|
||||||
|
create Result.make
|
||||||
|
Result.set_supported_variants (a_server_charset_supported)
|
||||||
|
if a_header = Void or else a_header.is_empty then
|
||||||
|
-- the request has no Accept-Charset header, ie the header is empty, in this case use default charset encoding
|
||||||
|
Result.set_acceptable (True)
|
||||||
|
Result.set_variant_value (default_charset)
|
||||||
|
else
|
||||||
|
Result.set_vary_header_value
|
||||||
|
|
||||||
|
-- select the best match, server support, client preferences
|
||||||
|
l_charset_match := accept_charset_utilities.best_match (a_server_charset_supported, a_header)
|
||||||
|
if l_charset_match.is_empty then
|
||||||
|
-- The server does not support any of the compression types prefered by the client
|
||||||
|
Result.set_acceptable (False)
|
||||||
|
else
|
||||||
|
-- Set the best match
|
||||||
|
Result.set_variant_value (l_charset_match)
|
||||||
|
Result.set_acceptable (True)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {SERVER_CONTENT_NEGOTIATION}. Utility class to support Server Side Content Negotiation "
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
description: "[
|
||||||
|
Reference : http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12.1
|
||||||
|
Server-driven Negotiation : If the selection of the best representation for a response is made by an algorithm located at the server,
|
||||||
|
it is called server-driven negotiation. Selection is based on the available representations of the response (the dimensions over which it can vary; e.g. language, content-coding, etc.)
|
||||||
|
and the contents of particular header fields in the request message or on other information pertaining to the request (such as the network address of the client).
|
||||||
|
Server-driven negotiation is advantageous when the algorithm for selecting from among the available representations is difficult to describe to the user agent,
|
||||||
|
or when the server desires to send its "best guess" to the client along with the first response (hoping to avoid the round-trip delay of a subsequent request if the "best guess" is good enough for the user).
|
||||||
|
In order to improve the server's guess, the user agent MAY include request header fields (Accept, Accept-Language, Accept-Encoding, etc.) which describe its preferences for such a response.
|
||||||
|
]"
|
||||||
|
EIS: "name=server driven negotiation", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12.", "protocol=uri"
|
||||||
|
|
||||||
|
class
|
||||||
|
SERVER_CONTENT_NEGOTIATION
|
||||||
|
|
||||||
|
inherit
|
||||||
|
SERVER_MEDIA_TYPE_NEGOTIATION
|
||||||
|
rename
|
||||||
|
make as make_media_type,
|
||||||
|
preference as media_type_preference
|
||||||
|
end
|
||||||
|
|
||||||
|
SERVER_LANGUAGE_NEGOTIATION
|
||||||
|
rename
|
||||||
|
make as make_language,
|
||||||
|
preference as language_preference
|
||||||
|
end
|
||||||
|
|
||||||
|
SERVER_CHARSET_NEGOTIATION
|
||||||
|
rename
|
||||||
|
make as make_charset,
|
||||||
|
preference as charset_preference
|
||||||
|
end
|
||||||
|
|
||||||
|
SERVER_ENCODING_NEGOTIATION
|
||||||
|
rename
|
||||||
|
make as make_encoding,
|
||||||
|
preference as encoding_preference
|
||||||
|
end
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make (a_mediatype_dft: READABLE_STRING_8; a_language_dft: READABLE_STRING_8; a_charset_dft: READABLE_STRING_8; a_encoding_dft: READABLE_STRING_8)
|
||||||
|
-- Initialize Current with default Media type, language, charset and encoding.
|
||||||
|
do
|
||||||
|
make_media_type (a_mediatype_dft)
|
||||||
|
make_language (a_language_dft)
|
||||||
|
make_charset (a_charset_dft)
|
||||||
|
make_encoding (a_encoding_dft)
|
||||||
|
ensure
|
||||||
|
default_media_type_set: default_media_type = a_mediatype_dft
|
||||||
|
default_language_set: default_language = a_language_dft
|
||||||
|
default_charset_set: default_charset = a_charset_dft
|
||||||
|
default_encoding_set: default_encoding = a_encoding_dft
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {SERVER_ENCODING_NEGOTIATION}. Utility class to support Server Side Content Negotiation on encoding"
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
description: "[
|
||||||
|
Reference : http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12.1
|
||||||
|
Server-driven Negotiation : If the selection of the best representation for a response is made by an algorithm located at the server,
|
||||||
|
it is called server-driven negotiation. Selection is based on the available representations of the response (the dimensions over which it can vary; e.g. language, content-coding, etc.)
|
||||||
|
and the contents of particular header fields in the request message or on other information pertaining to the request (such as the network address of the client).
|
||||||
|
Server-driven negotiation is advantageous when the algorithm for selecting from among the available representations is difficult to describe to the user agent,
|
||||||
|
or when the server desires to send its "best guess" to the client along with the first response (hoping to avoid the round-trip delay of a subsequent request if the "best guess" is good enough for the user).
|
||||||
|
In order to improve the server's guess, the user agent MAY include request header fields (Accept, Accept-Language, Accept-Encoding, etc.) which describe its preferences for such a response.
|
||||||
|
]"
|
||||||
|
EIS: "name=server driven negotiation", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12.", "protocol=uri"
|
||||||
|
|
||||||
|
class
|
||||||
|
SERVER_ENCODING_NEGOTIATION
|
||||||
|
|
||||||
|
inherit
|
||||||
|
REFACTORING_HELPER
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make (a_encoding_dft: READABLE_STRING_8)
|
||||||
|
do
|
||||||
|
create accept_encoding_utilities
|
||||||
|
set_default_encoding (a_encoding_dft)
|
||||||
|
ensure
|
||||||
|
default_encoding_set: default_encoding = a_encoding_dft
|
||||||
|
end
|
||||||
|
|
||||||
|
accept_encoding_utilities: HTTP_ANY_ACCEPT_HEADER_UTILITIES
|
||||||
|
-- Encoding
|
||||||
|
|
||||||
|
feature -- Access: Server Side Defaults Formats
|
||||||
|
|
||||||
|
default_encoding: READABLE_STRING_8
|
||||||
|
-- Content-coding that is acceptable in the response.
|
||||||
|
|
||||||
|
feature -- Change Element
|
||||||
|
|
||||||
|
set_default_encoding (a_encoding: READABLE_STRING_8)
|
||||||
|
-- Set `default_encoding' with `a_encoding'
|
||||||
|
do
|
||||||
|
default_encoding := a_encoding
|
||||||
|
ensure
|
||||||
|
default_encoding_set: a_encoding = default_encoding
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Encoding Negotiation
|
||||||
|
|
||||||
|
preference (a_server_encoding_supported: ITERABLE [READABLE_STRING_8]; a_header_value: detachable READABLE_STRING_8): HTTP_ACCEPT_ENCODING_VARIANTS
|
||||||
|
-- `a_server_encoding_supported' represent a list of encoding supported by the server.
|
||||||
|
-- `a_header_value' represent the Accept-Encoding header, ie, the client preferences.
|
||||||
|
-- Return which Encoding to use in a response, if the server supports
|
||||||
|
-- the requested Encoding, or empty in other case.
|
||||||
|
note
|
||||||
|
EIS: "name=encoding", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3", "protocol=uri"
|
||||||
|
local
|
||||||
|
l_compression_match: READABLE_STRING_8
|
||||||
|
do
|
||||||
|
create Result.make
|
||||||
|
Result.set_supported_variants (a_server_encoding_supported)
|
||||||
|
if a_header_value = Void or else a_header_value.is_empty then
|
||||||
|
-- the request has no Accept-Encoding header, ie the header is empty, in this case do not compress representations
|
||||||
|
Result.set_acceptable (True)
|
||||||
|
Result.set_variant_value (default_encoding)
|
||||||
|
else
|
||||||
|
Result.set_vary_header_value
|
||||||
|
|
||||||
|
-- select the best match, server support, client preferences
|
||||||
|
l_compression_match := accept_encoding_utilities.best_match (a_server_encoding_supported, a_header_value)
|
||||||
|
if l_compression_match.is_empty then
|
||||||
|
-- The server does not support any of the compression types prefered by the client
|
||||||
|
Result.set_acceptable (False)
|
||||||
|
else
|
||||||
|
-- Set the best match
|
||||||
|
Result.set_variant_value (l_compression_match)
|
||||||
|
Result.set_acceptable (True)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {SERVER_LANGUAGE_NEGOTIATION}. Utility class to support Server Side Content Negotiation on language"
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
description: "[
|
||||||
|
Reference : http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12.1
|
||||||
|
Server-driven Negotiation : If the selection of the best representation for a response is made by an algorithm located at the server,
|
||||||
|
it is called server-driven negotiation. Selection is based on the available representations of the response (the dimensions over which it can vary; e.g. language, content-coding, etc.)
|
||||||
|
and the contents of particular header fields in the request message or on other information pertaining to the request (such as the network address of the client).
|
||||||
|
Server-driven negotiation is advantageous when the algorithm for selecting from among the available representations is difficult to describe to the user agent,
|
||||||
|
or when the server desires to send its "best guess" to the client along with the first response (hoping to avoid the round-trip delay of a subsequent request if the "best guess" is good enough for the user).
|
||||||
|
In order to improve the server's guess, the user agent MAY include request header fields (Accept, Accept-Language, Accept-Encoding, etc.) which describe its preferences for such a response.
|
||||||
|
]"
|
||||||
|
EIS: "name=server driven negotiation", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12.", "protocol=uri"
|
||||||
|
|
||||||
|
class
|
||||||
|
SERVER_LANGUAGE_NEGOTIATION
|
||||||
|
|
||||||
|
inherit
|
||||||
|
REFACTORING_HELPER
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make (a_language_dft: READABLE_STRING_8)
|
||||||
|
do
|
||||||
|
create accept_language_utilities
|
||||||
|
set_default_language (a_language_dft)
|
||||||
|
ensure
|
||||||
|
default_language_set: default_language = a_language_dft
|
||||||
|
end
|
||||||
|
|
||||||
|
accept_language_utilities: HTTP_ACCEPT_LANGUAGE_UTILITIES
|
||||||
|
-- Language
|
||||||
|
|
||||||
|
feature -- Access: Server Side Defaults Formats
|
||||||
|
|
||||||
|
default_language: READABLE_STRING_8
|
||||||
|
-- Natural language that is preferred as a response to the request.
|
||||||
|
|
||||||
|
feature -- Change Element
|
||||||
|
|
||||||
|
set_default_language (a_language: READABLE_STRING_8)
|
||||||
|
-- Set `default_language' with `a_language'
|
||||||
|
do
|
||||||
|
default_language := a_language
|
||||||
|
ensure
|
||||||
|
default_language_set: a_language = default_language
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Language Negotiation
|
||||||
|
|
||||||
|
preference (a_server_language_supported: ITERABLE [READABLE_STRING_8]; a_header_value: detachable READABLE_STRING_8): HTTP_ACCEPT_LANGUAGE_VARIANTS
|
||||||
|
-- `a_server_language_supported' represent a list of languages supported by the server.
|
||||||
|
-- `a_header_value' represent the Accept-Language header, ie, the client preferences.
|
||||||
|
-- Return which Language to use in a response, if the server supports
|
||||||
|
-- the requested Language, or empty in other case.
|
||||||
|
note
|
||||||
|
EIS: "name=language", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4", "protocol=uri"
|
||||||
|
|
||||||
|
local
|
||||||
|
l_language_match: READABLE_STRING_8
|
||||||
|
do
|
||||||
|
create Result.make
|
||||||
|
Result.set_supported_variants (a_server_language_supported)
|
||||||
|
|
||||||
|
if a_header_value = Void or else a_header_value.is_empty then
|
||||||
|
-- the request has no Accept header, ie the header is empty, in this case we use the default format
|
||||||
|
Result.set_acceptable (True)
|
||||||
|
Result.set_variant_value (default_language)
|
||||||
|
else
|
||||||
|
Result.set_vary_header_value
|
||||||
|
|
||||||
|
-- select the best match, server support, client preferences
|
||||||
|
l_language_match := accept_language_utilities.best_match (a_server_language_supported, a_header_value)
|
||||||
|
if l_language_match.is_empty then
|
||||||
|
-- The server does not support any of the media types prefered by the client
|
||||||
|
Result.set_acceptable (False)
|
||||||
|
else
|
||||||
|
-- Set the best match
|
||||||
|
Result.set_variant_value (l_language_match)
|
||||||
|
Result.set_acceptable (True)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {SERVER_MEDIA_TYPE_NEGOTIATION}. Utility class to support Server Side Content Negotiation on media type"
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
description: "[
|
||||||
|
Reference : http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12.1
|
||||||
|
Server-driven Negotiation : If the selection of the best representation for a response is made by an algorithm located at the server,
|
||||||
|
it is called server-driven negotiation. Selection is based on the available representations of the response (the dimensions over which it can vary; e.g. language, content-coding, etc.)
|
||||||
|
and the contents of particular header fields in the request message or on other information pertaining to the request (such as the network address of the client).
|
||||||
|
Server-driven negotiation is advantageous when the algorithm for selecting from among the available representations is difficult to describe to the user agent,
|
||||||
|
or when the server desires to send its "best guess" to the client along with the first response (hoping to avoid the round-trip delay of a subsequent request if the "best guess" is good enough for the user).
|
||||||
|
In order to improve the server's guess, the user agent MAY include request header fields (Accept, Accept-Language, Accept-Encoding, etc.) which describe its preferences for such a response.
|
||||||
|
]"
|
||||||
|
EIS: "name=server driven negotiation", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12.", "protocol=uri"
|
||||||
|
|
||||||
|
class
|
||||||
|
SERVER_MEDIA_TYPE_NEGOTIATION
|
||||||
|
|
||||||
|
inherit
|
||||||
|
REFACTORING_HELPER
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make (a_mediatype_dft: READABLE_STRING_8)
|
||||||
|
do
|
||||||
|
create accept_media_type_utilities
|
||||||
|
set_default_media_type (a_mediatype_dft)
|
||||||
|
ensure
|
||||||
|
default_media_type_set: default_media_type = a_mediatype_dft
|
||||||
|
end
|
||||||
|
|
||||||
|
accept_media_type_utilities: HTTP_ACCEPT_MEDIA_TYPE_UTILITIES
|
||||||
|
-- MIME
|
||||||
|
|
||||||
|
feature -- Access: Server Side Defaults Formats
|
||||||
|
|
||||||
|
default_media_type: READABLE_STRING_8
|
||||||
|
-- Media type which is acceptable for the response.
|
||||||
|
|
||||||
|
feature -- Change Element
|
||||||
|
|
||||||
|
set_default_media_type (a_mediatype: READABLE_STRING_8)
|
||||||
|
-- Set `default_media_type' with `a_mediatype'
|
||||||
|
do
|
||||||
|
default_media_type := a_mediatype
|
||||||
|
ensure
|
||||||
|
default_media_type_set: a_mediatype = default_media_type
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Media Type Negotiation
|
||||||
|
|
||||||
|
preference (a_mime_types_supported: ITERABLE [READABLE_STRING_8]; a_header: detachable READABLE_STRING_8): HTTP_ACCEPT_MEDIA_TYPE_VARIANTS
|
||||||
|
-- `a_mime_types_supported' represent media types supported by the server.
|
||||||
|
-- `a_header represent' the Accept header, ie, the client preferences.
|
||||||
|
-- Return which media type to use for representation in a response, if the server supports
|
||||||
|
-- the requested media type, or empty in other case.
|
||||||
|
note
|
||||||
|
EIS: "name=media type", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1", "protocol=uri"
|
||||||
|
local
|
||||||
|
l_mime_match: READABLE_STRING_8
|
||||||
|
do
|
||||||
|
create Result.make
|
||||||
|
Result.set_supported_variants (a_mime_types_supported)
|
||||||
|
if a_header = Void or else a_header.is_empty then
|
||||||
|
-- the request has no Accept header, ie the header is empty, in this case we use the default format
|
||||||
|
Result.set_acceptable (True)
|
||||||
|
Result.set_variant_value (default_media_type)
|
||||||
|
else
|
||||||
|
Result.set_vary_header_value
|
||||||
|
|
||||||
|
-- select the best match, server support, client preferences
|
||||||
|
l_mime_match := accept_media_type_utilities.best_match (a_mime_types_supported, a_header)
|
||||||
|
if l_mime_match.is_empty then
|
||||||
|
-- The server does not support any of the media types preferred by the client
|
||||||
|
Result.set_acceptable (False)
|
||||||
|
else
|
||||||
|
-- Set the best match
|
||||||
|
Result.set_variant_value (l_mime_match)
|
||||||
|
Result.set_acceptable (True)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {SHARED_CONNEG}."
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
SHARED_CONNEG
|
|
||||||
|
|
||||||
feature
|
|
||||||
|
|
||||||
Mime: HTTP_ACCEPT_MEDIA_TYPE_PARSER
|
|
||||||
once
|
|
||||||
create Result
|
|
||||||
end
|
|
||||||
|
|
||||||
Common: HTTP_ANY_ACCEPT_HEADER_PARSER
|
|
||||||
-- Charset and Encoding
|
|
||||||
once
|
|
||||||
create Result
|
|
||||||
end
|
|
||||||
|
|
||||||
Language: HTTP_ACCEPT_LANGUAGE_PARSER
|
|
||||||
once
|
|
||||||
create Result
|
|
||||||
end
|
|
||||||
|
|
||||||
note
|
|
||||||
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -28,7 +28,7 @@ feature -- Access
|
|||||||
-- this indicates the Accept-* header source of the matched `variant_value' if any,
|
-- this indicates the Accept-* header source of the matched `variant_value' if any,
|
||||||
-- if this is using the default, the `vary_header_value' is Void.
|
-- if this is using the default, the `vary_header_value' is Void.
|
||||||
|
|
||||||
supported_variants: detachable LIST [READABLE_STRING_8]
|
supported_variants: detachable ITERABLE [READABLE_STRING_8]
|
||||||
-- Set of supported variants for the response
|
-- Set of supported variants for the response
|
||||||
|
|
||||||
variant_value: detachable READABLE_STRING_8
|
variant_value: detachable READABLE_STRING_8
|
||||||
@@ -77,7 +77,7 @@ feature -- Change Element
|
|||||||
is_acceptable_set: is_acceptable = b
|
is_acceptable_set: is_acceptable = b
|
||||||
end
|
end
|
||||||
|
|
||||||
set_supported_variants (a_supported: LIST [READABLE_STRING_8])
|
set_supported_variants (a_supported: ITERABLE [READABLE_STRING_8])
|
||||||
-- Set `supported variants' with `a_supported'
|
-- Set `supported variants' with `a_supported'
|
||||||
do
|
do
|
||||||
supported_variants := a_supported
|
supported_variants := a_supported
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ feature {NONE} -- Initialization
|
|||||||
|
|
||||||
make
|
make
|
||||||
local
|
local
|
||||||
mime_parse : HTTP_ACCEPT_MEDIA_TYPE_PARSER
|
mime_parse : HTTP_ACCEPT_MEDIA_TYPE_UTILITIES
|
||||||
accept : STRING
|
accept : STRING
|
||||||
charset_parse : HTTP_ANY_ACCEPT_HEADER_PARSER
|
charset_parse : HTTP_ANY_ACCEPT_HEADER_UTILITIES
|
||||||
language : HTTP_ACCEPT_LANGUAGE_PARSER
|
language : HTTP_ACCEPT_LANGUAGE_UTILITIES
|
||||||
do
|
do
|
||||||
create mime_parse
|
create mime_parse
|
||||||
-- parse_result := mime_parse.parse_mime_type ("application/xhtml;q=0.5")
|
-- parse_result := mime_parse.parse_mime_type ("application/xhtml;q=0.5")
|
||||||
|
|||||||
@@ -23,26 +23,24 @@ feature {NONE} -- Events
|
|||||||
|
|
||||||
feature -- Helpers
|
feature -- Helpers
|
||||||
|
|
||||||
format (a_common: HTTP_ANY_ACCEPT_HEADER): STRING
|
format (a_common: HTTP_ANY_ACCEPT): STRING
|
||||||
-- Representation of the current object
|
-- Representation of the current object
|
||||||
do
|
do
|
||||||
create Result.make_from_string ("(")
|
create Result.make_from_string ("(")
|
||||||
if attached a_common.field as t then
|
if attached a_common.value as t then
|
||||||
Result.append_string ("'" + t + "',")
|
Result.append_string ("'" + t + "',")
|
||||||
end
|
end
|
||||||
Result.append_string (" {")
|
Result.append_string (" {")
|
||||||
from
|
if attached a_common.parameters as l_parameters then
|
||||||
a_common.params.start
|
across
|
||||||
until
|
l_parameters as ic
|
||||||
a_common.params.after
|
loop
|
||||||
loop
|
Result.append ("'" + ic.key + "':'" + ic.item + "',");
|
||||||
Result.append ("'" + a_common.params.key_for_iteration + "':'" + a_common.params.item_for_iteration + "',");
|
end
|
||||||
a_common.params.forth
|
|
||||||
end
|
end
|
||||||
Result.append ("})")
|
Result.append ("})")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
feature -- Test routines
|
feature -- Test routines
|
||||||
|
|
||||||
test_parse_charsets
|
test_parse_charsets
|
||||||
@@ -74,6 +72,6 @@ feature -- Test routines
|
|||||||
assert ("Expected unicode-1-1", parser.best_match (charset_supported, "unicode-1-1;q=1").same_string ("unicode-1-1"))
|
assert ("Expected unicode-1-1", parser.best_match (charset_supported, "unicode-1-1;q=1").same_string ("unicode-1-1"))
|
||||||
end
|
end
|
||||||
|
|
||||||
parser : HTTP_ANY_ACCEPT_HEADER_PARSER
|
parser : HTTP_ANY_ACCEPT_HEADER_UTILITIES
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ feature -- Test routines
|
|||||||
media_variants := conneg.media_type_preference (mime_types_supported, "text/html")
|
media_variants := conneg.media_type_preference (mime_types_supported, "text/html")
|
||||||
assert ("Expected Not Acceptable", not media_variants.is_acceptable)
|
assert ("Expected Not Acceptable", not media_variants.is_acceptable)
|
||||||
if attached media_variants.supported_variants as l_supported_variants then
|
if attached media_variants.supported_variants as l_supported_variants then
|
||||||
assert ("Same Value at 1",mime_types_supported.first.same_string (l_supported_variants.first))
|
assert ("Same Value at 1", same_text (first_of (mime_types_supported), first_of (l_supported_variants)))
|
||||||
assert ("Same count",mime_types_supported.count = l_supported_variants.count)
|
assert ("Same count", count_of (mime_types_supported) = count_of (l_supported_variants))
|
||||||
else
|
else
|
||||||
assert ("Has supported_variants results", False)
|
assert ("Has supported_variants results", False)
|
||||||
end
|
end
|
||||||
@@ -72,8 +72,8 @@ feature -- Test routines
|
|||||||
charset_variants := conneg.charset_preference (charset_supported, "unicode-1-1")
|
charset_variants := conneg.charset_preference (charset_supported, "unicode-1-1")
|
||||||
assert ("Expected Not Acceptable", not charset_variants.is_acceptable)
|
assert ("Expected Not Acceptable", not charset_variants.is_acceptable)
|
||||||
if attached charset_variants.supported_variants as l_supported_variants then
|
if attached charset_variants.supported_variants as l_supported_variants then
|
||||||
assert ("Same Value at 1",charset_supported.first.same_string (l_supported_variants.first))
|
assert ("Same Value at 1", same_text (first_of (charset_supported), first_of (l_supported_variants)))
|
||||||
assert ("Same count",charset_supported.count = l_supported_variants.count)
|
assert ("Same count",charset_supported.count = count_of (l_supported_variants))
|
||||||
else
|
else
|
||||||
assert("Has supported_variants results", False)
|
assert("Has supported_variants results", False)
|
||||||
end
|
end
|
||||||
@@ -109,8 +109,8 @@ feature -- Test routines
|
|||||||
compression_variants := conneg.encoding_preference (compression_supported, "gzip")
|
compression_variants := conneg.encoding_preference (compression_supported, "gzip")
|
||||||
assert ("Expected Not Acceptable", not compression_variants.is_acceptable)
|
assert ("Expected Not Acceptable", not compression_variants.is_acceptable)
|
||||||
if attached compression_variants.supported_variants as l_supported_variants then
|
if attached compression_variants.supported_variants as l_supported_variants then
|
||||||
assert ("Same Value at 1",compression_supported.first.same_string (l_supported_variants.first))
|
assert ("Same Value at 1", same_text (first_of (compression_supported), first_of (l_supported_variants)))
|
||||||
assert ("Same count",compression_supported.count = l_supported_variants.count)
|
assert ("Same count",compression_supported.count = count_of (l_supported_variants))
|
||||||
else
|
else
|
||||||
assert ("Has supported_variants results", False)
|
assert ("Has supported_variants results", False)
|
||||||
end
|
end
|
||||||
@@ -153,8 +153,8 @@ feature -- Test routines
|
|||||||
assert ("Variant Header", attached language_variants.vary_header_value as l_variant_header and then l_variant_header.same_string ("Accept-Language"))
|
assert ("Variant Header", attached language_variants.vary_header_value as l_variant_header and then l_variant_header.same_string ("Accept-Language"))
|
||||||
assert ("Language type is Void",language_variants.language = Void)
|
assert ("Language type is Void",language_variants.language = Void)
|
||||||
if attached language_variants.supported_variants as l_supported_variants then
|
if attached language_variants.supported_variants as l_supported_variants then
|
||||||
assert ("Same Value at 1", languages_supported.first.same_string (l_supported_variants.first))
|
assert ("Same Value at 1", same_text (first_of (languages_supported), first_of (l_supported_variants)))
|
||||||
assert ("Same count",languages_supported.count = l_supported_variants.count)
|
assert ("Same count",languages_supported.count = count_of (l_supported_variants))
|
||||||
else
|
else
|
||||||
assert ("Has supported variants results", False)
|
assert ("Has supported variants results", False)
|
||||||
end
|
end
|
||||||
@@ -175,5 +175,36 @@ feature -- Test routines
|
|||||||
end
|
end
|
||||||
|
|
||||||
feature -- Implementation
|
feature -- Implementation
|
||||||
conneg : CONNEG_SERVER_SIDE
|
conneg : SERVER_CONTENT_NEGOTIATION
|
||||||
|
|
||||||
|
same_text (s1,s2: detachable READABLE_STRING_8): BOOLEAN
|
||||||
|
do
|
||||||
|
if s1 = Void then
|
||||||
|
Result := s2 = Void
|
||||||
|
elseif s2 = Void then
|
||||||
|
Result := False
|
||||||
|
else
|
||||||
|
Result := s1.same_string (s2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
count_of (i: ITERABLE [READABLE_STRING_8]): INTEGER
|
||||||
|
do
|
||||||
|
across
|
||||||
|
i as ic
|
||||||
|
loop
|
||||||
|
Result := Result + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
first_of (i: ITERABLE [READABLE_STRING_8]): detachable READABLE_STRING_8
|
||||||
|
do
|
||||||
|
across
|
||||||
|
i as ic
|
||||||
|
until
|
||||||
|
ic.item /= Void
|
||||||
|
loop
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,3 +3,16 @@ Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected REA
|
|||||||
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
||||||
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
||||||
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
||||||
|
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
||||||
|
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
||||||
|
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
||||||
|
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
||||||
|
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
||||||
|
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
||||||
|
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
||||||
|
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
||||||
|
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
||||||
|
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
||||||
|
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
||||||
|
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
||||||
|
Catcall detected in {READABLE_STRING_8}.make_from_string for arg#1: expected READABLE_STRING_8 but got Void
|
||||||
|
|||||||
@@ -34,14 +34,11 @@ feature -- Helpers
|
|||||||
Result.append_string (" '" + st + "',")
|
Result.append_string (" '" + st + "',")
|
||||||
end
|
end
|
||||||
Result.append_string (" {")
|
Result.append_string (" {")
|
||||||
if attached a_language.params as l_params then
|
if attached a_language.parameters as l_params then
|
||||||
from
|
across
|
||||||
l_params.start
|
l_params as ic
|
||||||
until
|
|
||||||
l_params.after
|
|
||||||
loop
|
loop
|
||||||
Result.append ("'" + l_params.key_for_iteration + "':'"+ l_params.item_for_iteration + "',");
|
Result.append ("'" + ic.key + "':'"+ ic.item + "',");
|
||||||
l_params.forth
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Result.append ("})")
|
Result.append ("})")
|
||||||
@@ -137,7 +134,7 @@ feature -- Test routines
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
parser : HTTP_ACCEPT_LANGUAGE_PARSER
|
parser : HTTP_ACCEPT_LANGUAGE_UTILITIES
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -38,13 +38,10 @@ feature -- Helper
|
|||||||
end
|
end
|
||||||
Result.append_string (" {")
|
Result.append_string (" {")
|
||||||
if attached a_mediatype.parameters as l_params then
|
if attached a_mediatype.parameters as l_params then
|
||||||
from
|
across
|
||||||
l_params.start
|
l_params as ic
|
||||||
until
|
|
||||||
l_params.after
|
|
||||||
loop
|
loop
|
||||||
Result.append ("'" + l_params.key_for_iteration + "':'" + l_params.item_for_iteration + "',");
|
Result.append ("'" + ic.key + "':'" + ic.item + "',");
|
||||||
l_params.forth
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Result.append ("})")
|
Result.append ("})")
|
||||||
@@ -148,7 +145,7 @@ feature -- Test routines
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
parser : HTTP_ACCEPT_MEDIA_TYPE_PARSER
|
parser : HTTP_ACCEPT_MEDIA_TYPE_UTILITIES
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,6 @@ feature {NONE} -- Initialization
|
|||||||
t: STRING_8
|
t: STRING_8
|
||||||
i,n: INTEGER
|
i,n: INTEGER
|
||||||
p: INTEGER
|
p: INTEGER
|
||||||
cl: CELL [INTEGER]
|
|
||||||
do
|
do
|
||||||
-- Ignore starting space (should not be any)
|
-- Ignore starting space (should not be any)
|
||||||
from
|
from
|
||||||
@@ -79,15 +78,7 @@ feature {NONE} -- Initialization
|
|||||||
p := s.index_of (';', i)
|
p := s.index_of (';', i)
|
||||||
if p > 0 then
|
if p > 0 then
|
||||||
t := s.substring (i, p - 1)
|
t := s.substring (i, p - 1)
|
||||||
from
|
create parameters.make_from_substring (s, p + 1, s.count)
|
||||||
create cl.put (p)
|
|
||||||
i := p + 1
|
|
||||||
until
|
|
||||||
i >= n
|
|
||||||
loop
|
|
||||||
add_parameter_from_string (s, i, cl)
|
|
||||||
i := cl.item
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
t := s.substring (i, n)
|
t := s.substring (i, n)
|
||||||
end
|
end
|
||||||
@@ -116,7 +107,7 @@ feature {NONE} -- Initialization
|
|||||||
subtype := type
|
subtype := type
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
not has_error implies (create {HTTP_CONTENT_TYPE}.make_from_string (string)).same_string (string)
|
not has_error implies (create {HTTP_MEDIA_TYPE}.make_from_string (string)).same_string (string)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Status report
|
feature -- Status report
|
||||||
@@ -149,7 +140,7 @@ feature -- Access
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
parameters: detachable HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
|
parameters: detachable HTTP_PARAMETER_TABLE
|
||||||
-- Parameters
|
-- Parameters
|
||||||
|
|
||||||
feature -- Conversion
|
feature -- Conversion
|
||||||
@@ -262,7 +253,7 @@ feature -- Element change
|
|||||||
-- Remove parameter named `a_name'
|
-- Remove parameter named `a_name'
|
||||||
do
|
do
|
||||||
if attached parameters as plst then
|
if attached parameters as plst then
|
||||||
plst.prune (a_name)
|
plst.remove (a_name)
|
||||||
if plst.is_empty then
|
if plst.is_empty then
|
||||||
parameters := Void
|
parameters := Void
|
||||||
end
|
end
|
||||||
@@ -270,84 +261,6 @@ feature -- Element change
|
|||||||
internal_string := Void
|
internal_string := Void
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
|
||||||
|
|
||||||
add_parameter_from_string (s: READABLE_STRING_8; start_index: INTEGER; out_end_index: CELL [INTEGER])
|
|
||||||
-- Add parameter from string " attribute=value "
|
|
||||||
-- and put in `out_end_index' the index after found parameter.
|
|
||||||
local
|
|
||||||
n: INTEGER
|
|
||||||
pn,pv: STRING_8
|
|
||||||
i: INTEGER
|
|
||||||
p, q: INTEGER
|
|
||||||
err: BOOLEAN
|
|
||||||
do
|
|
||||||
n := s.count
|
|
||||||
-- Skip spaces
|
|
||||||
from
|
|
||||||
i := start_index
|
|
||||||
until
|
|
||||||
i > n or not s[i].is_space
|
|
||||||
loop
|
|
||||||
i := i + 1
|
|
||||||
end
|
|
||||||
if s[i] = ';' then
|
|
||||||
-- empty parameter
|
|
||||||
out_end_index.replace (i + 1)
|
|
||||||
elseif i < n then
|
|
||||||
p := s.index_of ('=', i)
|
|
||||||
if p > 0 then
|
|
||||||
pn := s.substring (i, p - 1)
|
|
||||||
if p >= n then
|
|
||||||
pv := ""
|
|
||||||
out_end_index.replace (n + 1)
|
|
||||||
else
|
|
||||||
if s[p+1] = '%"' then
|
|
||||||
q := s.index_of ('%"', p + 2)
|
|
||||||
if q > 0 then
|
|
||||||
pv := s.substring (p + 2, q - 1)
|
|
||||||
from
|
|
||||||
i := q + 1
|
|
||||||
until
|
|
||||||
i > n or not s[i].is_space
|
|
||||||
loop
|
|
||||||
i := i + 1
|
|
||||||
end
|
|
||||||
if s[i] = ';' then
|
|
||||||
i := i + 1
|
|
||||||
end
|
|
||||||
out_end_index.replace (i)
|
|
||||||
else
|
|
||||||
err := True
|
|
||||||
pv := ""
|
|
||||||
-- missing closing double quote.
|
|
||||||
end
|
|
||||||
else
|
|
||||||
q := s.index_of (';', p + 1)
|
|
||||||
if q = 0 then
|
|
||||||
q := n + 1
|
|
||||||
end
|
|
||||||
pv := s.substring (p + 1, q - 1)
|
|
||||||
out_end_index.replace (q + 1)
|
|
||||||
end
|
|
||||||
pv.right_adjust
|
|
||||||
if not err then
|
|
||||||
add_parameter (pn, pv)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- expecting: attribute "=" value
|
|
||||||
err := True
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if err then
|
|
||||||
out_end_index.replace (n + 1)
|
|
||||||
end
|
|
||||||
has_error := has_error or err
|
|
||||||
ensure
|
|
||||||
entry_processed: out_end_index.item > start_index
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Internal
|
feature {NONE} -- Internal
|
||||||
|
|
||||||
internal_string: detachable STRING_8
|
internal_string: detachable STRING_8
|
||||||
|
|||||||
150
library/network/protocol/http/src/http_parameter_table.e
Normal file
150
library/network/protocol/http/src/http_parameter_table.e
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
note
|
||||||
|
description: "[
|
||||||
|
Table representing parameters of the form q=1.0;note="blabla";foo=bar
|
||||||
|
]"
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
HTTP_PARAMETER_TABLE
|
||||||
|
|
||||||
|
inherit
|
||||||
|
HASH_TABLE [READABLE_STRING_8, STRING_8]
|
||||||
|
redefine
|
||||||
|
empty_duplicate
|
||||||
|
end
|
||||||
|
|
||||||
|
create
|
||||||
|
make,
|
||||||
|
make_from_string,
|
||||||
|
make_from_substring
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make_from_string (s: READABLE_STRING_8)
|
||||||
|
-- Build table of parameters for `s'
|
||||||
|
do
|
||||||
|
make_from_substring (s, 1, s.count)
|
||||||
|
end
|
||||||
|
|
||||||
|
make_from_substring (s: READABLE_STRING_8; a_start_index: INTEGER; a_end_index: INTEGER)
|
||||||
|
-- Build table of parameters for `s.substring (a_start_index, a_end_index)'
|
||||||
|
local
|
||||||
|
cl: CELL [INTEGER]
|
||||||
|
i: INTEGER
|
||||||
|
do
|
||||||
|
make (1)
|
||||||
|
from
|
||||||
|
i := a_start_index
|
||||||
|
create cl.put (i)
|
||||||
|
until
|
||||||
|
i >= a_end_index
|
||||||
|
loop
|
||||||
|
force_substring (s, i, cl)
|
||||||
|
i := cl.item
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
has_error: BOOLEAN
|
||||||
|
-- Current has error?
|
||||||
|
--| Mainly in relation with `make_from_string' and `force_substring'
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
force_substring (s: READABLE_STRING_8; start_index: INTEGER; out_end_index: CELL [INTEGER])
|
||||||
|
-- Add parameter from string " attribute=value "
|
||||||
|
-- and put in `out_end_index' the index after found parameter.
|
||||||
|
local
|
||||||
|
n: INTEGER
|
||||||
|
pn,pv: STRING_8
|
||||||
|
i: INTEGER
|
||||||
|
p, q: INTEGER
|
||||||
|
err: BOOLEAN
|
||||||
|
do
|
||||||
|
n := s.count
|
||||||
|
-- Skip spaces
|
||||||
|
from
|
||||||
|
i := start_index
|
||||||
|
until
|
||||||
|
i > n or not s[i].is_space
|
||||||
|
loop
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
if s[i] = ';' then
|
||||||
|
-- empty parameter
|
||||||
|
out_end_index.replace (i + 1)
|
||||||
|
elseif i < n then
|
||||||
|
p := s.index_of ('=', i)
|
||||||
|
if p > 0 then
|
||||||
|
pn := s.substring (i, p - 1)
|
||||||
|
if p >= n then
|
||||||
|
pv := ""
|
||||||
|
out_end_index.replace (n + 1)
|
||||||
|
else
|
||||||
|
if s[p+1] = '%"' then
|
||||||
|
q := s.index_of ('%"', p + 2)
|
||||||
|
if q > 0 then
|
||||||
|
pv := s.substring (p + 2, q - 1)
|
||||||
|
from
|
||||||
|
i := q + 1
|
||||||
|
until
|
||||||
|
i > n or not s[i].is_space
|
||||||
|
loop
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
if s[i] = ';' then
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
out_end_index.replace (i)
|
||||||
|
else
|
||||||
|
err := True
|
||||||
|
pv := ""
|
||||||
|
-- missing closing double quote.
|
||||||
|
end
|
||||||
|
else
|
||||||
|
q := s.index_of (';', p + 1)
|
||||||
|
if q = 0 then
|
||||||
|
q := n + 1
|
||||||
|
end
|
||||||
|
pv := s.substring (p + 1, q - 1)
|
||||||
|
out_end_index.replace (q + 1)
|
||||||
|
end
|
||||||
|
pv.right_adjust
|
||||||
|
if not err then
|
||||||
|
force (pv, pn)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- expecting: attribute "=" value
|
||||||
|
err := True
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if err then
|
||||||
|
out_end_index.replace (n + 1)
|
||||||
|
end
|
||||||
|
has_error := has_error or err
|
||||||
|
ensure
|
||||||
|
entry_processed: out_end_index.item > start_index
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Duplication
|
||||||
|
|
||||||
|
empty_duplicate (n: INTEGER): like Current
|
||||||
|
-- Create an empty copy of Current that can accommodate `n' items
|
||||||
|
do
|
||||||
|
Result := Precursor (n)
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Jocelyn Fiat, 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
|
||||||
@@ -167,12 +167,12 @@ feature -- Content negotiation
|
|||||||
res_attached: res /= Void
|
res_attached: res /= Void
|
||||||
a_handler_attached: a_handler /= Void
|
a_handler_attached: a_handler /= Void
|
||||||
local
|
local
|
||||||
l_conneg: CONNEG_SERVER_SIDE
|
l_conneg: SERVER_CONTENT_NEGOTIATION
|
||||||
h: HTTP_HEADER
|
h: HTTP_HEADER
|
||||||
l_media: MEDIA_TYPE_VARIANT_RESULTS
|
l_media: like {SERVER_CONTENT_NEGOTIATION}.media_type_preference
|
||||||
l_lang: LANGUAGE_VARIANT_RESULTS
|
l_lang: like {SERVER_CONTENT_NEGOTIATION}.language_preference
|
||||||
l_charset: CHARACTER_ENCODING_VARIANT_RESULTS
|
l_charset: like {SERVER_CONTENT_NEGOTIATION}.charset_preference
|
||||||
l_encoding: COMPRESSION_VARIANT_RESULTS
|
l_encoding: like {SERVER_CONTENT_NEGOTIATION}.encoding_preference
|
||||||
l_mime_types, l_langs, l_charsets, l_encodings: LIST [STRING]
|
l_mime_types, l_langs, l_charsets, l_encodings: LIST [STRING]
|
||||||
l_vary_star: BOOLEAN
|
l_vary_star: BOOLEAN
|
||||||
do
|
do
|
||||||
@@ -188,7 +188,7 @@ feature -- Content negotiation
|
|||||||
l_conneg := a_handler.conneg (req)
|
l_conneg := a_handler.conneg (req)
|
||||||
l_mime_types := a_handler.mime_types_supported (req)
|
l_mime_types := a_handler.mime_types_supported (req)
|
||||||
l_media := l_conneg.media_type_preference (l_mime_types, req.http_accept)
|
l_media := l_conneg.media_type_preference (l_mime_types, req.http_accept)
|
||||||
if not l_vary_star and l_mime_types.count > 1 and attached l_media.variant_header as l_media_variant then
|
if not l_vary_star and l_mime_types.count > 1 and attached l_media.media_type as l_media_variant then
|
||||||
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_media_variant)
|
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_media_variant)
|
||||||
end
|
end
|
||||||
if not l_media.is_acceptable then
|
if not l_media.is_acceptable then
|
||||||
@@ -196,26 +196,26 @@ feature -- Content negotiation
|
|||||||
else
|
else
|
||||||
l_langs := a_handler.languages_supported (req)
|
l_langs := a_handler.languages_supported (req)
|
||||||
l_lang := l_conneg.language_preference (l_langs, req.http_accept_language)
|
l_lang := l_conneg.language_preference (l_langs, req.http_accept_language)
|
||||||
if not l_vary_star and l_langs.count > 1 and attached l_lang.variant_header as l_lang_variant then
|
if not l_vary_star and l_langs.count > 1 and attached l_lang.language as l_lang_variant then
|
||||||
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_lang_variant)
|
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_lang_variant)
|
||||||
end
|
end
|
||||||
if not l_lang.is_acceptable then
|
if not l_lang.is_acceptable then
|
||||||
handle_not_acceptable ("None of the requested languages were acceptable", l_langs, req, res)
|
handle_not_acceptable ("None of the requested languages were acceptable", l_langs, req, res)
|
||||||
else
|
else
|
||||||
if attached l_lang.type as l_language_type then
|
if attached l_lang.language as l_language_type then
|
||||||
h.put_content_language (l_language_type)
|
h.put_content_language (l_language_type)
|
||||||
req.set_execution_variable (a_handler.Negotiated_language_execution_variable, l_language_type)
|
req.set_execution_variable (a_handler.Negotiated_language_execution_variable, l_language_type)
|
||||||
end
|
end
|
||||||
l_charsets := a_handler.charsets_supported (req)
|
l_charsets := a_handler.charsets_supported (req)
|
||||||
l_charset := l_conneg.charset_preference (l_charsets, req.http_accept_charset)
|
l_charset := l_conneg.charset_preference (l_charsets, req.http_accept_charset)
|
||||||
if not l_vary_star and l_charsets.count > 1 and attached l_charset.variant_header as l_charset_variant then
|
if not l_vary_star and l_charsets.count > 1 and attached l_charset.charset as l_charset_variant then
|
||||||
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_charset_variant)
|
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_charset_variant)
|
||||||
end
|
end
|
||||||
if not l_charset.is_acceptable then
|
if not l_charset.is_acceptable then
|
||||||
handle_not_acceptable ("None of the requested character encodings were acceptable", l_charsets, req, res)
|
handle_not_acceptable ("None of the requested character encodings were acceptable", l_charsets, req, res)
|
||||||
else
|
else
|
||||||
if attached l_media.type as l_media_type then
|
if attached l_media.media_type as l_media_type then
|
||||||
if attached l_charset.type as l_character_type then
|
if attached l_charset.charset as l_character_type then
|
||||||
h.put_content_type (l_media_type + "; charset=" + l_character_type)
|
h.put_content_type (l_media_type + "; charset=" + l_character_type)
|
||||||
req.set_execution_variable (a_handler.Negotiated_charset_execution_variable, l_charset)
|
req.set_execution_variable (a_handler.Negotiated_charset_execution_variable, l_charset)
|
||||||
else
|
else
|
||||||
@@ -225,13 +225,13 @@ feature -- Content negotiation
|
|||||||
end
|
end
|
||||||
l_encodings := a_handler.encodings_supported (req)
|
l_encodings := a_handler.encodings_supported (req)
|
||||||
l_encoding := l_conneg.encoding_preference (l_encodings, req.http_accept_encoding)
|
l_encoding := l_conneg.encoding_preference (l_encodings, req.http_accept_encoding)
|
||||||
if not l_vary_star and l_encodings.count > 1 and attached l_encoding.variant_header as l_encoding_variant then
|
if not l_vary_star and l_encodings.count > 1 and attached l_encoding.encoding as l_encoding_variant then
|
||||||
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_encoding_variant)
|
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_encoding_variant)
|
||||||
end
|
end
|
||||||
if not l_encoding.is_acceptable then
|
if not l_encoding.is_acceptable then
|
||||||
handle_not_acceptable ("None of the requested transfer encodings were acceptable", l_encodings, req, res)
|
handle_not_acceptable ("None of the requested transfer encodings were acceptable", l_encodings, req, res)
|
||||||
else
|
else
|
||||||
if attached l_encoding.type as l_compression_type then
|
if attached l_encoding.encoding as l_compression_type then
|
||||||
h.put_content_encoding (l_compression_type)
|
h.put_content_encoding (l_compression_type)
|
||||||
req.set_execution_variable (a_handler.Negotiated_encoding_execution_variable, l_compression_type)
|
req.set_execution_variable (a_handler.Negotiated_encoding_execution_variable, l_compression_type)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ feature -- Access
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
conneg (req: WSF_REQUEST): CONNEG_SERVER_SIDE
|
conneg (req: WSF_REQUEST): SERVER_CONTENT_NEGOTIATION
|
||||||
-- Content negotiation for `req';
|
-- Content negotiation for `req';
|
||||||
-- This would normally be a once object, ignoring `req'.
|
-- This would normally be a once object, ignoring `req'.
|
||||||
require
|
require
|
||||||
@@ -103,7 +103,7 @@ feature -- Access
|
|||||||
req_attached: req /= Void
|
req_attached: req /= Void
|
||||||
deferred
|
deferred
|
||||||
ensure
|
ensure
|
||||||
mime_types_supported_includes_default: Result.has (conneg (req).mime_default)
|
mime_types_supported_includes_default: Result.has (conneg (req).default_media_type)
|
||||||
end
|
end
|
||||||
|
|
||||||
languages_supported (req: WSF_REQUEST): LIST [STRING]
|
languages_supported (req: WSF_REQUEST): LIST [STRING]
|
||||||
@@ -112,7 +112,7 @@ feature -- Access
|
|||||||
req_attached: req /= Void
|
req_attached: req /= Void
|
||||||
deferred
|
deferred
|
||||||
ensure
|
ensure
|
||||||
languages_supported_includes_default: Result.has (conneg (req).language_default)
|
languages_supported_includes_default: Result.has (conneg (req).default_language)
|
||||||
end
|
end
|
||||||
|
|
||||||
charsets_supported (req: WSF_REQUEST): LIST [STRING]
|
charsets_supported (req: WSF_REQUEST): LIST [STRING]
|
||||||
@@ -121,7 +121,7 @@ feature -- Access
|
|||||||
req_attached: req /= Void
|
req_attached: req /= Void
|
||||||
deferred
|
deferred
|
||||||
ensure
|
ensure
|
||||||
charsets_supported_includes_default: Result.has (conneg (req).charset_default)
|
charsets_supported_includes_default: Result.has (conneg (req).default_charset)
|
||||||
end
|
end
|
||||||
|
|
||||||
encodings_supported (req: WSF_REQUEST): LIST [STRING]
|
encodings_supported (req: WSF_REQUEST): LIST [STRING]
|
||||||
@@ -130,7 +130,7 @@ feature -- Access
|
|||||||
req_attached: req /= Void
|
req_attached: req /= Void
|
||||||
deferred
|
deferred
|
||||||
ensure
|
ensure
|
||||||
encodings_supported_includes_default: Result.has (conneg (req).encoding_default)
|
encodings_supported_includes_default: Result.has (conneg (req).default_encoding)
|
||||||
end
|
end
|
||||||
|
|
||||||
additional_variant_headers (req: WSF_REQUEST): detachable LIST [STRING]
|
additional_variant_headers (req: WSF_REQUEST): detachable LIST [STRING]
|
||||||
|
|||||||
Reference in New Issue
Block a user