Added support for chunked input data (see Transfer-Encoding: chunked)
This commit is contained in:
@@ -46,6 +46,8 @@ feature -- Access
|
||||
|
||||
http_referer: STRING = "HTTP_REFERER"
|
||||
|
||||
http_transfer_encoding: STRING = "HTTP_TRANSFER_ENCODING"
|
||||
|
||||
gateway_interface: STRING = "GATEWAY_INTERFACE"
|
||||
|
||||
auth_type: STRING = "AUTH_TYPE"
|
||||
@@ -77,7 +79,7 @@ feature -- Extra names
|
||||
orig_path_info: STRING = "ORIG_PATH_INFO"
|
||||
|
||||
note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
copyright: "2011-2012, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -77,6 +77,20 @@ feature -- Access: Input
|
||||
|
||||
input: WGI_INPUT_STREAM
|
||||
-- Server input channel
|
||||
require
|
||||
is_not_chunked_input: not is_chunked_input
|
||||
deferred
|
||||
end
|
||||
|
||||
is_chunked_input: BOOLEAN
|
||||
-- Is request using chunked transfer-encoding?
|
||||
deferred
|
||||
end
|
||||
|
||||
chunked_input: detachable WGI_CHUNKED_INPUT_STREAM
|
||||
-- Chunked server input channel
|
||||
require
|
||||
is_chunked_input: is_chunked_input
|
||||
deferred
|
||||
end
|
||||
|
||||
@@ -580,6 +594,12 @@ feature -- HTTP_*
|
||||
deferred
|
||||
end
|
||||
|
||||
http_transfer_encoding: detachable READABLE_STRING_8
|
||||
-- Transfer-Encoding
|
||||
-- for instance chunked
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Extra CGI environment variables
|
||||
|
||||
request_uri: READABLE_STRING_8
|
||||
@@ -606,7 +626,7 @@ invariant
|
||||
path_info_identical: path_info ~ meta_string_variable ({WGI_META_NAMES}.path_info)
|
||||
|
||||
note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
copyright: "2011-2012, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -26,15 +26,24 @@ feature {NONE} -- Initialization
|
||||
wgi_connector := a_wgi_connector
|
||||
input := a_input
|
||||
set_meta_variables (a_vars)
|
||||
|
||||
update_path_info
|
||||
if attached http_transfer_encoding as l_transfer_encoding and then l_transfer_encoding.same_string ("chunked") then
|
||||
is_chunked_input := True
|
||||
create chunked_input.make (a_input)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access: Input
|
||||
|
||||
is_chunked_input: BOOLEAN
|
||||
-- Is request using chunked transfer-encoding?
|
||||
|
||||
input: WGI_INPUT_STREAM
|
||||
-- Server input channel
|
||||
|
||||
chunked_input: detachable WGI_CHUNKED_INPUT_STREAM
|
||||
-- Chunked server input channel
|
||||
|
||||
feature -- EWSGI access
|
||||
|
||||
wgi_version: STRING = "0.1"
|
||||
@@ -211,6 +220,13 @@ feature -- Access: HTTP_* CGI meta parameters - 1.1
|
||||
Result := meta_string_variable ({WGI_META_NAMES}.http_authorization)
|
||||
end
|
||||
|
||||
http_transfer_encoding: detachable READABLE_STRING_8
|
||||
-- Transfer-Encoding
|
||||
-- for instance chunked
|
||||
do
|
||||
Result := meta_string_variable ({WGI_META_NAMES}.http_transfer_encoding)
|
||||
end
|
||||
|
||||
feature -- Access: Extension to CGI meta parameters - 1.1
|
||||
|
||||
request_uri: READABLE_STRING_8
|
||||
@@ -340,20 +356,6 @@ feature {NONE} -- Element change: CGI meta parameter related to PATH_INFO
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- I/O: implementation
|
||||
|
||||
read_input (nb: INTEGER)
|
||||
-- Read `nb' bytes from `input'
|
||||
do
|
||||
input.read_string (nb)
|
||||
end
|
||||
|
||||
last_input_string: STRING
|
||||
-- Last string read from `input'
|
||||
do
|
||||
Result := input.last_string
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: utilities
|
||||
|
||||
single_slash_starting_string (s: READABLE_STRING_8): STRING_8
|
||||
|
||||
@@ -6,118 +6,167 @@ note
|
||||
|
||||
class
|
||||
WGI_CHUNKED_INPUT_STREAM
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
make ( an_input : like input)
|
||||
|
||||
make (an_input: like input)
|
||||
do
|
||||
create last_chunked.make_empty
|
||||
create last_chunk_size.make_empty
|
||||
create tmp_hex_chunk_size.make_empty
|
||||
input := an_input
|
||||
end
|
||||
|
||||
feature --Input
|
||||
read
|
||||
-- Read all the data in a chunked stream.
|
||||
-- Make the result available in `last_chunked'.
|
||||
-- Chunked-Body = *chunk
|
||||
-- last-chunk
|
||||
-- trailer
|
||||
-- CRLF
|
||||
-- chunk = chunk-size [ chunk-extension ] CRLF
|
||||
-- chunk-data CRLF
|
||||
-- chunk-size = 1*HEX
|
||||
-- last-chunk = 1*("0") [ chunk-extension ] CRLF
|
||||
-- chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
|
||||
-- chunk-ext-name = token
|
||||
-- chunk-ext-val = token | quoted-string
|
||||
-- chunk-data = chunk-size(OCTET)
|
||||
-- trailer = *(entity-header CRLF)
|
||||
feature -- Input
|
||||
|
||||
data: READABLE_STRING_8
|
||||
local
|
||||
d: like internal_data
|
||||
do
|
||||
d := internal_data
|
||||
if d = Void then
|
||||
d := fetched_data
|
||||
internal_data := d
|
||||
end
|
||||
Result := d
|
||||
end
|
||||
|
||||
feature {NONE} -- Parser
|
||||
|
||||
internal_data: detachable READABLE_STRING_8
|
||||
|
||||
tmp_hex_chunk_size: STRING_8
|
||||
last_chunk_size: INTEGER
|
||||
last_chunk: detachable STRING_8
|
||||
|
||||
fetched_data: READABLE_STRING_8
|
||||
-- Read all the data in a chunked stream.
|
||||
-- Make the result available in `last_chunked'.
|
||||
-- Chunked-Body = *chunk
|
||||
-- last-chunk
|
||||
-- trailer
|
||||
-- CRLF
|
||||
-- chunk = chunk-size [ chunk-extension ] CRLF
|
||||
-- chunk-data CRLF
|
||||
-- chunk-size = 1*HEX
|
||||
-- last-chunk = 1*("0") [ chunk-extension ] CRLF
|
||||
-- chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
|
||||
-- chunk-ext-name = token
|
||||
-- chunk-ext-val = token | quoted-string
|
||||
-- chunk-data = chunk-size(OCTET)
|
||||
-- trailer = *(entity-header CRLF)
|
||||
local
|
||||
eoc : BOOLEAN
|
||||
s: STRING_8
|
||||
do
|
||||
from
|
||||
read_chunk
|
||||
last_chunked.append (input.last_string)
|
||||
if last_chunk_size.is_equal ("0") then
|
||||
eoc := true
|
||||
end
|
||||
create s.make (1024)
|
||||
until
|
||||
eoc
|
||||
loop
|
||||
read_chunk
|
||||
last_chunked.append (input.last_string)
|
||||
if last_chunk_size.is_equal ("0") then
|
||||
if attached last_chunk as l_last_chunk then
|
||||
s.append (l_last_chunk)
|
||||
else
|
||||
eoc := true
|
||||
end
|
||||
if last_chunk_size = 0 then
|
||||
eoc := True
|
||||
end
|
||||
end
|
||||
|
||||
read_trailer
|
||||
|
||||
Result := s
|
||||
end
|
||||
|
||||
feature {NONE} -- Parser
|
||||
last_chunk_size : STRING
|
||||
reset_chunk
|
||||
do
|
||||
last_chunk := Void
|
||||
last_chunk_size := 0
|
||||
end
|
||||
|
||||
read_chunk
|
||||
do
|
||||
-- clear last results
|
||||
last_chunk_size.wipe_out
|
||||
|
||||
-- new read
|
||||
reset_chunk
|
||||
read_chunk_size
|
||||
read_chunk_data
|
||||
if last_chunk_size > 0 then
|
||||
read_chunk_data
|
||||
end
|
||||
end
|
||||
|
||||
read_chunk_data
|
||||
local
|
||||
hex : HEXADECIMAL_STRING_TO_INTEGER_CONVERTER
|
||||
require
|
||||
last_chunk_size > 0
|
||||
do
|
||||
create hex.make
|
||||
hex.parse_string_with_type (last_chunk_size, hex.type_integer)
|
||||
if hex.parse_successful then
|
||||
input.read_string (hex.parsed_integer)
|
||||
end
|
||||
input.read_string (last_chunk_size)
|
||||
last_chunk := input.last_string
|
||||
|
||||
-- read CRLF
|
||||
input.read_character
|
||||
if input.last_character.is_equal ('%R') then
|
||||
if input.last_character = '%R' then
|
||||
input.read_character
|
||||
end
|
||||
ensure
|
||||
last_chunk_attached: attached last_chunk as el_last_chunk
|
||||
last_chunk_size_ok: el_last_chunk.count = last_chunk_size
|
||||
end
|
||||
|
||||
read_chunk_size
|
||||
require
|
||||
tmp_hex_chunk_size_is_empty: tmp_hex_chunk_size.is_empty
|
||||
local
|
||||
eol : BOOLEAN
|
||||
c: CHARACTER
|
||||
hex : HEXADECIMAL_STRING_TO_INTEGER_CONVERTER
|
||||
do
|
||||
from
|
||||
input.read_character
|
||||
until
|
||||
eol
|
||||
loop
|
||||
|
||||
if input.last_character.is_equal ('%R') then
|
||||
c := input.last_character
|
||||
inspect c
|
||||
when '%R' then
|
||||
-- We are in the end of the line, we need to read the next character to start the next line.
|
||||
eol := True
|
||||
input.read_character
|
||||
eol := true
|
||||
elseif input.last_character.is_equal (';') then
|
||||
when ';' then
|
||||
-- We are in an extension chunk data
|
||||
read_extension_chunk
|
||||
else
|
||||
last_chunk_size.append_character (input.last_character)
|
||||
tmp_hex_chunk_size.append_character (c)
|
||||
input.read_character
|
||||
end
|
||||
end
|
||||
if tmp_hex_chunk_size.same_string ("0") then
|
||||
last_chunk_size := 0
|
||||
else
|
||||
create hex.make
|
||||
hex.parse_string_with_type (tmp_hex_chunk_size, hex.type_integer)
|
||||
if hex.parse_successful then
|
||||
last_chunk_size := hex.parsed_integer
|
||||
else
|
||||
last_chunk_size := 0 -- ERROR ...
|
||||
end
|
||||
end
|
||||
tmp_hex_chunk_size.wipe_out
|
||||
end
|
||||
|
||||
read_extension_chunk
|
||||
do
|
||||
print (" Reading extension chunk ")
|
||||
debug
|
||||
print (" Reading extension chunk ")
|
||||
end
|
||||
from
|
||||
input.read_character
|
||||
until
|
||||
input.last_character.is_equal ('%R')
|
||||
input.last_character = '%R'
|
||||
loop
|
||||
print (input.last_character)
|
||||
debug
|
||||
print (input.last_character)
|
||||
end
|
||||
input.read_character
|
||||
end
|
||||
end
|
||||
@@ -125,29 +174,31 @@ feature {NONE} -- Parser
|
||||
read_trailer
|
||||
do
|
||||
if not input.end_of_input then
|
||||
print (" Reading trailer ")
|
||||
debug
|
||||
print (" Reading trailer ")
|
||||
end
|
||||
from
|
||||
input.read_character
|
||||
until
|
||||
input.last_character.is_equal ('%R')
|
||||
input.last_character = '%R'
|
||||
loop
|
||||
print (input.last_character)
|
||||
debug
|
||||
print (input.last_character)
|
||||
end
|
||||
input.read_character
|
||||
end
|
||||
-- read the LF
|
||||
input.read_character
|
||||
end
|
||||
end
|
||||
feature {NONE} -- Access
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
input: WGI_INPUT_STREAM
|
||||
-- Input Stream
|
||||
|
||||
feature -- Access
|
||||
last_chunked: STRING_8
|
||||
|
||||
;note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
copyright: "2011-2012, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -9,6 +9,20 @@ deferred class
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
full_input_data (req: WSF_REQUEST): READABLE_STRING_8
|
||||
do
|
||||
if req.is_chunked_input then
|
||||
if attached req.chunked_input as l_chunked_input then
|
||||
Result := l_chunked_input.data
|
||||
else
|
||||
check has_chunked_input: False end
|
||||
Result := ""
|
||||
end
|
||||
else
|
||||
Result := read_input_data (req.input, req.content_length_value)
|
||||
end
|
||||
end
|
||||
|
||||
read_input_data (a_input: WGI_INPUT_STREAM; nb: NATURAL_64): READABLE_STRING_8
|
||||
-- All data from input form
|
||||
local
|
||||
|
||||
@@ -21,7 +21,7 @@ feature -- Status report
|
||||
|
||||
feature -- Execution
|
||||
|
||||
handle (a_content_type: READABLE_STRING_8; a_content_length: NATURAL_64; req: WSF_REQUEST;
|
||||
handle (a_content_type: READABLE_STRING_8; req: WSF_REQUEST;
|
||||
a_vars: HASH_TABLE [WSF_VALUE, READABLE_STRING_32]; a_raw_data: detachable CELL [detachable STRING_8])
|
||||
local
|
||||
l_content: READABLE_STRING_8
|
||||
@@ -29,12 +29,12 @@ feature -- Execution
|
||||
s: READABLE_STRING_8
|
||||
l_name, l_value: READABLE_STRING_8
|
||||
do
|
||||
l_content := read_input_data (req.input, a_content_length)
|
||||
l_content := full_input_data (req)
|
||||
if a_raw_data /= Void then
|
||||
a_raw_data.replace (l_content)
|
||||
end
|
||||
check content_count_same_as_content_length_if_not_chunked: (not req.is_chunked_input) implies (l_content.count = req.content_length_value.to_integer_32) end --| FIXME: truncated value
|
||||
n := l_content.count
|
||||
check n_same_as_content_length: n = a_content_length.to_integer_32 end --| FIXME: truncated value
|
||||
if n > 0 then
|
||||
from
|
||||
p := 1
|
||||
|
||||
@@ -15,7 +15,7 @@ feature -- Status report
|
||||
|
||||
feature -- Execution
|
||||
|
||||
handle (a_content_type: READABLE_STRING_8; a_content_length: NATURAL_64; req: WSF_REQUEST;
|
||||
handle (a_content_type: READABLE_STRING_8; req: WSF_REQUEST;
|
||||
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')
|
||||
-- and if `a_raw_data' is attached, store any read data inside `a_raw_data'
|
||||
|
||||
@@ -43,12 +43,12 @@ feature -- Status report
|
||||
|
||||
feature -- Execution
|
||||
|
||||
handle (a_content_type: READABLE_STRING_8; a_content_length: NATURAL_64; req: WSF_REQUEST;
|
||||
handle (a_content_type: READABLE_STRING_8; req: WSF_REQUEST;
|
||||
a_vars: HASH_TABLE [WSF_VALUE, READABLE_STRING_32]; a_raw_data: detachable CELL [detachable STRING_8])
|
||||
local
|
||||
s: READABLE_STRING_8
|
||||
do
|
||||
s := read_input_data (req.input, a_content_length)
|
||||
s := full_input_data (req)
|
||||
if a_raw_data /= Void then
|
||||
a_raw_data.replace (s)
|
||||
end
|
||||
|
||||
@@ -124,10 +124,26 @@ feature -- Access: Input
|
||||
|
||||
input: WGI_INPUT_STREAM
|
||||
-- Server input channel
|
||||
require
|
||||
is_not_chunked_input: not is_chunked_input
|
||||
do
|
||||
Result := wgi_request.input
|
||||
end
|
||||
|
||||
is_chunked_input: BOOLEAN
|
||||
-- Is request using chunked transfer-encoding?
|
||||
do
|
||||
Result := wgi_request.is_chunked_input
|
||||
end
|
||||
|
||||
chunked_input: detachable WGI_CHUNKED_INPUT_STREAM
|
||||
-- Server input channel
|
||||
require
|
||||
is_chunked_input: is_chunked_input
|
||||
do
|
||||
Result := wgi_request.chunked_input
|
||||
end
|
||||
|
||||
feature -- Helper
|
||||
|
||||
is_request_method (m: READABLE_STRING_8): BOOLEAN
|
||||
@@ -768,6 +784,13 @@ feature -- HTTP_*
|
||||
Result := wgi_request.http_authorization
|
||||
end
|
||||
|
||||
http_transfer_encoding: detachable READABLE_STRING_8
|
||||
-- Transfer-Encoding
|
||||
-- for instance chunked
|
||||
do
|
||||
Result := wgi_request.http_transfer_encoding
|
||||
end
|
||||
|
||||
feature -- Extra CGI environment variables
|
||||
|
||||
request_uri: READABLE_STRING_8
|
||||
@@ -1133,13 +1156,11 @@ feature {NONE} -- Form fields and related
|
||||
local
|
||||
vars: like internal_form_data_parameters_table
|
||||
l_raw_data_cell: detachable CELL [detachable STRING_8]
|
||||
n: NATURAL_64
|
||||
l_type: like content_type
|
||||
do
|
||||
vars := internal_form_data_parameters_table
|
||||
if vars = Void then
|
||||
n := content_length_value
|
||||
if n = 0 then
|
||||
if not is_chunked_input and content_length_value = 0 then
|
||||
create vars.make (0)
|
||||
vars.compare_objects
|
||||
else
|
||||
@@ -1151,9 +1172,10 @@ feature {NONE} -- Form fields and related
|
||||
|
||||
l_type := content_type
|
||||
if l_type /= Void and then attached mime_handler (l_type) as hdl then
|
||||
hdl.handle (l_type, n, Current, vars, l_raw_data_cell)
|
||||
hdl.handle (l_type, Current, vars, l_raw_data_cell)
|
||||
end
|
||||
if l_raw_data_cell /= Void and then attached l_raw_data_cell.item as l_raw_data then
|
||||
-- What if no mime handler is associated to `l_type' ?
|
||||
set_meta_string_variable ("RAW_POST_DATA", l_raw_data)
|
||||
end
|
||||
end
|
||||
|
||||
22
library/server/wsf/tests/echo/echo-safe.ecf
Normal file
22
library/server/wsf/tests/echo/echo-safe.ecf
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-9-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-9-0 http://www.eiffel.com/developers/xml/configuration-1-9-0.xsd" name="echo_server" uuid="D3EE5B55-6F2E-4247-8C94-E7CFC4C5B648">
|
||||
<target name="echo_server">
|
||||
<root class="ECHO_SERVER" feature="make"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
|
||||
</option>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="connector_nino" location="..\..\..\ewsgi\connectors\nino\nino-safe.ecf" readonly="false"/>
|
||||
<library name="connector_null" location="..\..\..\ewsgi\connectors\null\null-safe.ecf" readonly="false"/>
|
||||
<library name="dft_nino" location="..\..\default\nino-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\..\ewsgi\ewsgi-safe.ecf" readonly="false"/>
|
||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
|
||||
<library name="wsf" location="..\..\wsf-safe.ecf" readonly="false"/>
|
||||
<tests name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
75
library/server/wsf/tests/echo/src/echo_server.e
Normal file
75
library/server/wsf/tests/echo/src/echo_server.e
Normal file
@@ -0,0 +1,75 @@
|
||||
note
|
||||
description : "Objects that ..."
|
||||
author : "$Author$"
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
class
|
||||
ECHO_SERVER
|
||||
|
||||
inherit
|
||||
WSF_SERVICE
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Initialize `Current'.
|
||||
local
|
||||
launcher: DEFAULT_SERVICE_LAUNCHER
|
||||
do
|
||||
create launcher.make_and_launch_with_options (agent execute, <<["port", 9091]>>)
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
page: WSF_PAGE_RESPONSE
|
||||
l_body: STRING_8
|
||||
do
|
||||
create l_body.make (1024)
|
||||
create page.make_with_body (l_body)
|
||||
page.header.put_content_type_text_plain
|
||||
|
||||
l_body.append ("REQUEST_METHOD=" + req.request_method + "%N")
|
||||
l_body.append ("REQUEST_URI=" + req.request_uri + "%N")
|
||||
l_body.append ("PATH_INFO=" + req.path_info + "%N")
|
||||
l_body.append ("QUERY_STRING=" + req.query_string + "%N")
|
||||
|
||||
l_body.append ("Query parameters:%N")
|
||||
across
|
||||
req.query_parameters as q
|
||||
loop
|
||||
l_body.append ("%T"+ q.item.name + "=" + q.item.string_representation +"%N")
|
||||
end
|
||||
|
||||
l_body.append ("Form parameters:%N")
|
||||
across
|
||||
req.form_parameters as q
|
||||
loop
|
||||
l_body.append ("%T"+ q.item.name + "=" + q.item.string_representation +"%N")
|
||||
end
|
||||
|
||||
l_body.append ("Meta variables:%N")
|
||||
across
|
||||
req.meta_variables as q
|
||||
loop
|
||||
l_body.append ("%T"+ q.item.name + "=" + q.item.string_representation +"%N")
|
||||
end
|
||||
|
||||
res.put_response (page)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
feature -- Change
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
invariant
|
||||
-- invariant_clause: True
|
||||
|
||||
end
|
||||
@@ -53,11 +53,14 @@ feature {NONE} -- Events
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
q: detachable STRING_32
|
||||
page: WSF_PAGE_RESPONSE
|
||||
do
|
||||
create page.make
|
||||
if attached req.request_uri as l_uri then
|
||||
if l_uri.starts_with (test_url ("get/01")) then
|
||||
res.write_header (200, <<["Content-Type", "text/plain"]>>)
|
||||
res.write_string ("get-01")
|
||||
page.set_status_code (200)
|
||||
page.header.put_content_type_text_plain
|
||||
page.put_string ("get-01")
|
||||
create q.make_empty
|
||||
|
||||
across
|
||||
@@ -69,11 +72,11 @@ feature {NONE} -- Events
|
||||
q.append (qcur.item.name.as_string_32 + "=" + qcur.item.as_string)
|
||||
end
|
||||
if not q.is_empty then
|
||||
res.write_string ("(" + q + ")")
|
||||
page.put_string ("(" + q + ")")
|
||||
end
|
||||
elseif l_uri.starts_with (test_url ("post/01")) then
|
||||
res.write_header (200, <<["Content-Type", "text/plain"]>>)
|
||||
res.write_string ("post-01")
|
||||
page.put_header (200, <<["Content-Type", "text/plain"]>>)
|
||||
page.put_string ("post-01")
|
||||
create q.make_empty
|
||||
|
||||
across
|
||||
@@ -86,7 +89,7 @@ feature {NONE} -- Events
|
||||
end
|
||||
|
||||
if not q.is_empty then
|
||||
res.write_string ("(" + q + ")")
|
||||
page.put_string ("(" + q + ")")
|
||||
end
|
||||
|
||||
create q.make_empty
|
||||
@@ -102,16 +105,18 @@ feature {NONE} -- Events
|
||||
end
|
||||
|
||||
if not q.is_empty then
|
||||
res.write_string (" : " + q )
|
||||
page.put_string (" : " + q )
|
||||
end
|
||||
else
|
||||
res.write_header (200, <<["Content-Type", "text/plain"]>>)
|
||||
res.write_string ("Hello")
|
||||
page.put_header (200, <<["Content-Type", "text/plain"]>>)
|
||||
page.put_string ("Hello")
|
||||
end
|
||||
else
|
||||
res.write_header (200, <<["Content-Type", "text/plain"]>>)
|
||||
res.write_string ("Bye")
|
||||
page.put_header (200, <<["Content-Type", "text/plain"]>>)
|
||||
page.put_string ("Bye")
|
||||
end
|
||||
|
||||
page.send_to (res)
|
||||
end
|
||||
|
||||
test_url (a_query_url: READABLE_STRING_8): READABLE_STRING_8
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
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_CHUNKED_INPUT
|
||||
|
||||
inherit
|
||||
TEST_WSF_REQUEST
|
||||
redefine
|
||||
test_get_request_01,
|
||||
test_post_request_01
|
||||
end
|
||||
|
||||
feature -- Test routines
|
||||
|
||||
test_get_request_01
|
||||
-- New test routine
|
||||
local
|
||||
ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT
|
||||
do
|
||||
get_http_session
|
||||
if attached http_session as sess then
|
||||
-- create ctx.make
|
||||
-- ctx.set_proxy ("127.0.0.1", 8888) --| debugging with http://www.fiddler2.com/
|
||||
|
||||
test_get_request ("get/01", ctx, "get-01")
|
||||
test_get_request ("get/01/?foo=bar", ctx, "get-01(foo=bar)")
|
||||
test_get_request ("get/01/?foo=bar&abc=def", ctx, "get-01(foo=bar&abc=def)")
|
||||
test_get_request ("get/01/?lst=a&lst=b", ctx, "get-01(lst=[a,b])")
|
||||
else
|
||||
assert ("not_implemented", False)
|
||||
end
|
||||
end
|
||||
|
||||
test_post_request_01
|
||||
-- New test routine
|
||||
local
|
||||
ctx: HTTP_CLIENT_REQUEST_CONTEXT
|
||||
do
|
||||
get_http_session
|
||||
if attached http_session as sess then
|
||||
create ctx.make
|
||||
ctx.add_form_parameter ("id", "123")
|
||||
ctx.headers.extend ("chunked", "Transfer-Encoding")
|
||||
-- ctx.set_proxy ("127.0.0.1", 8888) --| debugging with http://www.fiddler2.com/
|
||||
|
||||
test_post_request ("post/01", ctx, "post-01 : id=123")
|
||||
test_post_request ("post/01/?foo=bar", ctx, "post-01(foo=bar) : id=123")
|
||||
test_post_request ("post/01/?foo=bar&abc=def", ctx, "post-01(foo=bar&abc=def) : id=123")
|
||||
test_post_request ("post/01/?lst=a&lst=b", ctx, "post-01(lst=[a,b]) : id=123")
|
||||
else
|
||||
assert ("not_implemented", False)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -80,7 +80,6 @@ feature {NONE} -- Implementation
|
||||
new_request (a_meta: ARRAY [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]]): WSF_REQUEST
|
||||
local
|
||||
wgi_req: WGI_REQUEST
|
||||
req: WSF_REQUEST
|
||||
do
|
||||
create {WGI_REQUEST_NULL} wgi_req.make (Current, a_meta)
|
||||
create Result.make_from_wgi (wgi_req)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="wsf_tests" uuid="CA72F5B3-E608-4FA5-8F05-A812441DB961">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-9-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-9-0 http://www.eiffel.com/developers/xml/configuration-1-9-0.xsd" name="wsf_tests" uuid="C4FF9CDA-B4E4-4841-97E0-7F799B85B657">
|
||||
<target name="tests">
|
||||
<root class="ANY" feature="default_create"/>
|
||||
<file_rule>
|
||||
@@ -14,11 +14,11 @@
|
||||
<library name="connector_nino" location="..\..\ewsgi\connectors\nino\nino-safe.ecf" readonly="false"/>
|
||||
<library name="connector_null" location="..\..\ewsgi\connectors\null\null-safe.ecf" readonly="false"/>
|
||||
<library name="dft_nino" location="..\default\nino-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf"/>
|
||||
<library name="http_client" location="..\..\..\client\http_client\http_client-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi\ewsgi-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="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
|
||||
<library name="wsf" location="..\wsf-safe.ecf" readonly="false"/>
|
||||
<tests name="src" location=".\src" recursive="true"/>
|
||||
<tests name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-9-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-9-0 http://www.eiffel.com/developers/xml/configuration-1-9-0.xsd" name="wsf_tests" uuid="CA72F5B3-E608-4FA5-8F05-A812441DB961">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-9-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-9-0 http://www.eiffel.com/developers/xml/configuration-1-9-0.xsd" name="wsf_tests" uuid="C4FF9CDA-B4E4-4841-97E0-7F799B85B657">
|
||||
<target name="tests">
|
||||
<root class="ANY" feature="default_create"/>
|
||||
<file_rule>
|
||||
|
||||
Reference in New Issue
Block a user