Fixed reading chunked input data

When retrieving data block by block, use 8_192 instead of 1_024 (since 1_024 is too small most of the time)
This commit is contained in:
Jocelyn Fiat
2012-12-18 23:40:26 +01:00
parent 0d87c7939a
commit ffe87ccbe9
4 changed files with 105 additions and 46 deletions

View File

@@ -2,6 +2,7 @@ note
description: "Summary description for {WGI_CHUNKED_INPUT_STREAM}." description: "Summary description for {WGI_CHUNKED_INPUT_STREAM}."
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
EIS: "name=Chunked Transfer Coding", "protocol=URI", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1"
class class
WGI_CHUNKED_INPUT_STREAM WGI_CHUNKED_INPUT_STREAM
@@ -36,7 +37,7 @@ feature -- Input
if index > chunk_upper then if index > chunk_upper then
read_chunk read_chunk
if last_chunk = Void then if last_chunk = Void then
read_trailer read_trailer_and_crlf
end end
end end
last_character := last_chunk.item (index) last_character := last_chunk.item (index)
@@ -45,37 +46,48 @@ feature -- Input
read_string (nb: INTEGER) read_string (nb: INTEGER)
-- Read the next `nb' characters and -- Read the next `nb' characters and
-- make the string result available in `last_string' -- make the string result available in `last_string'
--| Chunked-Body = *chunk
--| last-chunk
--| trailer
--| CRLF
local local
i: like index i: like index
do do
last_string.wipe_out last_string.wipe_out
if last_chunk_size = 0 then if last_trailer /= Void then
read_chunk -- trailer already reached, no more data
end check input.end_of_input end
from else
index := index + 1 if last_chunk_size = 0 then
i := index
until
i - index + 1 = nb or last_chunk_size = 0
loop
if i + nb - 1 <= chunk_upper then
last_string.append (last_chunk.substring (i, i + nb - 1))
i := i + nb - 1
else
-- Need to read new chunk
-- first get all available data from current chunk
if i <= chunk_upper then
last_string.append (last_chunk.substring (i, chunk_upper))
i := chunk_upper
end
-- then continue
read_chunk read_chunk
end end
from
index := index + 1
i := index
until
i - index + 1 = nb or last_chunk_size = 0
loop
if i + nb - 1 <= chunk_upper then
last_string.append (last_chunk.substring (i - chunk_lower + 1, i - chunk_lower + 1 + nb - 1))
i := i + nb - 1
else
-- Need to read new chunk
-- first get all available data from current chunk
if i <= chunk_upper then
last_string.append (last_chunk.substring (i - chunk_lower + 1, chunk_upper - chunk_lower + 1))
i := chunk_upper
end
-- then continue
read_chunk
i := i + 1
check i = chunk_lower end
end
end
if last_chunk_size = 0 then
read_trailer_and_crlf
end
index := i
end end
if last_chunk_size = 0 then
read_trailer
end
index := i
end end
feature -- Access feature -- Access
@@ -91,6 +103,9 @@ feature -- Access
last_character: CHARACTER_8 last_character: CHARACTER_8
-- Last item read. -- Last item read.
last_trailer: detachable STRING_8
-- Last trailer content if any.
feature -- Status report feature -- Status report
is_open_read: BOOLEAN is_open_read: BOOLEAN
@@ -114,14 +129,26 @@ feature {NONE} -- Parser
tmp_hex_chunk_size: STRING_8 tmp_hex_chunk_size: STRING_8
read_chunk read_chunk
local
l_input: like input
do do
chunk_lower := chunk_upper + 1 if input.end_of_input then
last_chunk.wipe_out else
last_chunk_size := 0 chunk_lower := chunk_upper + 1
read_chunk_size last_chunk.wipe_out
if last_chunk_size > 0 then last_chunk_size := 0
chunk_upper := chunk_upper + last_chunk_size read_chunk_size
read_chunk_data if last_chunk_size > 0 then
chunk_upper := chunk_upper + last_chunk_size
read_chunk_data
check last_chunk.count = last_chunk_size end
l_input := input
l_input.read_character
check l_input.last_character = '%R' end
l_input.read_character
check l_input.last_character = '%N' end
end
end end
ensure ensure
attached last_chunk as l_last_chunk implies l_last_chunk.count = chunk_upper - chunk_lower attached last_chunk as l_last_chunk implies l_last_chunk.count = chunk_upper - chunk_lower
@@ -134,6 +161,9 @@ feature {NONE} -- Parser
local local
l_input: like input l_input: like input
do do
debug ("wgi")
print (" Read chunk data ("+ last_chunk_size.out +") %N")
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 := l_input.last_string
@@ -151,6 +181,10 @@ feature {NONE} -- Parser
hex : HEXADECIMAL_STRING_TO_INTEGER_CONVERTER hex : HEXADECIMAL_STRING_TO_INTEGER_CONVERTER
l_input: like input l_input: like input
do do
debug ("wgi")
print (" Read chunk size: ")
end
l_input := input l_input := input
from from
l_input.read_character l_input.read_character
@@ -158,6 +192,9 @@ feature {NONE} -- Parser
eol eol
loop loop
c := l_input.last_character c := l_input.last_character
debug ("wgi")
print (c.out)
end
inspect c inspect c
when '%R' then when '%R' then
-- We are in the end of the line, we need to read the next character to start the next line. -- We are in the end of the line, we need to read the next character to start the next line.
@@ -183,6 +220,10 @@ feature {NONE} -- Parser
end end
end end
tmp_hex_chunk_size.wipe_out tmp_hex_chunk_size.wipe_out
debug ("wgi")
print ("%N Chunk size = " + last_chunk_size.out + "%N")
end
end end
read_extension_chunk read_extension_chunk
@@ -190,7 +231,7 @@ feature {NONE} -- Parser
l_input: like input l_input: like input
do do
l_input := input l_input := input
debug debug ("wgi")
print (" Reading extension chunk ") print (" Reading extension chunk ")
end end
from from
@@ -198,41 +239,59 @@ feature {NONE} -- Parser
until until
l_input.last_character = '%R' l_input.last_character = '%R'
loop loop
debug debug ("wgi")
print (l_input.last_character) print (l_input.last_character)
end end
l_input.read_character l_input.read_character
end end
end end
read_trailer read_trailer_and_crlf
-- trailer = *(entity-header CRLF)
-- CRLF
local local
l_input: like input l_input: like input
l_line_size: INTEGER
s: STRING_8
do do
create s.make_empty
l_input := input l_input := input
if not l_input.end_of_input then if not l_input.end_of_input then
debug debug ("wgi")
print (" Reading trailer ") print (" Reading trailer ")
end end
from from
l_input.read_character l_line_size := 1 -- Dummy value /= 0
until until
l_input.last_character = '%R' l_line_size = 0
loop loop
debug l_line_size := 0
print (l_input.last_character) from
l_input.read_character
s.append_character (l_input.last_character)
until
l_input.last_character = '%R'
loop
l_line_size := l_line_size + 1
debug ("wgi")
print (l_input.last_character)
end
l_input.read_character
s.append_character (l_input.last_character)
end end
s.remove_tail (1)
-- read the LF
l_input.read_character l_input.read_character
check l_input.last_character = '%N' end
end end
-- read the LF
l_input.read_character
end end
last_trailer := s
end end
feature {NONE} -- Implementation feature {NONE} -- Implementation
input: WGI_INPUT_STREAM input: WGI_INPUT_STREAM
-- Input Stream -- Input Stream
;note ;note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"

View File

@@ -205,7 +205,7 @@ feature -- Retrieve content from WGI_INPUT_STREAM
l_input := req.input l_input := req.input
if req.is_chunked_input then if req.is_chunked_input then
from from
n := 1_024 n := 8_192
create Result.make (n) create Result.make (n)
until until
n = 0 n = 0

View File

@@ -21,7 +21,7 @@ feature {NONE} -- Implementation
t: STRING t: STRING
do do
from from
n := 1_024 n := 8_192
create Result.make (n) create Result.make (n)
until until
n = 0 n = 0

View File

@@ -207,7 +207,7 @@ feature -- Access: Input
l_input := input l_input := input
if is_chunked_input then if is_chunked_input then
from from
n := 1_024 n := 8_192
until until
n = 0 n = 0
loop loop