Added class HTTP_CONTENT_TYPE to help manipulation of Content-Type value
Now WSF_REQUEST return a HTTP_CONTENT_TYPE if available Adapted WSF_MIME_HANDLER to use this new class Added one manual autotest to test MIME handler
This commit is contained in:
318
library/protocol/http/src/http_content_type.e
Normal file
318
library/protocol/http/src/http_content_type.e
Normal file
@@ -0,0 +1,318 @@
|
|||||||
|
note
|
||||||
|
description: "[
|
||||||
|
CGI Meta variable define the CONTENT_TYPE entity
|
||||||
|
This class is to represent it as an object
|
||||||
|
|
||||||
|
the Internet Media Type [9] of the attached entity if the type
|
||||||
|
was provided via a "Content-type" field in the wgi_request header,
|
||||||
|
or if the server can determine it in the absence of a supplied
|
||||||
|
"Content-type" field. The syntax is the same as for the HTTP
|
||||||
|
"Content-Type" header field.
|
||||||
|
|
||||||
|
CONTENT_TYPE = "" | media-type
|
||||||
|
media-type = type "/" subtype *( ";" parameter)
|
||||||
|
type = token
|
||||||
|
subtype = token
|
||||||
|
parameter = attribute "=" value
|
||||||
|
attribute = token
|
||||||
|
value = token | quoted-string
|
||||||
|
|
||||||
|
The type, subtype, and parameter attribute names are not
|
||||||
|
case-sensitive. Parameter values MAY be case sensitive. Media
|
||||||
|
types and their use in HTTP are described in section 3.7 of
|
||||||
|
the HTTP/1.1 specification [8].
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
application/x-www-form-urlencoded
|
||||||
|
application/x-www-form-urlencoded; charset=UTF8
|
||||||
|
|
||||||
|
]"
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
HTTP_CONTENT_TYPE
|
||||||
|
|
||||||
|
inherit
|
||||||
|
DEBUG_OUTPUT
|
||||||
|
|
||||||
|
create
|
||||||
|
make,
|
||||||
|
make_from_content_type_header
|
||||||
|
|
||||||
|
convert
|
||||||
|
make_from_content_type_header ({READABLE_STRING_8, STRING_8, IMMUTABLE_STRING_8}),
|
||||||
|
string: {READABLE_STRING_8}
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make (a_type, a_subtype: READABLE_STRING_8)
|
||||||
|
-- Create Current based on `a_type/a_subtype'
|
||||||
|
require
|
||||||
|
not a_type.is_empty
|
||||||
|
not a_subtype.is_empty
|
||||||
|
do
|
||||||
|
type := a_type
|
||||||
|
subtype := a_subtype
|
||||||
|
ensure
|
||||||
|
has_no_error: not has_error
|
||||||
|
end
|
||||||
|
|
||||||
|
make_from_content_type_header (s: READABLE_STRING_8)
|
||||||
|
-- Create Current from `s'
|
||||||
|
-- if `s' does not respect the expected syntax, has_error is True
|
||||||
|
local
|
||||||
|
t: STRING_8
|
||||||
|
i,n: INTEGER
|
||||||
|
p: INTEGER
|
||||||
|
pn,pv: STRING_8
|
||||||
|
do
|
||||||
|
-- Ignore starting space (should not be any)
|
||||||
|
from
|
||||||
|
i := 1
|
||||||
|
n := s.count
|
||||||
|
until
|
||||||
|
i > n or not s[i].is_space
|
||||||
|
loop
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
if i < n then
|
||||||
|
-- Look for semi colon as parameter separation
|
||||||
|
p := s.index_of (';', i)
|
||||||
|
if p > 0 then
|
||||||
|
t := s.substring (i, p - 1)
|
||||||
|
-- Skip eventual space
|
||||||
|
i := p + 1
|
||||||
|
from
|
||||||
|
until
|
||||||
|
i > n or not s[i].is_space
|
||||||
|
loop
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
if i < n then
|
||||||
|
p := s.index_of ('=', i)
|
||||||
|
if p > 0 then
|
||||||
|
pn := s.substring (i, p - 1)
|
||||||
|
pv := s.substring (p + 1, n)
|
||||||
|
pv.right_adjust
|
||||||
|
if pv.count > 0 and pv [1] = '%"' then
|
||||||
|
if pv [pv.count] = '%"' then
|
||||||
|
pv := pv.substring (2, pv.count - 1)
|
||||||
|
else
|
||||||
|
has_error := True
|
||||||
|
-- missing closing double quote.
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not has_error then
|
||||||
|
set_parameter (pn, pv)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- expecting: attribute "=" value
|
||||||
|
has_error := True
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
t := s.substring (i, n)
|
||||||
|
end
|
||||||
|
-- Remove eventual trailing space
|
||||||
|
t.right_adjust
|
||||||
|
|
||||||
|
-- Extract type and subtype
|
||||||
|
p := t.index_of ('/', 1)
|
||||||
|
if p = 0 then
|
||||||
|
has_error := True
|
||||||
|
type := t
|
||||||
|
subtype := ""
|
||||||
|
else
|
||||||
|
subtype := t.substring (p + 1, t.count)
|
||||||
|
type := t
|
||||||
|
t.keep_head (p - 1)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
has_error := True
|
||||||
|
type := ""
|
||||||
|
subtype := type
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
not has_error implies (create {HTTP_CONTENT_TYPE}.make_from_content_type_header (string)).same_string (string)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
has_error: BOOLEAN
|
||||||
|
-- Current has error?
|
||||||
|
--| Mainly in relation with `make_from_content_type_header'
|
||||||
|
|
||||||
|
type: READABLE_STRING_8
|
||||||
|
-- Main type
|
||||||
|
|
||||||
|
subtype: READABLE_STRING_8
|
||||||
|
-- Sub type
|
||||||
|
|
||||||
|
has_parameter: BOOLEAN
|
||||||
|
-- Has Current a parameter?
|
||||||
|
do
|
||||||
|
Result := parameter_information /= Void
|
||||||
|
end
|
||||||
|
|
||||||
|
parameter (a_name: READABLE_STRING_8): detachable READABLE_STRING_8
|
||||||
|
-- Value for eventual parameter named `a_name'.
|
||||||
|
do
|
||||||
|
if has_parameter and then parameter_name.same_string (a_name) then
|
||||||
|
Result := parameter_value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
parameter_name: READABLE_STRING_8
|
||||||
|
-- Parameter's name if any.
|
||||||
|
require
|
||||||
|
has_parameter: has_parameter
|
||||||
|
do
|
||||||
|
if attached parameter_information as l_info then
|
||||||
|
Result := l_info.name
|
||||||
|
else
|
||||||
|
Result := ""
|
||||||
|
check has_parameter: False end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
parameter_value: READABLE_STRING_8
|
||||||
|
-- Parameter's value if any.
|
||||||
|
require
|
||||||
|
has_parameter: has_parameter
|
||||||
|
do
|
||||||
|
if attached parameter_information as l_info then
|
||||||
|
Result := l_info.value
|
||||||
|
else
|
||||||
|
Result := ""
|
||||||
|
check has_parameter: False end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Conversion
|
||||||
|
|
||||||
|
string: READABLE_STRING_8
|
||||||
|
-- String representation of type/subtype; attribute=value
|
||||||
|
local
|
||||||
|
res: like internal_string
|
||||||
|
do
|
||||||
|
res := internal_string
|
||||||
|
if res = Void then
|
||||||
|
create res.make_from_string (type_and_subtype_string)
|
||||||
|
if has_parameter then
|
||||||
|
res.append_character (';')
|
||||||
|
res.append_character (' ')
|
||||||
|
res.append (parameter_name)
|
||||||
|
res.append_character ('=')
|
||||||
|
res.append_character ('%"')
|
||||||
|
res.append (parameter_value)
|
||||||
|
res.append_character ('%"')
|
||||||
|
end
|
||||||
|
internal_string := res
|
||||||
|
end
|
||||||
|
Result := res
|
||||||
|
end
|
||||||
|
|
||||||
|
type_and_subtype_string: READABLE_STRING_8
|
||||||
|
-- String representation of type/subtype
|
||||||
|
local
|
||||||
|
res: like internal_type_and_subtype_string
|
||||||
|
s: like subtype
|
||||||
|
do
|
||||||
|
res := internal_type_and_subtype_string
|
||||||
|
if res = Void then
|
||||||
|
create res.make_from_string (type)
|
||||||
|
s := subtype
|
||||||
|
if not s.is_empty then
|
||||||
|
check has_error: has_error end
|
||||||
|
-- Just in case not is_valid, we keep in `type' the original string
|
||||||
|
res.append_character ('/')
|
||||||
|
res.append (s)
|
||||||
|
end
|
||||||
|
internal_type_and_subtype_string := res
|
||||||
|
end
|
||||||
|
Result := res
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Internal
|
||||||
|
|
||||||
|
internal_string: detachable STRING_8
|
||||||
|
|
||||||
|
internal_type_and_subtype_string: detachable STRING_8
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
same_as (other: HTTP_CONTENT_TYPE): BOOLEAN
|
||||||
|
do
|
||||||
|
Result := other.type.same_string (other.type) and then
|
||||||
|
other.subtype.same_string (other.subtype)
|
||||||
|
if Result then
|
||||||
|
Result := has_parameter = other.has_parameter
|
||||||
|
if has_parameter then
|
||||||
|
Result := parameter_name.same_string (other.parameter_name) and then
|
||||||
|
parameter_value.same_string (other.parameter_value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
same_type_and_subtype (s: READABLE_STRING_8): BOOLEAN
|
||||||
|
do
|
||||||
|
Result := type_and_subtype_string.same_string (s)
|
||||||
|
end
|
||||||
|
|
||||||
|
same_string (s: READABLE_STRING_8): BOOLEAN
|
||||||
|
do
|
||||||
|
Result := string.same_string (s)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Element change
|
||||||
|
|
||||||
|
set_parameter (a_name: like parameter_name; a_value: like parameter_value)
|
||||||
|
-- Set parameter for `a_name' to `a_value'
|
||||||
|
do
|
||||||
|
parameter_information := [a_name, a_value]
|
||||||
|
internal_string := Void
|
||||||
|
end
|
||||||
|
|
||||||
|
remove_parameter
|
||||||
|
-- Remove parameter
|
||||||
|
do
|
||||||
|
parameter_information := Void
|
||||||
|
internal_string := Void
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
parameter_information: detachable TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
debug_output: STRING
|
||||||
|
-- String that should be displayed in debugger to represent `Current'.
|
||||||
|
do
|
||||||
|
if type /= Void and subtype /= Void then
|
||||||
|
Result := type + "/" + subtype
|
||||||
|
if attached parameter_information as p_info then
|
||||||
|
Result.append ("; " + p_info.name + "=" + "%"" + p_info.value + "%"")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Result := ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
invariant
|
||||||
|
has_parameter implies parameter_name /= Void and parameter_value /= Void
|
||||||
|
type_and_subtype_not_empty: not has_error implies not type.is_empty and not subtype.is_empty
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2012, 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
|
||||||
@@ -28,7 +28,8 @@ create
|
|||||||
make,
|
make,
|
||||||
make_with_count,
|
make_with_count,
|
||||||
make_from_array,
|
make_from_array,
|
||||||
make_from_header
|
make_from_header,
|
||||||
|
make_from_raw_header_data
|
||||||
|
|
||||||
convert
|
convert
|
||||||
make_from_array ({ARRAY [TUPLE [key: READABLE_STRING_8; value: READABLE_STRING_8]]}),
|
make_from_array ({ARRAY [TUPLE [key: READABLE_STRING_8; value: READABLE_STRING_8]]}),
|
||||||
@@ -66,6 +67,27 @@ feature {NONE} -- Initialization
|
|||||||
append_header_object (a_header)
|
append_header_object (a_header)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
make_from_raw_header_data (h: READABLE_STRING_8)
|
||||||
|
-- Create Current from raw header data
|
||||||
|
local
|
||||||
|
line : detachable STRING
|
||||||
|
lines: LIST [READABLE_STRING_8]
|
||||||
|
do
|
||||||
|
lines := h.split ('%N')
|
||||||
|
make_with_count (lines.count)
|
||||||
|
across
|
||||||
|
lines as c
|
||||||
|
loop
|
||||||
|
line := c.item
|
||||||
|
if not line.is_empty then
|
||||||
|
if line[line.count] = '%R' then
|
||||||
|
line.remove_tail (1)
|
||||||
|
end
|
||||||
|
add_header (line)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Recycle
|
feature -- Recycle
|
||||||
|
|
||||||
recycle
|
recycle
|
||||||
@@ -100,6 +122,21 @@ feature -- Access
|
|||||||
result_has_single_ending_cr_lf: Result.count >= 4 implies not Result.substring (Result.count - 3, Result.count).same_string ("%R%N%R%N")
|
result_has_single_ending_cr_lf: Result.count >= 4 implies not Result.substring (Result.count - 3, Result.count).same_string ("%R%N%R%N")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
to_name_value_iterable: ITERABLE [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]]
|
||||||
|
local
|
||||||
|
res: ARRAYED_LIST [TUPLE [READABLE_STRING_8, READABLE_STRING_8]]
|
||||||
|
do
|
||||||
|
create res.make (headers.count)
|
||||||
|
across
|
||||||
|
headers as c
|
||||||
|
loop
|
||||||
|
if attached header_name_value (c.item) as tu then
|
||||||
|
res.extend (tu)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Result := res
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Header: filling
|
feature -- Header: filling
|
||||||
|
|
||||||
append_array (a_headers: ARRAY [TUPLE [key: READABLE_STRING_8; value: READABLE_STRING_8]])
|
append_array (a_headers: ARRAY [TUPLE [key: READABLE_STRING_8; value: READABLE_STRING_8]])
|
||||||
@@ -141,7 +178,7 @@ feature -- Header change: general
|
|||||||
require
|
require
|
||||||
h_not_empty: not h.is_empty
|
h_not_empty: not h.is_empty
|
||||||
do
|
do
|
||||||
force_header_by_name (header_name (h), h)
|
force_header_by_name (header_name_colon (h), h)
|
||||||
end
|
end
|
||||||
|
|
||||||
add_header_key_value (k,v: READABLE_STRING_8)
|
add_header_key_value (k,v: READABLE_STRING_8)
|
||||||
@@ -529,7 +566,7 @@ feature {NONE} -- Implementation: Header
|
|||||||
force_header_by_name (n: detachable READABLE_STRING_8; h: READABLE_STRING_8)
|
force_header_by_name (n: detachable READABLE_STRING_8; h: READABLE_STRING_8)
|
||||||
-- Add header `h' or replace existing header of same header name `n'
|
-- Add header `h' or replace existing header of same header name `n'
|
||||||
require
|
require
|
||||||
h_has_name_n: (n /= Void and attached header_name (h) as hn) implies n.same_string (hn)
|
h_has_name_n: (n /= Void and attached header_name_colon (h) as hn) implies n.same_string (hn)
|
||||||
local
|
local
|
||||||
l_headers: like headers
|
l_headers: like headers
|
||||||
do
|
do
|
||||||
@@ -552,7 +589,7 @@ feature {NONE} -- Implementation: Header
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
header_name (h: READABLE_STRING_8): detachable READABLE_STRING_8
|
header_name_colon (h: READABLE_STRING_8): detachable STRING_8
|
||||||
-- If any, header's name with colon
|
-- If any, header's name with colon
|
||||||
--| ex: for "Foo-bar: something", this will return "Foo-bar:"
|
--| ex: for "Foo-bar: something", this will return "Foo-bar:"
|
||||||
local
|
local
|
||||||
@@ -581,6 +618,36 @@ feature {NONE} -- Implementation: Header
|
|||||||
Result := s
|
Result := s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
header_name_value (h: READABLE_STRING_8): detachable TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]
|
||||||
|
-- If any, header's [name,value]
|
||||||
|
--| ex: for "Foo-bar: something", this will return ["Foo-bar", "something"]
|
||||||
|
local
|
||||||
|
s: detachable STRING_8
|
||||||
|
i,n: INTEGER
|
||||||
|
c: CHARACTER
|
||||||
|
do
|
||||||
|
from
|
||||||
|
i := 1
|
||||||
|
n := h.count
|
||||||
|
create s.make (10)
|
||||||
|
until
|
||||||
|
i > n or c = ':' or s = Void
|
||||||
|
loop
|
||||||
|
c := h[i]
|
||||||
|
inspect c
|
||||||
|
when ':' then
|
||||||
|
when '-', 'a' .. 'z', 'A' .. 'Z' then
|
||||||
|
s.extend (c)
|
||||||
|
else
|
||||||
|
s := Void
|
||||||
|
end
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
if s /= Void then
|
||||||
|
Result := [s, h.substring (i, n)]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
append_line_to (s: READABLE_STRING_8; h: STRING_8)
|
append_line_to (s: READABLE_STRING_8; h: STRING_8)
|
||||||
@@ -595,7 +662,7 @@ feature {NONE} -- Implementation
|
|||||||
h.append_character ('%N')
|
h.append_character ('%N')
|
||||||
end
|
end
|
||||||
|
|
||||||
date_to_rfc1123_http_date_format (dt: DATE_TIME): READABLE_STRING_8
|
date_to_rfc1123_http_date_format (dt: DATE_TIME): STRING_8
|
||||||
-- String representation of `dt' using the RFC 1123
|
-- String representation of `dt' using the RFC 1123
|
||||||
do
|
do
|
||||||
Result := dt.formatted_out ("ddd,[0]dd mmm yyyy [0]hh:[0]mi:[0]ss.ff2") + " GMT"
|
Result := dt.formatted_out ("ddd,[0]dd mmm yyyy [0]hh:[0]mi:[0]ss.ff2") + " GMT"
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for WGI_NULL_FILE_INPUT_STREAM."
|
||||||
|
legal: "See notice at end of class."
|
||||||
|
status: "See notice at end of class."
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
WGI_NULL_FILE_INPUT_STREAM
|
||||||
|
|
||||||
|
inherit
|
||||||
|
WGI_NULL_INPUT_STREAM
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make (f: FILE)
|
||||||
|
do
|
||||||
|
file := f
|
||||||
|
end
|
||||||
|
|
||||||
|
file: FILE
|
||||||
|
|
||||||
|
feature -- Input
|
||||||
|
|
||||||
|
read_character
|
||||||
|
-- Read the next character in input stream.
|
||||||
|
-- Make the result available in `last_character'
|
||||||
|
do
|
||||||
|
file.read_character
|
||||||
|
end
|
||||||
|
|
||||||
|
read_string (nb: INTEGER)
|
||||||
|
-- Read the next `nb' characters and
|
||||||
|
-- make the string result available in `last_string'
|
||||||
|
do
|
||||||
|
file.read_stream (nb)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
last_string: STRING_8
|
||||||
|
-- Last string read.
|
||||||
|
--
|
||||||
|
-- Note: this query *might* return the same object.
|
||||||
|
-- Therefore a clone should be used if the result
|
||||||
|
-- is to be kept beyond the next call to this feature.
|
||||||
|
-- However `last_string' is not shared between file objects.)
|
||||||
|
do
|
||||||
|
Result := file.last_string
|
||||||
|
end
|
||||||
|
|
||||||
|
last_character: CHARACTER_8
|
||||||
|
-- Last item read.
|
||||||
|
do
|
||||||
|
Result := file.last_character
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
is_open_read: BOOLEAN
|
||||||
|
-- Can items be read from input stream?
|
||||||
|
do
|
||||||
|
Result := file.is_open_read
|
||||||
|
end
|
||||||
|
|
||||||
|
end_of_input: BOOLEAN
|
||||||
|
-- Has the end of input stream been reached?
|
||||||
|
do
|
||||||
|
Result := file.end_of_file
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
invariant
|
||||||
|
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2012, 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
|
||||||
@@ -5,31 +5,12 @@ note
|
|||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
class
|
deferred class
|
||||||
WGI_NULL_INPUT_STREAM
|
WGI_NULL_INPUT_STREAM
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
WGI_INPUT_STREAM
|
WGI_INPUT_STREAM
|
||||||
undefine
|
|
||||||
read_to_string
|
|
||||||
end
|
|
||||||
|
|
||||||
CONSOLE
|
|
||||||
rename
|
|
||||||
make as console_make,
|
|
||||||
read_stream as read_string,
|
|
||||||
end_of_file as end_of_input
|
|
||||||
end
|
|
||||||
|
|
||||||
create
|
|
||||||
make
|
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
|
||||||
|
|
||||||
make
|
|
||||||
do
|
|
||||||
make_open_stdin ("stdin")
|
|
||||||
end
|
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2011, Eiffel Software and others"
|
copyright: "2011-2011, Eiffel Software and others"
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for WGI_NULL_STRING_INPUT_STREAM."
|
||||||
|
legal: "See notice at end of class."
|
||||||
|
status: "See notice at end of class."
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
WGI_NULL_STRING_INPUT_STREAM
|
||||||
|
|
||||||
|
inherit
|
||||||
|
WGI_NULL_INPUT_STREAM
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make (s: READABLE_STRING_8)
|
||||||
|
do
|
||||||
|
body := s
|
||||||
|
index := 1
|
||||||
|
count := s.count
|
||||||
|
last_string := ""
|
||||||
|
end
|
||||||
|
|
||||||
|
body: READABLE_STRING_8
|
||||||
|
|
||||||
|
index: INTEGER
|
||||||
|
|
||||||
|
count: INTEGER
|
||||||
|
|
||||||
|
feature -- Input
|
||||||
|
|
||||||
|
read_character
|
||||||
|
-- Read the next character in input stream.
|
||||||
|
-- Make the result available in `last_character'
|
||||||
|
do
|
||||||
|
last_character := body[index]
|
||||||
|
index := index + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
read_string (nb: INTEGER)
|
||||||
|
-- Read the next `nb' characters and
|
||||||
|
-- make the string result available in `last_string'
|
||||||
|
local
|
||||||
|
e: INTEGER
|
||||||
|
do
|
||||||
|
e := (index + nb).min (count)
|
||||||
|
last_string := body.substring (index, e)
|
||||||
|
index := e + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
last_string: STRING_8
|
||||||
|
|
||||||
|
last_character: CHARACTER_8
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
is_open_read: BOOLEAN
|
||||||
|
-- Can items be read from input stream?
|
||||||
|
do
|
||||||
|
Result := True
|
||||||
|
end
|
||||||
|
|
||||||
|
end_of_input: BOOLEAN
|
||||||
|
-- Has the end of input stream been reached?
|
||||||
|
do
|
||||||
|
Result := index > count
|
||||||
|
end
|
||||||
|
|
||||||
|
invariant
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2012, 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
|
||||||
@@ -14,14 +14,14 @@ inherit
|
|||||||
|
|
||||||
feature -- Status report
|
feature -- Status report
|
||||||
|
|
||||||
valid_content_type (a_content_type: READABLE_STRING_8): BOOLEAN
|
valid_content_type (a_content_type: HTTP_CONTENT_TYPE): BOOLEAN
|
||||||
do
|
do
|
||||||
Result := a_content_type.same_string ({HTTP_MIME_TYPES}.application_x_www_form_encoded)
|
Result := a_content_type.same_type_and_subtype ({HTTP_MIME_TYPES}.application_x_www_form_encoded)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Execution
|
feature -- Execution
|
||||||
|
|
||||||
handle (a_content_type: READABLE_STRING_8; req: WSF_REQUEST;
|
handle (a_content_type: HTTP_CONTENT_TYPE; req: WSF_REQUEST;
|
||||||
a_vars: HASH_TABLE [WSF_VALUE, READABLE_STRING_32]; a_raw_data: detachable CELL [detachable STRING_8])
|
a_vars: HASH_TABLE [WSF_VALUE, READABLE_STRING_32]; a_raw_data: detachable CELL [detachable STRING_8])
|
||||||
local
|
local
|
||||||
l_content: READABLE_STRING_8
|
l_content: READABLE_STRING_8
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ deferred class
|
|||||||
|
|
||||||
feature -- Status report
|
feature -- Status report
|
||||||
|
|
||||||
valid_content_type (a_content_type: READABLE_STRING_8): BOOLEAN
|
valid_content_type (a_content_type: HTTP_CONTENT_TYPE): BOOLEAN
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Execution
|
feature -- Execution
|
||||||
|
|
||||||
handle (a_content_type: READABLE_STRING_8; req: WSF_REQUEST;
|
handle (a_content_type: HTTP_CONTENT_TYPE; req: WSF_REQUEST;
|
||||||
a_vars: TABLE [WSF_VALUE, READABLE_STRING_32]; a_raw_data: detachable CELL [detachable STRING_8])
|
a_vars: TABLE [WSF_VALUE, READABLE_STRING_32]; a_raw_data: detachable CELL [detachable STRING_8])
|
||||||
-- Handle MIME content from request `req', eventually fill the `a_vars' (not yet available from `req')
|
-- Handle MIME content from request `req', eventually fill the `a_vars' (not yet available from `req')
|
||||||
-- and if `a_raw_data' is attached, store any read data inside `a_raw_data'
|
-- and if `a_raw_data' is attached, store any read data inside `a_raw_data'
|
||||||
|
|||||||
@@ -17,33 +17,21 @@ create
|
|||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
make (a_err_handler: like error_handler)
|
make
|
||||||
-- Instantiate Current
|
-- Instantiate Current
|
||||||
do
|
do
|
||||||
error_handler := a_err_handler
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Error handling
|
|
||||||
|
|
||||||
has_error: BOOLEAN
|
|
||||||
do
|
|
||||||
Result := error_handler.has_error
|
|
||||||
end
|
|
||||||
|
|
||||||
error_handler: ERROR_HANDLER
|
|
||||||
-- Error handler
|
|
||||||
-- By default initialized to new handler
|
|
||||||
|
|
||||||
feature -- Status report
|
feature -- Status report
|
||||||
|
|
||||||
valid_content_type (a_content_type: READABLE_STRING_8): BOOLEAN
|
valid_content_type (a_content_type: HTTP_CONTENT_TYPE): BOOLEAN
|
||||||
do
|
do
|
||||||
Result := a_content_type.starts_with ({HTTP_MIME_TYPES}.multipart_form_data)
|
Result := a_content_type.same_type_and_subtype ({HTTP_MIME_TYPES}.multipart_form_data)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Execution
|
feature -- Execution
|
||||||
|
|
||||||
handle (a_content_type: READABLE_STRING_8; req: WSF_REQUEST;
|
handle (a_content_type: HTTP_CONTENT_TYPE; req: WSF_REQUEST;
|
||||||
a_vars: HASH_TABLE [WSF_VALUE, READABLE_STRING_32]; a_raw_data: detachable CELL [detachable STRING_8])
|
a_vars: HASH_TABLE [WSF_VALUE, READABLE_STRING_32]; a_raw_data: detachable CELL [detachable STRING_8])
|
||||||
local
|
local
|
||||||
s: like full_input_data
|
s: like full_input_data
|
||||||
@@ -58,24 +46,23 @@ feature -- Execution
|
|||||||
|
|
||||||
feature {NONE} -- Implementation: Form analyzer
|
feature {NONE} -- Implementation: Form analyzer
|
||||||
|
|
||||||
analyze_multipart_form (req: WSF_REQUEST; t: READABLE_STRING_8; s: READABLE_STRING_8; vars: HASH_TABLE [WSF_VALUE, READABLE_STRING_32])
|
analyze_multipart_form (req: WSF_REQUEST; a_content_type: HTTP_CONTENT_TYPE; s: READABLE_STRING_8; vars: HASH_TABLE [WSF_VALUE, READABLE_STRING_32])
|
||||||
-- Analyze multipart form content
|
-- Analyze multipart form content
|
||||||
--| FIXME[2011-06-21]: integrate eMIME parser library
|
--| FIXME[2011-06-21]: integrate eMIME parser library
|
||||||
require
|
require
|
||||||
t_attached: t /= Void
|
a_content_type_valid: a_content_type /= Void and not a_content_type.has_error
|
||||||
s_attached: s /= Void
|
s_attached: s /= Void
|
||||||
vars_attached: vars /= Void
|
vars_attached: vars /= Void
|
||||||
local
|
local
|
||||||
p,i,next_b: INTEGER
|
p,i,next_b: INTEGER
|
||||||
l_boundary_prefix: STRING
|
l_boundary_prefix: STRING
|
||||||
l_boundary: STRING
|
|
||||||
l_boundary_len: INTEGER
|
l_boundary_len: INTEGER
|
||||||
|
l_boundary: detachable READABLE_STRING_8
|
||||||
m: STRING
|
m: STRING
|
||||||
is_crlf: BOOLEAN
|
is_crlf: BOOLEAN
|
||||||
do
|
do
|
||||||
p := t.substring_index ("boundary=", 1)
|
l_boundary := a_content_type.parameter ("boundary")
|
||||||
if p > 0 then
|
if l_boundary /= Void then
|
||||||
l_boundary := t.substring (p + 9, t.count)
|
|
||||||
p := s.substring_index (l_boundary, 1)
|
p := s.substring_index (l_boundary, 1)
|
||||||
if p > 1 then
|
if p > 1 then
|
||||||
l_boundary_prefix := s.substring (1, p - 1)
|
l_boundary_prefix := s.substring (1, p - 1)
|
||||||
@@ -116,7 +103,7 @@ feature {NONE} -- Implementation: Form analyzer
|
|||||||
m := s.substring (i - 1, s.count)
|
m := s.substring (i - 1, s.count)
|
||||||
m.right_adjust
|
m.right_adjust
|
||||||
if not l_boundary_prefix.same_string (m) then
|
if not l_boundary_prefix.same_string (m) then
|
||||||
error_handler.add_custom_error (0, "Invalid form data", "Invalid ending for form data from input")
|
req.error_handler.add_custom_error (0, "Invalid form data", "Invalid ending for form data from input")
|
||||||
end
|
end
|
||||||
i := next_b
|
i := next_b
|
||||||
end
|
end
|
||||||
@@ -235,10 +222,10 @@ feature {NONE} -- Implementation: Form analyzer
|
|||||||
add_string_value_to_table (l_name, l_content, vars)
|
add_string_value_to_table (l_name, l_content, vars)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
error_handler.add_custom_error (0, "unamed multipart entry", Void)
|
req.error_handler.add_custom_error (0, "unamed multipart entry", Void)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
error_handler.add_custom_error (0, "missformed multipart entry", Void)
|
req.error_handler.add_custom_error (0, "missformed multipart entry", Void)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -22,15 +22,15 @@ note
|
|||||||
class
|
class
|
||||||
WSF_HEADER
|
WSF_HEADER
|
||||||
|
|
||||||
obsolete "Use HTTP_HEADER [2011-nov-25]"
|
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
HTTP_HEADER
|
HTTP_HEADER
|
||||||
|
|
||||||
create
|
create
|
||||||
make,
|
make,
|
||||||
make_with_count
|
make_with_count,
|
||||||
|
make_from_array,
|
||||||
|
make_from_header,
|
||||||
|
make_from_raw_header_data
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||||
|
|||||||
@@ -77,6 +77,14 @@ feature {NONE} -- Initialization
|
|||||||
content_length_value := 0
|
content_length_value := 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Content-Type
|
||||||
|
s8 := wgi_request.content_type
|
||||||
|
if s8 /= Void then
|
||||||
|
content_type := s8
|
||||||
|
else
|
||||||
|
content_type := Void
|
||||||
|
end
|
||||||
|
|
||||||
--| PATH_INFO
|
--| PATH_INFO
|
||||||
path_info := url_encoder.decoded_string (wgi_request.path_info)
|
path_info := url_encoder.decoded_string (wgi_request.path_info)
|
||||||
|
|
||||||
@@ -396,7 +404,7 @@ feature -- Access: CGI meta parameters - 1.1
|
|||||||
content_length_value: NATURAL_64
|
content_length_value: NATURAL_64
|
||||||
-- Integer value related to `content_length"
|
-- Integer value related to `content_length"
|
||||||
|
|
||||||
content_type: detachable READABLE_STRING_8
|
content_type: detachable HTTP_CONTENT_TYPE
|
||||||
-- If the wgi_request includes a message-body, CONTENT_TYPE is set to
|
-- If the wgi_request includes a message-body, CONTENT_TYPE is set to
|
||||||
-- the Internet Media Type [9] of the attached entity if the type
|
-- the Internet Media Type [9] of the attached entity if the type
|
||||||
-- was provided via a "Content-type" field in the wgi_request header,
|
-- was provided via a "Content-type" field in the wgi_request header,
|
||||||
@@ -436,9 +444,6 @@ feature -- Access: CGI meta parameters - 1.1
|
|||||||
-- determine the correct datatype, or it MAY omit this
|
-- determine the correct datatype, or it MAY omit this
|
||||||
-- metavariable when communicating the wgi_request information to the
|
-- metavariable when communicating the wgi_request information to the
|
||||||
-- script.
|
-- script.
|
||||||
do
|
|
||||||
Result := wgi_request.content_type
|
|
||||||
end
|
|
||||||
|
|
||||||
gateway_interface: READABLE_STRING_8
|
gateway_interface: READABLE_STRING_8
|
||||||
-- This metavariable is set to the dialect of CGI being used by
|
-- This metavariable is set to the dialect of CGI being used by
|
||||||
@@ -1145,7 +1150,7 @@ feature -- Access: MIME handler
|
|||||||
hdls.force (a_handler)
|
hdls.force (a_handler)
|
||||||
end
|
end
|
||||||
|
|
||||||
mime_handler (a_content_type: READABLE_STRING_8): detachable WSF_MIME_HANDLER
|
mime_handler (a_content_type: HTTP_CONTENT_TYPE): detachable WSF_MIME_HANDLER
|
||||||
-- Mime handler associated with `a_content_type'
|
-- Mime handler associated with `a_content_type'
|
||||||
do
|
do
|
||||||
if attached mime_handlers as hdls then
|
if attached mime_handlers as hdls then
|
||||||
@@ -1169,7 +1174,7 @@ feature {NONE} -- Implementation: MIME handler
|
|||||||
|
|
||||||
init_mime_handlers
|
init_mime_handlers
|
||||||
do
|
do
|
||||||
register_mime_handler (create {WSF_MULTIPART_FORM_DATA_HANDLER}.make (error_handler))
|
register_mime_handler (create {WSF_MULTIPART_FORM_DATA_HANDLER}.make)
|
||||||
register_mime_handler (create {WSF_APPLICATION_X_WWW_FORM_URLENCODED_HANDLER})
|
register_mime_handler (create {WSF_APPLICATION_X_WWW_FORM_URLENCODED_HANDLER})
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1566,7 +1571,7 @@ feature {NONE} -- Implementation: utilities
|
|||||||
|
|
||||||
invariant
|
invariant
|
||||||
empty_string_unchanged: empty_string.is_empty
|
empty_string_unchanged: empty_string.is_empty
|
||||||
|
wgi_request.content_type /= Void implies content_type /= Void
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||||
|
|||||||
118
library/server/wsf/tests/src/test_wsf_request_mime_handler.e
Normal file
118
library/server/wsf/tests/src/test_wsf_request_mime_handler.e
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
note
|
||||||
|
description: "[
|
||||||
|
Eiffel tests that can be executed by testing tool.
|
||||||
|
]"
|
||||||
|
author: "EiffelStudio test wizard"
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
testing: "type/manual"
|
||||||
|
|
||||||
|
class
|
||||||
|
TEST_WSF_REQUEST_MIME_HANDLER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
EQA_TEST_SET
|
||||||
|
|
||||||
|
WSF_SERVICE
|
||||||
|
undefine
|
||||||
|
default_create
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Events
|
||||||
|
|
||||||
|
port_number: INTEGER
|
||||||
|
base_url: detachable STRING
|
||||||
|
|
||||||
|
feature -- Execution
|
||||||
|
|
||||||
|
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
do
|
||||||
|
--| do nothing
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Tests
|
||||||
|
|
||||||
|
test_mime_handler
|
||||||
|
local
|
||||||
|
req: WSF_REQUEST
|
||||||
|
b: STRING_8
|
||||||
|
h: WSF_HEADER
|
||||||
|
ct: HTTP_CONTENT_TYPE
|
||||||
|
m: ARRAY [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]]
|
||||||
|
do
|
||||||
|
m := <<
|
||||||
|
["REQUEST_METHOD", "GET"],
|
||||||
|
["QUERY_STRING", ""],
|
||||||
|
["REQUEST_URI", "/auto/test/foo"],
|
||||||
|
["SCRIPT_NAME", "/auto/test/test.ews"],
|
||||||
|
["PATH_INFO", "/foo"]
|
||||||
|
>>
|
||||||
|
|
||||||
|
create ct.make_from_content_type_header ({HTTP_MIME_TYPES}.multipart_form_data)
|
||||||
|
ct.set_parameter ("boundary", "__=_the_boundary_1332296477_1804289383_=__")
|
||||||
|
create h.make
|
||||||
|
h.put_content_type (ct)
|
||||||
|
|
||||||
|
b := "[
|
||||||
|
--__=_the_boundary_1332296477_1804289383_=__
|
||||||
|
Content-Disposition: form-data; name="user_name"
|
||||||
|
|
||||||
|
EWFdemo
|
||||||
|
--__=_the_boundary_1332296477_1804289383_=__
|
||||||
|
Content-Disposition: form-data; name="password"
|
||||||
|
|
||||||
|
EWFpassword
|
||||||
|
--__=_the_boundary_1332296477_1804289383_=__--
|
||||||
|
]"
|
||||||
|
|
||||||
|
h.put_content_length (b.count)
|
||||||
|
|
||||||
|
--| Case #1
|
||||||
|
req := new_request (m, h.string, b)
|
||||||
|
assert ("found user_name", attached req.form_parameter ("user_name") as u and then u.same_string ("EWFdemo"))
|
||||||
|
assert ("found password", attached req.form_parameter ("password") as u and then u.same_string ("EWFpassword"))
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
new_request (a_meta: ARRAY [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]]; h: READABLE_STRING_8; s: READABLE_STRING_8): WSF_REQUEST_NULL
|
||||||
|
local
|
||||||
|
wgi_req: WGI_REQUEST
|
||||||
|
l_header: WSF_HEADER
|
||||||
|
lst: ARRAYED_LIST [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]]
|
||||||
|
vn: STRING_8
|
||||||
|
do
|
||||||
|
create lst.make (10)
|
||||||
|
across
|
||||||
|
a_meta as c
|
||||||
|
loop
|
||||||
|
lst.extend (c.item)
|
||||||
|
end
|
||||||
|
|
||||||
|
create l_header.make_from_raw_header_data (h)
|
||||||
|
across
|
||||||
|
l_header.to_name_value_iterable as c
|
||||||
|
loop
|
||||||
|
--| for Any Abc-Def-Ghi add (or replace) the HTTP_ABC_DEF_GHI variable to `env'
|
||||||
|
vn := c.item.name.as_upper
|
||||||
|
|
||||||
|
vn.replace_substring_all ("-", "_")
|
||||||
|
if
|
||||||
|
vn.starts_with ("CONTENT_") and then
|
||||||
|
(vn.same_string_general ({WGI_META_NAMES}.content_type) or vn.same_string_general ({WGI_META_NAMES}.content_length))
|
||||||
|
then
|
||||||
|
--| Keep this name
|
||||||
|
else
|
||||||
|
vn.prepend ("HTTP_")
|
||||||
|
end
|
||||||
|
lst.extend ([vn, c.item.value])
|
||||||
|
-- lst.extend (c.item)
|
||||||
|
end
|
||||||
|
|
||||||
|
create {WGI_REQUEST_NULL} wgi_req.make_with_body (lst, s)
|
||||||
|
create Result.make_from_wgi (wgi_req)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ feature {NONE} -- Implementation
|
|||||||
local
|
local
|
||||||
wgi_req: WGI_REQUEST
|
wgi_req: WGI_REQUEST
|
||||||
do
|
do
|
||||||
create {WGI_REQUEST_NULL} wgi_req.make (a_meta)
|
create {WGI_REQUEST_NULL} wgi_req.make_with_file (a_meta, io.input)
|
||||||
create Result.make_from_wgi (wgi_req)
|
create Result.make_from_wgi (wgi_req)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -14,19 +14,20 @@ inherit
|
|||||||
end
|
end
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make_with_file,
|
||||||
|
make_with_body
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
make (a_meta: ARRAY [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]])
|
make_with_file (a_meta: ITERABLE [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]]; f: FILE)
|
||||||
local
|
local
|
||||||
ht: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
|
ht: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
|
||||||
i: WGI_NULL_INPUT_STREAM
|
i: WGI_NULL_FILE_INPUT_STREAM
|
||||||
c: WGI_NULL_CONNECTOR
|
c: WGI_NULL_CONNECTOR
|
||||||
do
|
do
|
||||||
create c.make
|
create c.make
|
||||||
create i.make
|
create i.make (f)
|
||||||
create ht.make (a_meta.count)
|
create ht.make (10)
|
||||||
across
|
across
|
||||||
a_meta as curs
|
a_meta as curs
|
||||||
loop
|
loop
|
||||||
@@ -35,6 +36,22 @@ feature {NONE} -- Initialization
|
|||||||
wgi_request_from_table_make (ht, i, c)
|
wgi_request_from_table_make (ht, i, c)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
make_with_body (a_meta: ITERABLE [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]]; s: READABLE_STRING_8)
|
||||||
|
local
|
||||||
|
ht: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
|
||||||
|
i: WGI_NULL_STRING_INPUT_STREAM
|
||||||
|
c: WGI_NULL_CONNECTOR
|
||||||
|
do
|
||||||
|
create c.make
|
||||||
|
create i.make (s)
|
||||||
|
create ht.make (10)
|
||||||
|
across
|
||||||
|
a_meta as curs
|
||||||
|
loop
|
||||||
|
ht.force (curs.item.value, curs.item.name)
|
||||||
|
end
|
||||||
|
wgi_request_from_table_make (ht, i, c)
|
||||||
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2011, Eiffel Software and others"
|
copyright: "2011-2011, Eiffel Software and others"
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
<library name="http_client" location="..\..\..\client\http_client\http_client-safe.ecf" readonly="false"/>
|
<library name="http_client" location="..\..\..\client\http_client\http_client-safe.ecf" readonly="false"/>
|
||||||
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
|
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
|
||||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
|
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
|
||||||
|
<library name="http" location="..\..\..\protocol\http\http-safe.ecf" readonly="false"/>
|
||||||
<library name="wsf" location="..\wsf-safe.ecf" readonly="false"/>
|
<library name="wsf" location="..\wsf-safe.ecf" readonly="false"/>
|
||||||
<tests name="src" location=".\src\" recursive="true"/>
|
<tests name="src" location=".\src\" recursive="true"/>
|
||||||
</target>
|
</target>
|
||||||
|
|||||||
Reference in New Issue
Block a user