Fixed WSF_RESPONSE chunk transfer implementation

and also the optional extension `a_ext' should now include the ';'
Now HTTP_HEADER is an ITERABLE [READABLE_STRING_8]
This commit is contained in:
Jocelyn Fiat
2012-12-19 11:45:59 +01:00
parent f3aeb67e16
commit 59f19dc52f
3 changed files with 54 additions and 34 deletions

View File

@@ -22,7 +22,7 @@ class
HTTP_HEADER
inherit
ANY
ITERABLE [READABLE_STRING_8]
create
make,
@@ -149,6 +149,14 @@ feature -- Access
Result := res
end
feature -- Access
new_cursor: INDEXABLE_ITERATION_CURSOR [READABLE_STRING_8]
-- Fresh cursor associated with current structure
do
Result := headers.new_cursor
end
feature -- Header: filling
append_array (a_headers: ARRAY [TUPLE [key: READABLE_STRING_8; value: READABLE_STRING_8]])

View File

@@ -47,16 +47,15 @@ feature {WSF_RESPONSE} -- Output
s.append (l_header.to_string_8)
s.append_character ('%N')
else
s := ""
create s.make_empty
end
if req.is_chunked_input then
h.put_transfer_encoding_chunked
res.put_header_text (h.string)
res.put_chunk (s, Void)
if attached req.input as l_input then
from
n := 1_024
n := 8_192
until
n = 0
loop

View File

@@ -183,7 +183,7 @@ feature {NONE} -- Implementation
transfered_content_length := transfered_content_length + n.to_natural_64
end
feature -- Output operation
feature -- Body
put_character (c: CHARACTER_8)
-- Send the character `c'
@@ -212,20 +212,23 @@ feature -- Output operation
increment_transfered_content_length (a_end_index - a_begin_index + 1)
end
put_chunk (s: READABLE_STRING_8; a_extension: detachable READABLE_STRING_8)
-- Write chunk non empty `s'
-- Note: that you should have header
-- "Transfer-Encoding: chunked"
feature -- Chunk body
put_chunk (a_content: READABLE_STRING_8; a_ext: detachable READABLE_STRING_8)
-- Write chunk non empty `a_content'
-- with optional extension `a_ext': chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
-- Note: that you should have header "Transfer-Encoding: chunked"
require
s_not_empty: s /= Void and then not s.is_empty
a_content_not_empty: a_content /= Void and then not a_content.is_empty
message_writable: message_writable
valid_chunk_extension: a_extension /= Void implies not a_extension.has ('%N') and not not a_extension.has ('%R')
valid_chunk_extension: (a_ext /= Void and then not a_ext.is_empty) implies
( a_ext.starts_with (";") and not a_ext.has ('%N') and not not a_ext.has ('%R') )
local
l_chunk_size_line: STRING_8
i: INTEGER
do
--| Remove all left '0'
l_chunk_size_line := s.count.to_hex_string
l_chunk_size_line := a_content.count.to_hex_string
from
i := 1
until
@@ -237,42 +240,52 @@ feature -- Output operation
l_chunk_size_line := l_chunk_size_line.substring (i, l_chunk_size_line.count)
end
if a_extension /= Void then
l_chunk_size_line.append_character (';')
l_chunk_size_line.append (a_extension)
if a_ext /= Void then
l_chunk_size_line.append (a_ext)
end
l_chunk_size_line.append ({HTTP_CONSTANTS}.crlf)
wgi_response.put_string (l_chunk_size_line)
put_string (s)
put_string (a_content)
wgi_response.put_string ({HTTP_CONSTANTS}.crlf)
flush
ensure
transfered_content_length = old transfered_content_length + s.count.to_natural_64
transfered_content_length = old transfered_content_length + a_content.count.to_natural_64
end
put_custom_chunk_end (a_ext: detachable READABLE_STRING_8; a_trailer: detachable READABLE_STRING_8)
-- Put end of chunked content,
-- with optional extension `a_ext': chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
-- and with optional trailer `a_trailer' : trailer= *(entity-header CRLF)
local
l_chunk_size_line: STRING_8
do
-- Chunk end
create l_chunk_size_line.make (1)
l_chunk_size_line.append_integer (0)
if a_ext /= Void then
l_chunk_size_line.append (a_ext)
end
l_chunk_size_line.append ({HTTP_CONSTANTS}.crlf)
wgi_response.put_string (l_chunk_size_line)
-- Optional trailer
if a_trailer /= Void and then not a_trailer.is_empty then
wgi_response.put_string (a_trailer)
end
-- Final CRLF
wgi_response.put_string ({HTTP_CONSTANTS}.crlf)
flush
end
put_chunk_end
-- Put end of chunked content
-- without any optional trailer.
do
wgi_response.put_string ("0")
wgi_response.put_string ({HTTP_CONSTANTS}.crlf)
-- No trailer
wgi_response.put_string ({HTTP_CONSTANTS}.crlf)
flush
end
put_chunk_end_with_trailer (a_trailer: detachable READABLE_STRING_8)
-- Put end of chunked content
-- with optional trailer: *(entity-header CRLF)
require
a_trailer_well_formatted: (a_trailer /= Void and then not a_trailer.is_empty) implies a_trailer.ends_with ({HTTP_CONSTANTS}.crlf)
do
if a_trailer /= Void and then not a_trailer.is_empty then
wgi_response.put_string (a_trailer)
end
wgi_response.put_string ({HTTP_CONSTANTS}.crlf)
put_custom_chunk_end (Void, Void)
end
flush