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:
@@ -22,7 +22,7 @@ class
|
|||||||
HTTP_HEADER
|
HTTP_HEADER
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
ANY
|
ITERABLE [READABLE_STRING_8]
|
||||||
|
|
||||||
create
|
create
|
||||||
make,
|
make,
|
||||||
@@ -149,6 +149,14 @@ feature -- Access
|
|||||||
Result := res
|
Result := res
|
||||||
end
|
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
|
feature -- Header: filling
|
||||||
|
|
||||||
append_array (a_headers: ARRAY [TUPLE [key: READABLE_STRING_8; value: READABLE_STRING_8]])
|
append_array (a_headers: ARRAY [TUPLE [key: READABLE_STRING_8; value: READABLE_STRING_8]])
|
||||||
|
|||||||
@@ -47,16 +47,15 @@ feature {WSF_RESPONSE} -- Output
|
|||||||
s.append (l_header.to_string_8)
|
s.append (l_header.to_string_8)
|
||||||
s.append_character ('%N')
|
s.append_character ('%N')
|
||||||
else
|
else
|
||||||
s := ""
|
create s.make_empty
|
||||||
end
|
end
|
||||||
if req.is_chunked_input then
|
if req.is_chunked_input then
|
||||||
h.put_transfer_encoding_chunked
|
h.put_transfer_encoding_chunked
|
||||||
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
|
from
|
||||||
n := 1_024
|
n := 8_192
|
||||||
until
|
until
|
||||||
n = 0
|
n = 0
|
||||||
loop
|
loop
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ feature {NONE} -- Implementation
|
|||||||
transfered_content_length := transfered_content_length + n.to_natural_64
|
transfered_content_length := transfered_content_length + n.to_natural_64
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Output operation
|
feature -- Body
|
||||||
|
|
||||||
put_character (c: CHARACTER_8)
|
put_character (c: CHARACTER_8)
|
||||||
-- Send the character `c'
|
-- Send the character `c'
|
||||||
@@ -212,20 +212,23 @@ feature -- Output operation
|
|||||||
increment_transfered_content_length (a_end_index - a_begin_index + 1)
|
increment_transfered_content_length (a_end_index - a_begin_index + 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
put_chunk (s: READABLE_STRING_8; a_extension: detachable READABLE_STRING_8)
|
feature -- Chunk body
|
||||||
-- Write chunk non empty `s'
|
|
||||||
-- Note: that you should have header
|
put_chunk (a_content: READABLE_STRING_8; a_ext: detachable READABLE_STRING_8)
|
||||||
-- "Transfer-Encoding: chunked"
|
-- 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
|
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
|
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
|
local
|
||||||
l_chunk_size_line: STRING_8
|
l_chunk_size_line: STRING_8
|
||||||
i: INTEGER
|
i: INTEGER
|
||||||
do
|
do
|
||||||
--| Remove all left '0'
|
--| Remove all left '0'
|
||||||
l_chunk_size_line := s.count.to_hex_string
|
l_chunk_size_line := a_content.count.to_hex_string
|
||||||
from
|
from
|
||||||
i := 1
|
i := 1
|
||||||
until
|
until
|
||||||
@@ -237,42 +240,52 @@ feature -- Output operation
|
|||||||
l_chunk_size_line := l_chunk_size_line.substring (i, l_chunk_size_line.count)
|
l_chunk_size_line := l_chunk_size_line.substring (i, l_chunk_size_line.count)
|
||||||
end
|
end
|
||||||
|
|
||||||
if a_extension /= Void then
|
if a_ext /= Void then
|
||||||
l_chunk_size_line.append_character (';')
|
l_chunk_size_line.append (a_ext)
|
||||||
l_chunk_size_line.append (a_extension)
|
|
||||||
end
|
end
|
||||||
l_chunk_size_line.append ({HTTP_CONSTANTS}.crlf)
|
l_chunk_size_line.append ({HTTP_CONSTANTS}.crlf)
|
||||||
|
|
||||||
|
|
||||||
wgi_response.put_string (l_chunk_size_line)
|
wgi_response.put_string (l_chunk_size_line)
|
||||||
put_string (s)
|
put_string (a_content)
|
||||||
wgi_response.put_string ({HTTP_CONSTANTS}.crlf)
|
wgi_response.put_string ({HTTP_CONSTANTS}.crlf)
|
||||||
flush
|
flush
|
||||||
ensure
|
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
|
end
|
||||||
|
|
||||||
put_chunk_end
|
put_chunk_end
|
||||||
-- Put end of chunked content
|
-- Put end of chunked content
|
||||||
-- without any optional trailer.
|
-- without any optional trailer.
|
||||||
do
|
do
|
||||||
wgi_response.put_string ("0")
|
put_custom_chunk_end (Void, Void)
|
||||||
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)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
flush
|
flush
|
||||||
|
|||||||
Reference in New Issue
Block a user