From 7193ce93f46223e1ab45d047dbdaa889be458252 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Wed, 19 Dec 2012 12:47:35 +0100 Subject: [PATCH] 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. --- .../stream/wgi_chunked_input_stream.e | 81 ++++++++++++++----- .../wsf/src/response/wsf_trace_response.e | 43 ++++++---- library/server/wsf/src/wsf_request.e | 8 +- 3 files changed, 93 insertions(+), 39 deletions(-) diff --git a/library/server/ewsgi/specification/stream/wgi_chunked_input_stream.e b/library/server/ewsgi/specification/stream/wgi_chunked_input_stream.e index ee025be4..de2b07c3 100644 --- a/library/server/ewsgi/specification/stream/wgi_chunked_input_stream.e +++ b/library/server/ewsgi/specification/stream/wgi_chunked_input_stream.e @@ -18,7 +18,7 @@ feature {NONE} -- Implementation make (an_input: like input) do create last_string.make_empty - create last_chunk.make_empty + create last_chunk_data.make_empty last_chunk_size := 0 index := 0 chunk_lower := 0 @@ -35,12 +35,12 @@ feature -- Input do index := index + 1 if index > chunk_upper then - read_chunk - if last_chunk = Void then + read_chunk_block + if last_chunk_data = Void then read_trailer_and_crlf end end - last_character := last_chunk.item (index) + last_character := last_chunk_data.item (index) end read_string (nb: INTEGER) @@ -59,7 +59,7 @@ feature -- Input check input.end_of_input end else if last_chunk_size = 0 then - read_chunk + read_chunk_block end from index := index + 1 @@ -68,17 +68,17 @@ feature -- Input 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)) + last_string.append (last_chunk_data.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)) + last_string.append (last_chunk_data.substring (i - chunk_lower + 1, chunk_upper - chunk_lower + 1)) i := chunk_upper end -- then continue - read_chunk + read_chunk_block i := i + 1 check i = chunk_lower end end @@ -103,8 +103,33 @@ feature -- Access last_character: CHARACTER_8 -- 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 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 @@ -123,25 +148,25 @@ feature -- Status report feature {NONE} -- Parser index, chunk_lower, chunk_upper: INTEGER - last_chunk_size: INTEGER - last_chunk: 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 l_input: like input do if input.end_of_input then else chunk_lower := chunk_upper + 1 - last_chunk.wipe_out + last_chunk_data.wipe_out last_chunk_size := 0 read_chunk_size if last_chunk_size > 0 then chunk_upper := chunk_upper + last_chunk_size 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.read_character @@ -151,12 +176,12 @@ feature {NONE} -- Parser end end 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 read_chunk_data require - last_chunk.is_empty + last_chunk_data.is_empty last_chunk_size > 0 local l_input: like input @@ -166,9 +191,9 @@ feature {NONE} -- Parser end l_input := input l_input.read_string (last_chunk_size) - last_chunk := l_input.last_string + last_chunk_data := l_input.last_string 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 end @@ -229,13 +254,16 @@ feature {NONE} -- Parser read_extension_chunk local l_input: like input + s: STRING_8 do l_input := input debug ("wgi") print (" Reading extension chunk ") end + create s.make_empty from l_input.read_character + s.append_character (l_input.last_character) until l_input.last_character = '%R' loop @@ -243,11 +271,18 @@ feature {NONE} -- Parser print (l_input.last_character) end 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 read_trailer_and_crlf - -- trailer = *(entity-header CRLF) + -- trailer = *(entity-header CRLF) -- CRLF local l_input: like input @@ -285,7 +320,11 @@ feature {NONE} -- Parser check l_input.last_character = '%N' end end end - last_trailer := s + if s.is_empty then + last_trailer := Void + else + last_trailer := s + end end feature {NONE} -- Implementation diff --git a/library/server/wsf/src/response/wsf_trace_response.e b/library/server/wsf/src/response/wsf_trace_response.e index 3b559e7a..5e0e6ee0 100644 --- a/library/server/wsf/src/response/wsf_trace_response.e +++ b/library/server/wsf/src/response/wsf_trace_response.e @@ -54,24 +54,37 @@ feature {WSF_RESPONSE} -- Output res.put_header_text (h.string) res.put_chunk (s, Void) if attached req.input as l_input then - 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) + if attached {WGI_CHUNKED_INPUT_STREAM} l_input as l_chunked_input then + from + l_chunked_input.read_chunk + until + l_chunked_input.last_chunk_size = 0 + loop + res.put_chunk (l_chunked_input.last_chunk_data, l_chunked_input.last_chunk_extension) + l_chunked_input.read_chunk 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 - res.put_chunk_end res.flush else req.read_input_data_into (s) diff --git a/library/server/wsf/src/wsf_request.e b/library/server/wsf/src/wsf_request.e index 36a918a3..d90d89b2 100644 --- a/library/server/wsf/src/wsf_request.e +++ b/library/server/wsf/src/wsf_request.e @@ -224,9 +224,11 @@ feature -- Access: Input end else n := content_length_value.as_integer_32 - buf.resize (buf.count + n) - n := l_input.read_to_string (buf, buf.count + 1, n) - check n = content_length_value.as_integer_32 end + if n > 0 then + buf.resize (buf.count + n) + n := l_input.read_to_string (buf, buf.count + 1, n) + check n = content_length_value.as_integer_32 end + end end if raw_input_data_recorded then set_raw_input_data (buf)