diff --git a/library/network/protocol/http/src/http_header.e b/library/network/protocol/http/src/http_header.e index e3a8956a..001067a9 100644 --- a/library/network/protocol/http/src/http_header.e +++ b/library/network/protocol/http/src/http_header.e @@ -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]]) diff --git a/library/server/wsf/src/response/wsf_trace_response.e b/library/server/wsf/src/response/wsf_trace_response.e index 4b287d08..3b559e7a 100644 --- a/library/server/wsf/src/response/wsf_trace_response.e +++ b/library/server/wsf/src/response/wsf_trace_response.e @@ -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 diff --git a/library/server/wsf/src/wsf_response.e b/library/server/wsf/src/wsf_response.e index 3921c4ab..edd69fed 100644 --- a/library/server/wsf/src/wsf_response.e +++ b/library/server/wsf/src/wsf_response.e @@ -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