Fixed issue in WSF_REQUEST.read_input_data_into when the content is zero

Cleaned the WGI_CHUNKED_INPUT_STREAM and provides access to last extension, last trailer, ...
Improved WSF_TRACE_RESPONSE to support tracing chunked input back to the client.
This commit is contained in:
Jocelyn Fiat
2012-12-19 12:47:35 +01:00
parent 59f19dc52f
commit 7193ce93f4
3 changed files with 93 additions and 39 deletions

View File

@@ -18,7 +18,7 @@ feature {NONE} -- Implementation
make (an_input: like input) make (an_input: like input)
do do
create last_string.make_empty create last_string.make_empty
create last_chunk.make_empty create last_chunk_data.make_empty
last_chunk_size := 0 last_chunk_size := 0
index := 0 index := 0
chunk_lower := 0 chunk_lower := 0
@@ -35,12 +35,12 @@ feature -- Input
do do
index := index + 1 index := index + 1
if index > chunk_upper then if index > chunk_upper then
read_chunk read_chunk_block
if last_chunk = Void then if last_chunk_data = Void then
read_trailer_and_crlf read_trailer_and_crlf
end end
end end
last_character := last_chunk.item (index) last_character := last_chunk_data.item (index)
end end
read_string (nb: INTEGER) read_string (nb: INTEGER)
@@ -59,7 +59,7 @@ feature -- Input
check input.end_of_input end check input.end_of_input end
else else
if last_chunk_size = 0 then if last_chunk_size = 0 then
read_chunk read_chunk_block
end end
from from
index := index + 1 index := index + 1
@@ -68,17 +68,17 @@ feature -- Input
i - index + 1 = nb or last_chunk_size = 0 i - index + 1 = nb or last_chunk_size = 0
loop loop
if i + nb - 1 <= chunk_upper then if i + nb - 1 <= chunk_upper then
last_string.append (last_chunk.substring (i - chunk_lower + 1, i - chunk_lower + 1 + nb - 1)) last_string.append (last_chunk_data.substring (i - chunk_lower + 1, i - chunk_lower + 1 + nb - 1))
i := i + nb - 1 i := i + nb - 1
else else
-- Need to read new chunk -- Need to read new chunk
-- first get all available data from current chunk -- first get all available data from current chunk
if i <= chunk_upper then if i <= chunk_upper then
last_string.append (last_chunk.substring (i - chunk_lower + 1, chunk_upper - chunk_lower + 1)) last_string.append (last_chunk_data.substring (i - chunk_lower + 1, chunk_upper - chunk_lower + 1))
i := chunk_upper i := chunk_upper
end end
-- then continue -- then continue
read_chunk read_chunk_block
i := i + 1 i := i + 1
check i = chunk_lower end check i = chunk_lower end
end end
@@ -103,8 +103,33 @@ feature -- Access
last_character: CHARACTER_8 last_character: CHARACTER_8
-- Last item read. -- Last item read.
feature -- Access: chunk
last_chunk_size: INTEGER
-- Last chunk size.
last_chunk_data: STRING_8
-- Last chunk data.
last_trailer: detachable STRING_8 last_trailer: detachable STRING_8
-- Last trailer content if any. -- Last optional trailer content if any.
last_chunk_extension: detachable STRING_8
-- Last optional extension if any
feature -- Chunk reading
read_chunk
-- Read next chunk
-- WARNING: do not mix read_chunk calls and read_string/read_character
-- this would mess up the traversal.
-- note: modify last_chunk_size, last_chunk, last_extension
do
read_chunk_block
if last_chunk_size = 0 then
read_trailer_and_crlf
end
end
feature -- Status report feature -- Status report
@@ -123,25 +148,25 @@ feature -- Status report
feature {NONE} -- Parser feature {NONE} -- Parser
index, chunk_lower, chunk_upper: INTEGER index, chunk_lower, chunk_upper: INTEGER
last_chunk_size: INTEGER
last_chunk: STRING_8
tmp_hex_chunk_size: STRING_8 tmp_hex_chunk_size: STRING_8
read_chunk read_chunk_block
-- Read next chunk
-- WARNING: do not mix read_chunk calls and read_string/read_character
-- this would mess up the traversal.
local local
l_input: like input l_input: like input
do do
if input.end_of_input then if input.end_of_input then
else else
chunk_lower := chunk_upper + 1 chunk_lower := chunk_upper + 1
last_chunk.wipe_out last_chunk_data.wipe_out
last_chunk_size := 0 last_chunk_size := 0
read_chunk_size read_chunk_size
if last_chunk_size > 0 then if last_chunk_size > 0 then
chunk_upper := chunk_upper + last_chunk_size chunk_upper := chunk_upper + last_chunk_size
read_chunk_data read_chunk_data
check last_chunk.count = last_chunk_size end check last_chunk_data.count = last_chunk_size end
l_input := input l_input := input
l_input.read_character l_input.read_character
@@ -151,12 +176,12 @@ feature {NONE} -- Parser
end end
end end
ensure ensure
attached last_chunk as l_last_chunk implies l_last_chunk.count = chunk_upper - chunk_lower + 1 attached last_chunk_data as l_last_chunk implies l_last_chunk.count = chunk_upper - chunk_lower + 1
end end
read_chunk_data read_chunk_data
require require
last_chunk.is_empty last_chunk_data.is_empty
last_chunk_size > 0 last_chunk_size > 0
local local
l_input: like input l_input: like input
@@ -166,9 +191,9 @@ feature {NONE} -- Parser
end end
l_input := input l_input := input
l_input.read_string (last_chunk_size) l_input.read_string (last_chunk_size)
last_chunk := l_input.last_string last_chunk_data := l_input.last_string
ensure ensure
last_chunk_attached: attached last_chunk as el_last_chunk last_chunk_attached: attached last_chunk_data as el_last_chunk
last_chunk_size_ok: el_last_chunk.count = last_chunk_size last_chunk_size_ok: el_last_chunk.count = last_chunk_size
end end
@@ -229,13 +254,16 @@ feature {NONE} -- Parser
read_extension_chunk read_extension_chunk
local local
l_input: like input l_input: like input
s: STRING_8
do do
l_input := input l_input := input
debug ("wgi") debug ("wgi")
print (" Reading extension chunk ") print (" Reading extension chunk ")
end end
create s.make_empty
from from
l_input.read_character l_input.read_character
s.append_character (l_input.last_character)
until until
l_input.last_character = '%R' l_input.last_character = '%R'
loop loop
@@ -243,11 +271,18 @@ feature {NONE} -- Parser
print (l_input.last_character) print (l_input.last_character)
end end
l_input.read_character l_input.read_character
s.append_character (l_input.last_character)
end
s.remove_tail (1)
if s.is_empty then
last_chunk_extension := Void
else
last_chunk_extension := s
end end
end end
read_trailer_and_crlf read_trailer_and_crlf
-- trailer = *(entity-header CRLF) -- trailer = *(entity-header CRLF)
-- CRLF -- CRLF
local local
l_input: like input l_input: like input
@@ -285,7 +320,11 @@ feature {NONE} -- Parser
check l_input.last_character = '%N' end check l_input.last_character = '%N' end
end end
end end
last_trailer := s if s.is_empty then
last_trailer := Void
else
last_trailer := s
end
end end
feature {NONE} -- Implementation feature {NONE} -- Implementation

View File

@@ -54,24 +54,37 @@ feature {WSF_RESPONSE} -- Output
res.put_header_text (h.string) res.put_header_text (h.string)
res.put_chunk (s, Void) res.put_chunk (s, Void)
if attached req.input as l_input then if attached req.input as l_input then
from if attached {WGI_CHUNKED_INPUT_STREAM} l_input as l_chunked_input then
n := 8_192 from
until l_chunked_input.read_chunk
n = 0 until
loop l_chunked_input.last_chunk_size = 0
s.wipe_out loop
nb := l_input.read_to_string (s, 1, n) res.put_chunk (l_chunked_input.last_chunk_data, l_chunked_input.last_chunk_extension)
if nb = 0 then l_chunked_input.read_chunk
n := 0
else
if nb < n then
n := 0
end
res.put_chunk (s, Void)
end end
res.put_custom_chunk_end (l_chunked_input.last_chunk_extension, l_chunked_input.last_trailer)
else
check is_chunked_input: False end
from
n := 8_192
until
n = 0
loop
s.wipe_out
nb := l_input.read_to_string (s, 1, n)
if nb = 0 then
n := 0
else
if nb < n then
n := 0
end
res.put_chunk (s, Void)
end
end
res.put_chunk_end
end end
end end
res.put_chunk_end
res.flush res.flush
else else
req.read_input_data_into (s) req.read_input_data_into (s)

View File

@@ -224,9 +224,11 @@ feature -- Access: Input
end end
else else
n := content_length_value.as_integer_32 n := content_length_value.as_integer_32
buf.resize (buf.count + n) if n > 0 then
n := l_input.read_to_string (buf, buf.count + 1, n) buf.resize (buf.count + n)
check n = content_length_value.as_integer_32 end n := l_input.read_to_string (buf, buf.count + 1, n)
check n = content_length_value.as_integer_32 end
end
end end
if raw_input_data_recorded then if raw_input_data_recorded then
set_raw_input_data (buf) set_raw_input_data (buf)