From e70d67aed56c3b3f7116dc16fe6dae5289a4e2a7 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Thu, 1 Dec 2011 19:12:26 +0100 Subject: [PATCH] Integrated new system to handle form_parameter, input_data in relation with MIME handling This is not yet clear how to let the user precise its own MIME handler but it is in progress --- .../wsf/src/support/wsf_mime_handler_helper.e | 143 ++++++++ ...pplication_x_www_form_urlencoded_handler.e | 64 ++++ library/server/wsf/src/wsf_mime_handler.e | 27 ++ .../wsf/src/wsf_multipart_form_data_handler.e | 248 +++++++++++++ library/server/wsf/src/wsf_request.e | 328 ++++++------------ 5 files changed, 592 insertions(+), 218 deletions(-) create mode 100644 library/server/wsf/src/support/wsf_mime_handler_helper.e create mode 100644 library/server/wsf/src/wsf_application_x_www_form_urlencoded_handler.e create mode 100644 library/server/wsf/src/wsf_mime_handler.e create mode 100644 library/server/wsf/src/wsf_multipart_form_data_handler.e diff --git a/library/server/wsf/src/support/wsf_mime_handler_helper.e b/library/server/wsf/src/support/wsf_mime_handler_helper.e new file mode 100644 index 00000000..9777244c --- /dev/null +++ b/library/server/wsf/src/support/wsf_mime_handler_helper.e @@ -0,0 +1,143 @@ +note + description: "Summary description for {WSF_MIME_HANDLER_HELPER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_MIME_HANDLER_HELPER + +feature {NONE} -- Implementation + + read_input_data (a_input: WGI_INPUT_STREAM; nb: NATURAL_64): READABLE_STRING_8 + -- All data from input form + local + nb32: INTEGER + n64: NATURAL_64 + n: INTEGER + t: STRING + s: STRING_8 + do + from + n64 := nb + nb32 := n64.to_integer_32 + create s.make (nb32) + Result := s + n := nb32 + if n > 1_024 then + n := 1_024 + end + until + n64 <= 0 + loop + a_input.read_string (n) + t := a_input.last_string + s.append_string (t) + if t.count < n then + n64 := 0 + else + n64 := n64 - t.count.as_natural_64 + end + end + end + + add_value_to_table (a_name: READABLE_STRING_8; a_value: READABLE_STRING_8; a_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_32]) + local + + v: detachable WSF_VALUE + n,k,r: STRING_8 + k32: STRING_32 + p,q: INTEGER + tb,ptb: detachable WSF_TABLE + do + --| Check if this is a list format such as choice[] or choice[a] or even choice[a][] or choice[a][b][c]... + p := a_name.index_of ('[', 1) + if p > 0 then + q := a_name.index_of (']', p + 1) + if q > p then + n := a_name.substring (1, p - 1) + r := a_name.substring (q + 1, a_name.count) + r.left_adjust; r.right_adjust + + create tb.make (n) + if a_table.has_key (tb.name) and then attached {WSF_TABLE} a_table.found_item as l_existing_table then + tb := l_existing_table + end + + k := a_name.substring (p + 1, q - 1) + k.left_adjust; k.right_adjust + if k.is_empty then + k.append_integer (tb.count + 1) + end + v := tb + n.append_character ('[') + n.append (k) + n.append_character (']') + + from + until + r.is_empty + loop + ptb := tb + p := r.index_of ({CHARACTER_8} '[', 1) + if p > 0 then + q := r.index_of ({CHARACTER_8} ']', p + 1) + if q > p then + k32 := url_encoder.decoded_string (k) + if attached {WSF_TABLE} ptb.value (k32) as l_tb_value then + tb := l_tb_value + else + create tb.make (n) + ptb.add_value (tb, k32) + end + + k := r.substring (p + 1, q - 1) + r := r.substring (q + 1, r.count) + r.left_adjust; r.right_adjust + if k.is_empty then + k.append_integer (tb.count + 1) + end + n.append_character ('[') + n.append (k) + n.append_character (']') + end + else + r.wipe_out + --| Ignore bad value + end + end + tb.add_value (new_string_value (n, a_value), k) + else + --| Missing end bracket + end + end + if v = Void then + v := new_string_value (a_name, a_value) + end + if a_table.has_key (v.name) and then attached a_table.found_item as l_existing_value then + if tb /= Void then + --| Already done in previous part + elseif attached {WSF_MULTIPLE_STRING} l_existing_value as l_multi then + l_multi.add_value (v) + else + a_table.force (create {WSF_MULTIPLE_STRING}.make_with_array (<>), v.name) + check replaced: a_table.found and then a_table.found_item ~ l_existing_value end + end + else + a_table.force (v, v.name) + end + end + + new_string_value (a_name: READABLE_STRING_8; a_value: READABLE_STRING_8): WSF_STRING + do + create Result.make (a_name, a_value) + end + +feature {NONE} -- Implementation + + url_encoder: URL_ENCODER + once + create {UTF8_URL_ENCODER} Result + end + +end diff --git a/library/server/wsf/src/wsf_application_x_www_form_urlencoded_handler.e b/library/server/wsf/src/wsf_application_x_www_form_urlencoded_handler.e new file mode 100644 index 00000000..f92e6360 --- /dev/null +++ b/library/server/wsf/src/wsf_application_x_www_form_urlencoded_handler.e @@ -0,0 +1,64 @@ +note + description: "Summary description for {WSF_APPLICATION_X_WWW_FORM_URLENCODED_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_APPLICATION_X_WWW_FORM_URLENCODED_HANDLER + +inherit + WSF_MIME_HANDLER + + WSF_MIME_HANDLER_HELPER + +feature -- Status report + + valid_content_type (a_content_type: READABLE_STRING_8): BOOLEAN + do + Result := a_content_type.same_string ({HTTP_MIME_TYPES}.application_x_www_form_encoded) + end + +feature -- Execution + + handle (a_content_type: READABLE_STRING_8; a_content_length: NATURAL_64; 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 + n, p, i, j: INTEGER + s: READABLE_STRING_8 + l_name, l_value: READABLE_STRING_8 + do + l_content := read_input_data (req.input, a_content_length) + if a_raw_data /= Void then + a_raw_data.replace (l_content) + end + 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 + until + p = 0 + loop + i := l_content.index_of ('&', p) + if i = 0 then + s := l_content.substring (p, n) + p := 0 + else + s := l_content.substring (p, i - 1) + p := i + 1 + end + if not s.is_empty then + j := s.index_of ('=', 1) + if j > 0 then + l_name := s.substring (1, j - 1) + l_value := s.substring (j + 1, s.count) + add_value_to_table (l_name, l_value, a_vars) + end + end + end + end + end + +end diff --git a/library/server/wsf/src/wsf_mime_handler.e b/library/server/wsf/src/wsf_mime_handler.e new file mode 100644 index 00000000..f7f57d38 --- /dev/null +++ b/library/server/wsf/src/wsf_mime_handler.e @@ -0,0 +1,27 @@ +note + description: "Summary description for {WSF_MIME_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_MIME_HANDLER + +feature -- Status report + + valid_content_type (a_content_type: READABLE_STRING_8): BOOLEAN + deferred + end + +feature -- Execution + + handle (a_content_type: READABLE_STRING_8; a_content_length: NATURAL_64; 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' + require + valid_content_type: valid_content_type (a_content_type) + deferred + end + +end diff --git a/library/server/wsf/src/wsf_multipart_form_data_handler.e b/library/server/wsf/src/wsf_multipart_form_data_handler.e new file mode 100644 index 00000000..4ecfa75b --- /dev/null +++ b/library/server/wsf/src/wsf_multipart_form_data_handler.e @@ -0,0 +1,248 @@ +note + description: "Summary description for {WSF_MULTIPART_FORM_DATA_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_MULTIPART_FORM_DATA_HANDLER + +inherit + WSF_MIME_HANDLER + + WSF_MIME_HANDLER_HELPER + +create + make + +feature {NONE} -- Initialization + + make (a_err_handler: like error_handler) + -- Instantiate Current + do + error_handler := a_err_handler + end + +feature -- Error handling + + has_error: BOOLEAN + do + Result := error_handler.has_error + end + + error_handler: ERROR_HANDLER + -- Error handler + -- By default initialized to new handler + +feature -- Status report + + valid_content_type (a_content_type: READABLE_STRING_8): BOOLEAN + do + Result := a_content_type.starts_with ({HTTP_MIME_TYPES}.multipart_form_data) + end + +feature -- Execution + + handle (a_content_type: READABLE_STRING_8; a_content_length: NATURAL_64; 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) + if a_raw_data /= Void then + a_raw_data.replace (s) + end + --| FIXME: optimization ... fetch the input data progressively, otherwise we might run out of memory ... + analyze_multipart_form (req, a_content_type, s, a_vars) + end + +feature {NONE} -- Implementation: Form analyzer + + analyze_multipart_form (req: WSF_REQUEST; t: READABLE_STRING_8; s: READABLE_STRING_8; vars: HASH_TABLE [WSF_VALUE, READABLE_STRING_32]) + -- Analyze multipart form content + --| FIXME[2011-06-21]: integrate eMIME parser library + require + t_attached: t /= Void + s_attached: s /= Void + vars_attached: vars /= Void + local + p,i,next_b: INTEGER + l_boundary_prefix: STRING + l_boundary: STRING + l_boundary_len: INTEGER + m: STRING + is_crlf: BOOLEAN + do + p := t.substring_index ("boundary=", 1) + if p > 0 then + l_boundary := t.substring (p + 9, t.count) + p := s.substring_index (l_boundary, 1) + if p > 1 then + l_boundary_prefix := s.substring (1, p - 1) + l_boundary := l_boundary_prefix + l_boundary + else + create l_boundary_prefix.make_empty + end + l_boundary_len := l_boundary.count + --| Let's support either %R%N and %N ... + --| Since both cases might occurs (for instance, our implementation of CGI does not have %R%N) + --| then let's be as flexible as possible on this. + is_crlf := s[l_boundary_len + 1] = '%R' + from + i := 1 + l_boundary_len + 1 + if is_crlf then + i := i + 1 --| +1 = CR = %R + end + next_b := i + until + i = 0 + loop + next_b := s.substring_index (l_boundary, i) + if next_b > 0 then + if is_crlf then + m := s.substring (i, next_b - 1 - 2) --| 2 = CR LF = %R %N + else + m := s.substring (i, next_b - 1 - 1) --| 1 = LF = %N + end + analyze_multipart_form_input (req, m, vars) + i := next_b + l_boundary_len + 1 + if is_crlf then + i := i + 1 --| +1 = CR = %R + end + else + if is_crlf then + i := i + 1 + end + m := s.substring (i - 1, s.count) + m.right_adjust + if not l_boundary_prefix.same_string (m) then + error_handler.add_custom_error (0, "Invalid form data", "Invalid ending for form data from input") + end + i := next_b + end + end + end + end + + analyze_multipart_form_input (req: WSF_REQUEST; s: STRING; vars: HASH_TABLE [WSF_VALUE, READABLE_STRING_32]) + -- Analyze multipart entry + require + s_not_empty: s /= Void and then not s.is_empty + local + n, i,p, b,e: INTEGER + l_name, l_filename, l_content_type: detachable STRING_8 + l_header: detachable STRING_8 + l_content: detachable STRING_8 + l_line: detachable STRING_8 + l_up_file_info: WGI_UPLOADED_FILE_DATA + do + from + p := 1 + n := s.count + until + p > n or l_header /= Void + loop + inspect s[p] + when '%R' then -- CR + if + n >= p + 3 and then + s[p+1] = '%N' and then -- LF + s[p+2] = '%R' and then -- CR + s[p+3] = '%N' -- LF + then + l_header := s.substring (1, p + 1) + l_content := s.substring (p + 4, n) + end + when '%N' then + if + n >= p + 1 and then + s[p+1] = '%N' + then + l_header := s.substring (1, p) + l_content := s.substring (p + 2, n) + end + else + end + p := p + 1 + end + if l_header /= Void and l_content /= Void then + from + i := 1 + n := l_header.count + until + i = 0 or i > n + loop + l_line := Void + b := i + p := l_header.index_of ('%N', b) + if p > 0 then + if l_header[p - 1] = '%R' then + p := p - 1 + i := p + 2 + else + i := p + 1 + end + end + if p > 0 then + l_line := l_header.substring (b, p - 1) + if l_line.starts_with ("Content-Disposition: form-data") then + p := l_line.substring_index ("name=", 1) + if p > 0 then + p := p + 4 --| 4 = ("name=").count - 1 + if l_line.valid_index (p+1) and then l_line[p+1] = '%"' then + p := p + 1 + e := l_line.index_of ('"', p + 1) + else + e := l_line.index_of (';', p + 1) + if e = 0 then + e := l_line.count + end + end + l_name := l_header.substring (p + 1, e - 1) + end + + p := l_line.substring_index ("filename=", 1) + if p > 0 then + p := p + 8 --| 8 = ("filename=").count - 1 + if l_line.valid_index (p+1) and then l_line[p+1] = '%"' then + p := p + 1 + e := l_line.index_of ('"', p + 1) + else + e := l_line.index_of (';', p + 1) + if e = 0 then + e := l_line.count + end + end + l_filename := l_header.substring (p + 1, e - 1) + end + elseif l_line.starts_with ("Content-Type: ") then + l_content_type := l_line.substring (15, l_line.count) + end + else + i := 0 + end + end + if l_name /= Void then + if l_filename /= Void then + if l_content_type = Void then + l_content_type := default_content_type + end + create l_up_file_info.make (l_filename, l_content_type, l_content.count) + req.save_uploaded_file (l_content, l_up_file_info) + req.uploaded_files.force (l_up_file_info, l_name) + else + add_value_to_table (l_name, l_content, vars) + end + else + error_handler.add_custom_error (0, "unamed multipart entry", Void) + end + else + error_handler.add_custom_error (0, "missformed multipart entry", Void) + end + end + + default_content_type: STRING = "text/plain" + -- Default content type + + +end diff --git a/library/server/wsf/src/wsf_request.e b/library/server/wsf/src/wsf_request.e index d2727916..ea92efd8 100644 --- a/library/server/wsf/src/wsf_request.e +++ b/library/server/wsf/src/wsf_request.e @@ -53,6 +53,8 @@ feature {NONE} -- Initialization local s8: detachable READABLE_STRING_8 do + init_mime_handlers + --| Content-Length if attached content_length as s and then s.is_natural_64 then content_length_value := s.to_natural_64 @@ -1017,40 +1019,112 @@ feature -- Form fields and related --| error: if /= 0 , there was an error : TODO ... --| size: size of the file given by the http request +feature -- Access: MIME handler + + has_mime_handler (a_content_type: READABLE_STRING_8): BOOLEAN + -- Has a MIME handler registered for `a_content_type'? + do + if attached mime_handlers as hdls then + from + hdls.start + until + hdls.after or Result + loop + Result := hdls.item_for_iteration.valid_content_type (a_content_type) + hdls.forth + end + end + end + + register_mime_handler (a_handler: WSF_MIME_HANDLER) + -- Register `a_handler' for `a_content_type' + local + hdls: like mime_handlers + do + hdls := mime_handlers + if hdls = Void then + create hdls.make (3) + hdls.compare_objects + mime_handlers := hdls + end + hdls.force (a_handler) + end + + mime_handler (a_content_type: READABLE_STRING_8): detachable WSF_MIME_HANDLER + -- Mime handler associated with `a_content_type' + do + if attached mime_handlers as hdls then + from + hdls.start + until + hdls.after or Result /= Void + loop + Result := hdls.item_for_iteration + if not Result.valid_content_type (a_content_type) then + Result := Void + end + hdls.forth + end + end + ensure + has_mime_handler_implies_attached: has_mime_handler (a_content_type) implies Result /= Void + end + +feature {NONE} -- Implementation: MIME handler + + init_mime_handlers + do + register_mime_handler (create {WSF_MULTIPART_FORM_DATA_HANDLER}.make (error_handler)) + register_mime_handler (create {WSF_APPLICATION_X_WWW_FORM_URLENCODED_HANDLER}) + end + + mime_handlers: detachable ARRAYED_LIST [WSF_MIME_HANDLER] + -- Table of mime handles + feature {NONE} -- Form fields and related form_parameters_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_32] -- Variables sent by POST request local vars: like internal_form_data_parameters_table - s: READABLE_STRING_8 + 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 - l_type := content_type - if - l_type /= Void and then - l_type.starts_with ({HTTP_MIME_TYPES}.multipart_form_data) - then - create vars.make (5) - vars.compare_objects - --| FIXME: optimization ... fetch the input data progressively, otherwise we might run out of memory ... - s := form_input_data (n) - analyze_multipart_form (l_type, s, vars) - else - s := form_input_data (n) - vars := urlencoded_parameters (s) - end - if raw_post_data_recorded then - set_meta_string_variable ("RAW_POST_DATA", s) - end - else + if n = 0 then create vars.make (0) vars.compare_objects + else + if raw_post_data_recorded then + create l_raw_data_cell.put (Void) + end + create vars.make (5) + vars.compare_objects + + 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) + end + if l_raw_data_cell /= Void and then attached l_raw_data_cell.item as l_raw_data then + set_meta_string_variable ("RAW_POST_DATA", l_raw_data) + end + +-- if +-- l_type /= Void and then +-- l_type.starts_with ({HTTP_MIME_TYPES}.multipart_form_data) +-- then +-- create vars.make (5) +-- vars.compare_objects +-- --| FIXME: optimization ... fetch the input data progressively, otherwise we might run out of memory ... +-- s := form_input_data (n) +-- analyze_multipart_form (l_type, s, vars) +-- else +-- s := form_input_data (n) +-- vars := urlencoded_parameters (s) +-- end end internal_form_data_parameters_table := vars end @@ -1130,7 +1204,8 @@ feature -- URL Utility end internal_url_base := l_base_url end - Result := l_base_url + a_path + create Result.make_from_string (l_base_url) + Result.append (a_path) end feature {NONE} -- Implementation: URL Utility @@ -1152,7 +1227,7 @@ feature -- Element change error_handler := ehdl end -feature {NONE} -- Temporary File handling +feature {WSF_MIME_HANDLER} -- Temporary File handling delete_uploaded_file (uf: WGI_UPLOADED_FILE_DATA) -- Delete file `a_filename' @@ -1312,225 +1387,42 @@ feature {NONE} -- Temporary File handling end end -feature {NONE} -- Implementation: Form analyzer - - analyze_multipart_form (t: STRING; s: STRING; vars: like form_parameters_table) - -- Analyze multipart form content - --| FIXME[2011-06-21]: integrate eMIME parser library - require - t_attached: t /= Void - s_attached: s /= Void - vars_attached: vars /= Void - local - p,i,next_b: INTEGER - l_boundary_prefix: STRING - l_boundary: STRING - l_boundary_len: INTEGER - m: STRING - is_crlf: BOOLEAN - do - p := t.substring_index ("boundary=", 1) - if p > 0 then - l_boundary := t.substring (p + 9, t.count) - p := s.substring_index (l_boundary, 1) - if p > 1 then - l_boundary_prefix := s.substring (1, p - 1) - l_boundary := l_boundary_prefix + l_boundary - else - create l_boundary_prefix.make_empty - end - l_boundary_len := l_boundary.count - --| Let's support either %R%N and %N ... - --| Since both cases might occurs (for instance, our implementation of CGI does not have %R%N) - --| then let's be as flexible as possible on this. - is_crlf := s[l_boundary_len + 1] = '%R' - from - i := 1 + l_boundary_len + 1 - if is_crlf then - i := i + 1 --| +1 = CR = %R - end - next_b := i - until - i = 0 - loop - next_b := s.substring_index (l_boundary, i) - if next_b > 0 then - if is_crlf then - m := s.substring (i, next_b - 1 - 2) --| 2 = CR LF = %R %N - else - m := s.substring (i, next_b - 1 - 1) --| 1 = LF = %N - end - analyze_multipart_form_input (m, vars) - i := next_b + l_boundary_len + 1 - if is_crlf then - i := i + 1 --| +1 = CR = %R - end - else - if is_crlf then - i := i + 1 - end - m := s.substring (i - 1, s.count) - m.right_adjust - if not l_boundary_prefix.same_string (m) then - error_handler.add_custom_error (0, "Invalid form data", "Invalid ending for form data from input") - end - i := next_b - end - end - end - end - - analyze_multipart_form_input (s: STRING; vars_post: like form_parameters_table) - -- Analyze multipart entry - require - s_not_empty: s /= Void and then not s.is_empty - local - n, i,p, b,e: INTEGER - l_name, l_filename, l_content_type: detachable STRING_8 - l_header: detachable STRING_8 - l_content: detachable STRING_8 - l_line: detachable STRING_8 - l_up_file_info: WGI_UPLOADED_FILE_DATA - do - from - p := 1 - n := s.count - until - p > n or l_header /= Void - loop - inspect s[p] - when '%R' then -- CR - if - n >= p + 3 and then - s[p+1] = '%N' and then -- LF - s[p+2] = '%R' and then -- CR - s[p+3] = '%N' -- LF - then - l_header := s.substring (1, p + 1) - l_content := s.substring (p + 4, n) - end - when '%N' then - if - n >= p + 1 and then - s[p+1] = '%N' - then - l_header := s.substring (1, p) - l_content := s.substring (p + 2, n) - end - else - end - p := p + 1 - end - if l_header /= Void and l_content /= Void then - from - i := 1 - n := l_header.count - until - i = 0 or i > n - loop - l_line := Void - b := i - p := l_header.index_of ('%N', b) - if p > 0 then - if l_header[p - 1] = '%R' then - p := p - 1 - i := p + 2 - else - i := p + 1 - end - end - if p > 0 then - l_line := l_header.substring (b, p - 1) - if l_line.starts_with ("Content-Disposition: form-data") then - p := l_line.substring_index ("name=", 1) - if p > 0 then - p := p + 4 --| 4 = ("name=").count - 1 - if l_line.valid_index (p+1) and then l_line[p+1] = '%"' then - p := p + 1 - e := l_line.index_of ('"', p + 1) - else - e := l_line.index_of (';', p + 1) - if e = 0 then - e := l_line.count - end - end - l_name := l_header.substring (p + 1, e - 1) - end - - p := l_line.substring_index ("filename=", 1) - if p > 0 then - p := p + 8 --| 8 = ("filename=").count - 1 - if l_line.valid_index (p+1) and then l_line[p+1] = '%"' then - p := p + 1 - e := l_line.index_of ('"', p + 1) - else - e := l_line.index_of (';', p + 1) - if e = 0 then - e := l_line.count - end - end - l_filename := l_header.substring (p + 1, e - 1) - end - elseif l_line.starts_with ("Content-Type: ") then - l_content_type := l_line.substring (15, l_line.count) - end - else - i := 0 - end - end - if l_name /= Void then - if l_filename /= Void then - if l_content_type = Void then - l_content_type := default_content_type - end - create l_up_file_info.make (l_filename, l_content_type, l_content.count) - save_uploaded_file (l_content, l_up_file_info) - uploaded_files.force (l_up_file_info, l_name) - else - add_value_to_table (l_name, l_content, vars_post) - end - else - error_handler.add_custom_error (0, "unamed multipart entry", Void) - end - else - error_handler.add_custom_error (0, "missformed multipart entry", Void) - end - end - -feature {NONE} -- Internal value - - default_content_type: STRING = "text/plain" - -- Default content type +feature {WSF_MIME_HANDLER} -- Input data access form_input_data (nb: NATURAL_64): READABLE_STRING_8 - -- data from input form + -- All data from input form local nb32: INTEGER + n64: NATURAL_64 n: INTEGER t: STRING s: STRING_8 do from - nb32 := nb.to_integer_32 - n := nb32 - create s.make (n) + n64 := nb + nb32 := n64.to_integer_32 + create s.make (nb32) Result := s + n := nb32 if n > 1_024 then n := 1_024 end until - n <= 0 + n64 <= 0 loop input.read_string (n) t := input.last_string s.append_string (t) if t.count < n then - n := 0 + n64 := 0 + else + n64 := n64 - t.count.as_natural_64 end - n := nb32 - t.count end end +feature {NONE} -- Internal value + internal_query_parameters_table: detachable like query_parameters_table -- cached value for `query_parameters'