Added support for chunked input data (see Transfer-Encoding: chunked)

This commit is contained in:
Jocelyn Fiat
2012-02-07 15:47:55 +01:00
parent cf8d25c4e5
commit 69bc4d568c
16 changed files with 378 additions and 102 deletions

View File

@@ -9,6 +9,20 @@ deferred class
feature {NONE} -- Implementation
full_input_data (req: WSF_REQUEST): READABLE_STRING_8
do
if req.is_chunked_input then
if attached req.chunked_input as l_chunked_input then
Result := l_chunked_input.data
else
check has_chunked_input: False end
Result := ""
end
else
Result := read_input_data (req.input, req.content_length_value)
end
end
read_input_data (a_input: WGI_INPUT_STREAM; nb: NATURAL_64): READABLE_STRING_8
-- All data from input form
local

View File

@@ -21,7 +21,7 @@ feature -- Status report
feature -- Execution
handle (a_content_type: READABLE_STRING_8; a_content_length: NATURAL_64; req: WSF_REQUEST;
handle (a_content_type: READABLE_STRING_8; req: WSF_REQUEST;
a_vars: HASH_TABLE [WSF_VALUE, READABLE_STRING_32]; a_raw_data: detachable CELL [detachable STRING_8])
local
l_content: READABLE_STRING_8
@@ -29,12 +29,12 @@ feature -- Execution
s: READABLE_STRING_8
l_name, l_value: READABLE_STRING_8
do
l_content := read_input_data (req.input, a_content_length)
l_content := full_input_data (req)
if a_raw_data /= Void then
a_raw_data.replace (l_content)
end
check content_count_same_as_content_length_if_not_chunked: (not req.is_chunked_input) implies (l_content.count = req.content_length_value.to_integer_32) end --| FIXME: truncated value
n := l_content.count
check n_same_as_content_length: n = a_content_length.to_integer_32 end --| FIXME: truncated value
if n > 0 then
from
p := 1

View File

@@ -15,7 +15,7 @@ feature -- Status report
feature -- Execution
handle (a_content_type: READABLE_STRING_8; a_content_length: NATURAL_64; req: WSF_REQUEST;
handle (a_content_type: READABLE_STRING_8; req: WSF_REQUEST;
a_vars: TABLE [WSF_VALUE, READABLE_STRING_32]; a_raw_data: detachable CELL [detachable STRING_8])
-- Handle MIME content from request `req', eventually fill the `a_vars' (not yet available from `req')
-- and if `a_raw_data' is attached, store any read data inside `a_raw_data'

View File

@@ -43,12 +43,12 @@ feature -- Status report
feature -- Execution
handle (a_content_type: READABLE_STRING_8; a_content_length: NATURAL_64; req: WSF_REQUEST;
handle (a_content_type: READABLE_STRING_8; req: WSF_REQUEST;
a_vars: HASH_TABLE [WSF_VALUE, READABLE_STRING_32]; a_raw_data: detachable CELL [detachable STRING_8])
local
s: READABLE_STRING_8
do
s := read_input_data (req.input, a_content_length)
s := full_input_data (req)
if a_raw_data /= Void then
a_raw_data.replace (s)
end

View File

@@ -124,10 +124,26 @@ feature -- Access: Input
input: WGI_INPUT_STREAM
-- Server input channel
require
is_not_chunked_input: not is_chunked_input
do
Result := wgi_request.input
end
is_chunked_input: BOOLEAN
-- Is request using chunked transfer-encoding?
do
Result := wgi_request.is_chunked_input
end
chunked_input: detachable WGI_CHUNKED_INPUT_STREAM
-- Server input channel
require
is_chunked_input: is_chunked_input
do
Result := wgi_request.chunked_input
end
feature -- Helper
is_request_method (m: READABLE_STRING_8): BOOLEAN
@@ -768,6 +784,13 @@ feature -- HTTP_*
Result := wgi_request.http_authorization
end
http_transfer_encoding: detachable READABLE_STRING_8
-- Transfer-Encoding
-- for instance chunked
do
Result := wgi_request.http_transfer_encoding
end
feature -- Extra CGI environment variables
request_uri: READABLE_STRING_8
@@ -1133,13 +1156,11 @@ feature {NONE} -- Form fields and related
local
vars: like internal_form_data_parameters_table
l_raw_data_cell: detachable CELL [detachable STRING_8]
n: NATURAL_64
l_type: like content_type
do
vars := internal_form_data_parameters_table
if vars = Void then
n := content_length_value
if n = 0 then
if not is_chunked_input and content_length_value = 0 then
create vars.make (0)
vars.compare_objects
else
@@ -1151,9 +1172,10 @@ feature {NONE} -- Form fields and related
l_type := content_type
if l_type /= Void and then attached mime_handler (l_type) as hdl then
hdl.handle (l_type, n, Current, vars, l_raw_data_cell)
hdl.handle (l_type, Current, vars, l_raw_data_cell)
end
if l_raw_data_cell /= Void and then attached l_raw_data_cell.item as l_raw_data then
-- What if no mime handler is associated to `l_type' ?
set_meta_string_variable ("RAW_POST_DATA", l_raw_data)
end
end