From 79e12b8d044801dbb37e4135573b460c84136dd6 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Fri, 21 Oct 2011 12:56:00 +0200 Subject: [PATCH] Continued reducing WGI and move implementation to WSF (Web Server Framework) Removed many usage of READABLE_STRING_GENERAL in favor to READABLE_STRING_8 to avoid potential nasty issues in user's code URI-template is working only with STRING_8, then changed any _GENERAL or _STRING_32 to _STRING_8 --- .../src/http_file_extension_mime_mapping.e | 1 - .../protocol/uri_template/src/uri_template.e | 12 +- .../src/uri_template_match_result.e | 19 +- .../request/value/wgi_multiple_string_value.e | 143 --------- .../request/value/wgi_string_value.e | 71 ----- .../ewsgi/specification/request/wgi_request.e | 5 - .../ewsgi/specification/request/wgi_value.e | 59 ---- .../server/ewsgi/src/wgi_request_from_table.e | 277 ++++++------------ .../router/src/request_handler_context.e | 16 +- .../src/uri/request_uri_handler_context.e | 4 +- .../request_uri_template_handler_context.e | 4 +- .../request_uri_template_router_i.e | 4 +- .../wsf/src/request/value/wsf_string_value.e | 26 +- library/server/wsf/src/wsf_request.e | 113 +++---- 14 files changed, 199 insertions(+), 555 deletions(-) delete mode 100644 library/server/ewsgi/specification/request/value/wgi_multiple_string_value.e delete mode 100644 library/server/ewsgi/specification/request/value/wgi_string_value.e delete mode 100644 library/server/ewsgi/specification/request/wgi_value.e diff --git a/library/protocol/http/src/http_file_extension_mime_mapping.e b/library/protocol/http/src/http_file_extension_mime_mapping.e index 9434a879..387e8ed4 100644 --- a/library/protocol/http/src/http_file_extension_mime_mapping.e +++ b/library/protocol/http/src/http_file_extension_mime_mapping.e @@ -126,7 +126,6 @@ feature {NONE} -- Initialization end end - feature -- Access mime_type (ext: READABLE_STRING_8): detachable READABLE_STRING_8 diff --git a/library/protocol/uri_template/src/uri_template.e b/library/protocol/uri_template/src/uri_template.e index 6807e3cb..4f74c0de 100644 --- a/library/protocol/uri_template/src/uri_template.e +++ b/library/protocol/uri_template/src/uri_template.e @@ -189,7 +189,7 @@ feature -- Match exp: URI_TEMPLATE_EXPRESSION vn, s,t: STRING vv, path_vv: STRING - l_vars, l_path_vars, l_query_vars: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL] + l_vars, l_path_vars, l_query_vars: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] l_uri_count: INTEGER tpl_count: INTEGER l_next_literal_separator: detachable STRING @@ -414,7 +414,7 @@ feature {NONE} -- Implementation end end - import_path_style_parameters_into (a_content: STRING; res: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]) + import_path_style_parameters_into (a_content: STRING; res: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]) require a_content_attached: a_content /= Void res_attached: res /= Void @@ -422,7 +422,7 @@ feature {NONE} -- Implementation import_custom_style_parameters_into (a_content, ';', res) end - import_form_style_parameters_into (a_content: STRING; res: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]) + import_form_style_parameters_into (a_content: STRING; res: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]) require a_content_attached: a_content /= Void res_attached: res /= Void @@ -430,14 +430,14 @@ feature {NONE} -- Implementation import_custom_style_parameters_into (a_content, '&', res) end - import_custom_style_parameters_into (a_content: STRING; a_separator: CHARACTER; res: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]) + import_custom_style_parameters_into (a_content: STRING; a_separator: CHARACTER; res: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]) require a_content_attached: a_content /= Void res_attached: res /= Void local n, p, i, j: INTEGER - s: STRING - l_name,l_value: STRING + s: READABLE_STRING_8 + l_name, l_value: READABLE_STRING_8 do n := a_content.count if n > 0 then diff --git a/library/protocol/uri_template/src/uri_template_match_result.e b/library/protocol/uri_template/src/uri_template_match_result.e index 1077444c..7feb8d0e 100644 --- a/library/protocol/uri_template/src/uri_template_match_result.e +++ b/library/protocol/uri_template/src/uri_template_match_result.e @@ -24,30 +24,29 @@ feature {NONE} -- Initialization make (create {like path_variables}.make (0), create {like query_variables}.make (0)) end - feature -- Access - path_variables: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL] + path_variables: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] -- Variables being part of the path segments - query_variables: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL] + query_variables: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] -- Variables being part of the query segments (i.e: after the ?) feature -- Query - path_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + path_variable (n: READABLE_STRING_8): detachable READABLE_STRING_8 -- Value related to query variable name `n' do Result := path_variables.item (n) end - query_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + query_variable (n: READABLE_STRING_8): detachable READABLE_STRING_8 -- Value related to path variable name `n' do Result := query_variables.item (n) end - variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + variable (n: READABLE_STRING_8): detachable READABLE_STRING_8 -- Value related to variable name `n' do Result := query_variable (n) @@ -58,7 +57,7 @@ feature -- Query feature -- Query: url-decoded - url_decoded_query_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + url_decoded_query_variable (n: READABLE_STRING_8): detachable READABLE_STRING_32 -- Unencoded value related to variable name `n' do if attached query_variable (n) as v then @@ -66,7 +65,7 @@ feature -- Query: url-decoded end end - url_decoded_path_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + url_decoded_path_variable (n: READABLE_STRING_8): detachable READABLE_STRING_32 -- Unencoded value related to variable name `n' do if attached path_variable (n) as v then @@ -74,7 +73,7 @@ feature -- Query: url-decoded end end - url_decoded_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + url_decoded_variable (n: READABLE_STRING_8): detachable READABLE_STRING_32 -- Unencoded value related to variable name `n' do if attached variable (n) as v then @@ -84,7 +83,7 @@ feature -- Query: url-decoded feature {NONE} -- Implementation - url_decoded_string (s: READABLE_STRING_GENERAL): READABLE_STRING_32 + url_decoded_string (s: READABLE_STRING_8): READABLE_STRING_32 do Result := url_encoder.decoded_string (s.as_string_8) end diff --git a/library/server/ewsgi/specification/request/value/wgi_multiple_string_value.e b/library/server/ewsgi/specification/request/value/wgi_multiple_string_value.e deleted file mode 100644 index acd6645d..00000000 --- a/library/server/ewsgi/specification/request/value/wgi_multiple_string_value.e +++ /dev/null @@ -1,143 +0,0 @@ -note - description: "Summary description for {WGI_MULTIPLE_STRING_VALUE}." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - WGI_MULTIPLE_STRING_VALUE - -inherit - WGI_VALUE - - ITERABLE [WGI_STRING_VALUE] - -create - make_with_value, - make_with_array, - make_with_string - -feature {NONE} -- Initialization - - make_with_value (a_value: WGI_VALUE) - do - name := a_value.name - create {LINKED_LIST [WGI_STRING_VALUE]} string_values.make - add_value (a_value) - end - - make_with_array (arr: ARRAY [WGI_VALUE]) - require - arr_not_empty: not arr.is_empty - all_same_name: across arr as c all c.item.name.same_string (arr[arr.lower].name) end - local - i,up: INTEGER - do - up := arr.upper - i := arr.lower - make_with_value (arr[i]) - from - i := i + 1 - until - i > up - loop - add_value (arr[i]) - i := i + 1 - end - end - - make_with_string (a_name: like name; a_string: READABLE_STRING_32) - do - make_with_value (create {WGI_STRING_VALUE}.make (a_name, a_string)) - end - -feature -- Access - - name: READABLE_STRING_32 - - string_values: LIST [WGI_STRING_VALUE] - - first_string_value: WGI_STRING_VALUE - do - Result := string_values.first - end - -feature -- Traversing - - new_cursor: ITERATION_CURSOR [WGI_STRING_VALUE] - do - Result := string_values.new_cursor - end - -feature -- Helper - - same_string (a_other: READABLE_STRING_GENERAL): BOOLEAN - -- Does `a_other' represent the same string as `Current'? - do - if string_values.count = 1 then - Result := first_string_value.same_string (a_other) - end - end - - is_case_insensitive_equal (a_other: READABLE_STRING_8): BOOLEAN - -- Does `a_other' represent the same case insensitive string as `Current'? - do - if string_values.count = 1 then - Result := first_string_value.is_case_insensitive_equal (a_other) - end - end - - as_string: STRING_32 - do - if string_values.count = 1 then - create Result.make_from_string (first_string_value) - else - create Result.make_from_string ("[") - across - string_values as c - loop - if Result.count > 1 then - Result.append_character (',') - end - Result.append_string (c.item) - end - Result.append_character (']') - end - end - -feature -- Element change - - add_value (a_value: WGI_VALUE) - require - same_name: a_value.name.same_string (name) - do - if attached {WGI_STRING_VALUE} a_value as sval then - add_string_value (sval) - elseif attached {WGI_MULTIPLE_STRING_VALUE} a_value as slst then - across - slst as cur - loop - add_string_value (cur.item) - end - end - end - - add_string_value (s: WGI_STRING_VALUE) - do - string_values.extend (s) - end - -invariant - string_values_not_empty: string_values.count >= 1 - -;note - copyright: "2011-2011, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 5949 Hollister Ave., Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" -end diff --git a/library/server/ewsgi/specification/request/value/wgi_string_value.e b/library/server/ewsgi/specification/request/value/wgi_string_value.e deleted file mode 100644 index 3f3f6f2d..00000000 --- a/library/server/ewsgi/specification/request/value/wgi_string_value.e +++ /dev/null @@ -1,71 +0,0 @@ -note - description: "Summary description for {WGI_STRING_VALUE}." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - WGI_STRING_VALUE - -inherit - WGI_VALUE - -create - make - -convert - as_string: {READABLE_STRING_32, STRING_32} - -feature {NONE} -- Initialization - - make (a_name: READABLE_STRING_GENERAL; a_string: like string) - do - name := a_name.as_string_32 - string := a_string - end - -feature -- Access - - name: READABLE_STRING_32 - - string: READABLE_STRING_32 - -feature -- Helper - - same_string (a_other: READABLE_STRING_GENERAL): BOOLEAN - -- Does `a_other' represent the same string as `Current'? - do - Result := string.same_string_general (a_other) - end - - is_case_insensitive_equal (a_other: READABLE_STRING_8): BOOLEAN - -- Does `a_other' represent the same case insensitive string as `Current'? - local - v: like string - do - v := string - if v = a_other then - Result := True - elseif v.is_valid_as_string_8 then - Result := v.is_case_insensitive_equal (a_other) - end - end - -feature -- Conversion - - as_string: STRING_32 - do - create Result.make_from_string (string) - end - -;note - copyright: "2011-2011, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 5949 Hollister Ave., Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" -end diff --git a/library/server/ewsgi/specification/request/wgi_request.e b/library/server/ewsgi/specification/request/wgi_request.e index 7f286400..cf169bf5 100644 --- a/library/server/ewsgi/specification/request/wgi_request.e +++ b/library/server/ewsgi/specification/request/wgi_request.e @@ -168,11 +168,6 @@ feature -- Common Gateway Interface - 1.1 8 January 1996 deferred end - content_length_value: NATURAL_64 - -- Integer value related to `content_length" - deferred - end - content_type: detachable READABLE_STRING_8 -- If the request includes a message-body, CONTENT_TYPE is set to -- the Internet Media Type [9] of the attached entity if the type diff --git a/library/server/ewsgi/specification/request/wgi_value.e b/library/server/ewsgi/specification/request/wgi_value.e deleted file mode 100644 index 59d4e6eb..00000000 --- a/library/server/ewsgi/specification/request/wgi_value.e +++ /dev/null @@ -1,59 +0,0 @@ -note - description: "Summary description for {WGI_VALUE}." - author: "" - date: "$Date$" - revision: "$Revision$" - -deferred class - WGI_VALUE - -inherit - DEBUG_OUTPUT - -convert - as_string: {READABLE_STRING_32, STRING_32} - -feature -- Access - - name: READABLE_STRING_32 - -- Parameter name - deferred - end - -feature -- Helper - - same_string (a_other: READABLE_STRING_GENERAL): BOOLEAN - -- Does `a_other' represent the same string as `Current'? - deferred - end - - is_case_insensitive_equal (a_other: READABLE_STRING_8): BOOLEAN - -- Does `a_other' represent the same case insensitive string as `Current'? - deferred - end - -feature -- Status report - - debug_output: STRING - -- String that should be displayed in debugger to represent `Current'. - do - create Result.make_from_string (name.as_string_8 + "=" + as_string.as_string_8) - end - -feature -- Query - - as_string: STRING_32 - deferred - end - -note - copyright: "2011-2011, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 5949 Hollister Ave., Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" -end diff --git a/library/server/ewsgi/src/wgi_request_from_table.e b/library/server/ewsgi/src/wgi_request_from_table.e index 68055a2a..a39b1c12 100644 --- a/library/server/ewsgi/src/wgi_request_from_table.e +++ b/library/server/ewsgi/src/wgi_request_from_table.e @@ -23,152 +23,26 @@ feature {NONE} -- Initialization require vars_attached: a_vars /= Void do - create error_handler.make input := a_input - set_meta_parameters (a_vars) + set_meta_variables (a_vars) - initialize - analyze + update_path_info end - set_meta_parameters (a_vars: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]) - -- Fill with variable from `a_vars' - local - s: like meta_string_variable - table: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] - l_query_string: like query_string - l_request_uri: detachable STRING_32 - do - create {STRING_8} empty_string.make_empty - - create table.make (a_vars.count) - table.compare_objects - meta_variables_table := table - from - a_vars.start - until - a_vars.after - loop - table.force (new_string_value (a_vars.key_for_iteration, a_vars.item_for_iteration), a_vars.key_for_iteration) - a_vars.forth - end - - --| QUERY_STRING - l_query_string := meta_string_variable_or_default ({WGI_META_NAMES}.query_string, empty_string, False) - query_string := l_query_string - - --| REQUEST_METHOD - request_method := meta_string_variable_or_default ({WGI_META_NAMES}.request_method, empty_string, False) - - --| CONTENT_TYPE - s := meta_string_variable ({WGI_META_NAMES}.content_type) - if s /= Void and then not s.is_empty then - content_type := s - else - content_type := Void - end - - --| CONTENT_LENGTH - s := meta_string_variable ({WGI_META_NAMES}.content_length) - content_length := s - if s /= Void and then s.is_natural_64 then - content_length_value := s.to_natural_64 - else - --| content_length := 0 - end - - --| PATH_INFO - path_info := meta_string_variable_or_default ({WGI_META_NAMES}.path_info, empty_string, False) - - --| SERVER_NAME - server_name := meta_string_variable_or_default ({WGI_META_NAMES}.server_name, empty_string, False) - - --| SERVER_PORT - s := meta_string_variable ({WGI_META_NAMES}.server_port) - if s /= Void and then s.is_integer then - server_port := s.to_integer - else - server_port := 80 - end - - --| SCRIPT_NAME - script_name := meta_string_variable_or_default ({WGI_META_NAMES}.script_name, empty_string, False) - - --| REMOTE_ADDR - remote_addr := meta_string_variable_or_default ({WGI_META_NAMES}.remote_addr, empty_string, False) - - --| REMOTE_HOST - remote_host := meta_string_variable_or_default ({WGI_META_NAMES}.remote_host, empty_string, False) - - --| REQUEST_URI - s := meta_string_variable ({WGI_META_NAMES}.request_uri) - if s /= Void then - l_request_uri := s - else - --| It might occur that REQUEST_URI is not available, so let's compute it from SCRIPT_NAME - create l_request_uri.make_from_string (script_name) - if not l_query_string.is_empty then - l_request_uri.append_character ('?') - l_request_uri.append (l_query_string) - end - end - request_uri := single_slash_starting_string (l_request_uri) - end - - initialize - -- Specific initialization - do - --| Here one can set its own environment entries if needed --- if meta_variable ({WGI_META_NAMES}.request_time) = Void then --- set_meta_string_variable ({WGI_META_NAMES}.request_time, date_time_utilities.unix_time_stamp (Void).out) --- end - 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 -- Access: Input input: WGI_INPUT_STREAM -- Server input channel ---feature -- Access extra information --- --- request_time: detachable DATE_TIME --- -- Request time (UTC) --- do --- if --- attached {WGI_STRING_VALUE} meta_variable ({WGI_META_NAMES}.request_time) as t and then --- t.string.is_integer_64 --- then --- Result := date_time_utilities.unix_time_stamp_to_date_time (t.string.to_integer_64) --- end --- end - -feature {NONE} -- Access: CGI meta parameters - - meta_variables_table: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] - -- CGI Environment parameters - feature -- Access: CGI meta parameters meta_variables: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] - do - Result := meta_variables_table - end + -- CGI Environment parameters meta_variable (a_name: READABLE_STRING_8): detachable READABLE_STRING_8 -- CGI meta variable related to `a_name' do - Result := meta_variables_table.item (a_name) + Result := meta_variables.item (a_name) end meta_string_variable_or_default (a_name: READABLE_STRING_8; a_default: READABLE_STRING_8; use_default_when_empty: BOOLEAN): READABLE_STRING_8 @@ -189,14 +63,14 @@ feature -- Access: CGI meta parameters set_meta_string_variable (a_name: READABLE_STRING_8; a_value: READABLE_STRING_8) do - meta_variables_table.force (new_string_value (a_name, a_value), a_name) + meta_variables.force (a_value, a_name) ensure param_set: attached meta_variable (a_name) as val and then val ~ a_value end unset_meta_variable (a_name: READABLE_STRING_8) do - meta_variables_table.remove (a_name) + meta_variables.remove (a_name) ensure param_unset: meta_variable (a_name) = Void end @@ -207,8 +81,6 @@ feature -- Access: CGI meta parameters - 1.1 content_length: detachable READABLE_STRING_8 - content_length_value: NATURAL_64 - content_type: detachable READABLE_STRING_8 gateway_interface: READABLE_STRING_8 @@ -340,6 +212,84 @@ feature -- Access: Extension to CGI meta parameters - 1.1 feature {NONE} -- Element change: CGI meta parameter related to PATH_INFO + set_meta_variables (a_vars: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]) + -- Fill with variable from `a_vars' + local + s: like meta_string_variable + table: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] + l_query_string: like query_string + l_request_uri: detachable STRING_32 + do + create {STRING_8} empty_string.make_empty + + create table.make (a_vars.count) + table.compare_objects + meta_variables := table + from + a_vars.start + until + a_vars.after + loop + table.force (a_vars.item_for_iteration, a_vars.key_for_iteration) + a_vars.forth + end + + --| QUERY_STRING + l_query_string := meta_string_variable_or_default ({WGI_META_NAMES}.query_string, empty_string, False) + query_string := l_query_string + + --| REQUEST_METHOD + request_method := meta_string_variable_or_default ({WGI_META_NAMES}.request_method, empty_string, False) + + --| CONTENT_TYPE + s := meta_string_variable ({WGI_META_NAMES}.content_type) + if s /= Void and then not s.is_empty then + content_type := s + else + content_type := Void + end + + --| CONTENT_LENGTH + content_length := meta_string_variable ({WGI_META_NAMES}.content_length) + + --| PATH_INFO + path_info := meta_string_variable_or_default ({WGI_META_NAMES}.path_info, empty_string, False) + + --| SERVER_NAME + server_name := meta_string_variable_or_default ({WGI_META_NAMES}.server_name, empty_string, False) + + --| SERVER_PORT + s := meta_string_variable ({WGI_META_NAMES}.server_port) + if s /= Void and then s.is_integer then + server_port := s.to_integer + else + server_port := 80 + end + + --| SCRIPT_NAME + script_name := meta_string_variable_or_default ({WGI_META_NAMES}.script_name, empty_string, False) + + --| REMOTE_ADDR + remote_addr := meta_string_variable_or_default ({WGI_META_NAMES}.remote_addr, empty_string, False) + + --| REMOTE_HOST + remote_host := meta_string_variable_or_default ({WGI_META_NAMES}.remote_host, empty_string, False) + + --| REQUEST_URI + s := meta_string_variable ({WGI_META_NAMES}.request_uri) + if s /= Void then + l_request_uri := s + else + --| It might occur that REQUEST_URI is not available, so let's compute it from SCRIPT_NAME + create l_request_uri.make_from_string (script_name) + if not l_query_string.is_empty then + l_request_uri.append_character ('?') + l_request_uri.append (l_query_string) + end + end + request_uri := single_slash_starting_string (l_request_uri) + end + set_orig_path_info (s: READABLE_STRING_8) -- Set ORIG_PATH_INFO to `s' require @@ -381,14 +331,6 @@ feature {NONE} -- Element change: CGI meta parameter related to PATH_INFO end end -feature -- Element change - - set_error_handler (ehdl: like error_handler) - -- Set `error_handler' to `ehdl' - do - error_handler := ehdl - end - feature {NONE} -- I/O: implementation read_input (nb: INTEGER) @@ -403,46 +345,6 @@ feature {NONE} -- I/O: implementation Result := input.last_string end -feature {NONE} -- Implementation - - report_bad_request_error (a_message: detachable STRING) - -- Report error - local - e: EWF_ERROR - do - create e.make ({HTTP_STATUS_CODE}.bad_request) - if a_message /= Void then - e.set_message (a_message) - end - error_handler.add_error (e) - end - - analyze - -- Extract relevant meta parameters - local - s: detachable READABLE_STRING_8 - do - s := request_uri - if s.is_empty then - report_bad_request_error ("Missing URI") - end - if not has_error then - s := request_method - if s.is_empty then - report_bad_request_error ("Missing request method") - end - end - if not has_error then - s := http_host - if s = Void or else s.is_empty then - report_bad_request_error ("Missing host header") - end - end - if not has_error then - update_path_info - end - end - feature {NONE} -- Implementation: utilities single_slash_starting_string (s: READABLE_STRING_8): STRING_8 @@ -491,20 +393,9 @@ feature {NONE} -- Implementation: utilities one_starting_slash: Result[1] = '/' and (Result.count = 1 or else Result[2] /= '/') end - new_string_value (a_name: READABLE_STRING_8; a_value: READABLE_STRING_8): READABLE_STRING_8 - do - Result := a_value - end - empty_string: READABLE_STRING_8 -- Reusable empty string --- date_time_utilities: HTTP_DATE_TIME_UTILITIES --- -- Utilities classes related to date and time. --- once --- create Result --- end - invariant empty_string_unchanged: empty_string.is_empty diff --git a/library/server/request/router/src/request_handler_context.e b/library/server/request/router/src/request_handler_context.e index db2e908e..12cbda99 100644 --- a/library/server/request/router/src/request_handler_context.e +++ b/library/server/request/router/src/request_handler_context.e @@ -31,7 +31,7 @@ feature {NONE} -- Constants feature -- Query - request_format (a_format_variable_name: detachable READABLE_STRING_GENERAL; content_type_supported: detachable ARRAY [READABLE_STRING_8]): detachable READABLE_STRING_8 + request_format (a_format_variable_name: detachable READABLE_STRING_8; content_type_supported: detachable ARRAY [READABLE_STRING_8]): detachable READABLE_STRING_8 -- Format id for the request based on {HTTP_FORMAT_CONSTANTS} do if a_format_variable_name /= Void and then attached string_parameter (a_format_variable_name) as ctx_format then @@ -41,7 +41,7 @@ feature -- Query end end - request_format_id (a_format_variable_name: detachable READABLE_STRING_GENERAL; content_type_supported: detachable ARRAY [READABLE_STRING_8]): INTEGER + request_format_id (a_format_variable_name: detachable READABLE_STRING_8; content_type_supported: detachable ARRAY [READABLE_STRING_8]): INTEGER -- Format id for the request based on {HTTP_FORMAT_CONSTANTS} do if attached request_format (a_format_variable_name, content_type_supported) as l_format then @@ -107,18 +107,18 @@ feature -- Query feature -- Query - path_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE + path_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE -- Parameter value for path variable `a_name' deferred end - query_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE + query_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE -- Parameter value for query variable `a_name' --| i.e after the ? character deferred end - parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE + parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE -- Any parameter value for variable `a_name' -- URI template parameter and query parameters do @@ -137,17 +137,17 @@ feature -- String query end end - string_path_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + string_path_parameter (a_name: READABLE_STRING_8): detachable READABLE_STRING_32 do Result := string_from (path_parameter (a_name)) end - string_query_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + string_query_parameter (a_name: READABLE_STRING_8): detachable READABLE_STRING_32 do Result := string_from (query_parameter (a_name)) end - string_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + string_parameter (a_name: READABLE_STRING_8): detachable READABLE_STRING_32 do Result := string_from (parameter (a_name)) end diff --git a/library/server/request/router/src/uri/request_uri_handler_context.e b/library/server/request/router/src/uri/request_uri_handler_context.e index 543ac4d3..ec7077c8 100644 --- a/library/server/request/router/src/uri/request_uri_handler_context.e +++ b/library/server/request/router/src/uri/request_uri_handler_context.e @@ -23,11 +23,11 @@ feature {NONE} -- Initialization feature -- Query - path_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE + path_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE do end - query_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE + query_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE do Result := request.query_parameter (a_name) end diff --git a/library/server/request/router/src/uri_template/request_uri_template_handler_context.e b/library/server/request/router/src/uri_template/request_uri_template_handler_context.e index 2dc046c1..2c1eafb2 100644 --- a/library/server/request/router/src/uri_template/request_uri_template_handler_context.e +++ b/library/server/request/router/src/uri_template/request_uri_template_handler_context.e @@ -31,14 +31,14 @@ feature -- Access feature -- Query - path_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE + path_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE do if attached uri_template_match.url_decoded_path_variable (a_name) as s then create {WSF_STRING_VALUE} Result.make (a_name, s) end end - query_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE + query_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE do if attached uri_template_match.url_decoded_query_variable (a_name) as s then create {WSF_STRING_VALUE} Result.make (a_name, s) diff --git a/library/server/request/router/src/uri_template/request_uri_template_router_i.e b/library/server/request/router/src/uri_template/request_uri_template_router_i.e index 4e10389a..18ab2b42 100644 --- a/library/server/request/router/src/uri_template/request_uri_template_router_i.e +++ b/library/server/request/router/src/uri_template/request_uri_template_router_i.e @@ -57,8 +57,8 @@ feature {NONE} -- Access: Implementation handler (req: WSF_REQUEST): detachable TUPLE [handler: attached like default_handler; context: like default_handler_context] local l_handlers: like handlers - t: STRING - p: STRING + t: READABLE_STRING_8 + p: READABLE_STRING_8 l_req_method: READABLE_STRING_GENERAL l_res: URI_TEMPLATE_MATCH_RESULT do diff --git a/library/server/wsf/src/request/value/wsf_string_value.e b/library/server/wsf/src/request/value/wsf_string_value.e index f72e794d..dfc7e4a6 100644 --- a/library/server/wsf/src/request/value/wsf_string_value.e +++ b/library/server/wsf/src/request/value/wsf_string_value.e @@ -18,10 +18,13 @@ convert feature {NONE} -- Initialization - make (a_name: READABLE_STRING_GENERAL; a_string: like string) + make (a_name: READABLE_STRING_8; a_string: READABLE_STRING_8) do - name := a_name.as_string_32 - string := a_string + name := url_decoded_string (a_name) + string := url_decoded_string (a_string) + + url_encoded_name := a_name + url_encoded_string := a_string end feature -- Access @@ -30,6 +33,10 @@ feature -- Access string: READABLE_STRING_32 + url_encoded_name: READABLE_STRING_32 + + url_encoded_string: READABLE_STRING_32 + feature -- Helper same_string (a_other: READABLE_STRING_GENERAL): BOOLEAN @@ -58,6 +65,19 @@ feature -- Conversion create Result.make_from_string (string) end +feature {NONE} -- Implementation + + url_decoded_string (s: READABLE_STRING_8): READABLE_STRING_32 + -- Decoded url-encoded string `s' + do + Result := url_encoder.decoded_string (s) + end + + url_encoder: URL_ENCODER + once + create Result + end + ;note copyright: "2011-2011, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" diff --git a/library/server/wsf/src/wsf_request.e b/library/server/wsf/src/wsf_request.e index 918f5ec8..de9305a3 100644 --- a/library/server/wsf/src/wsf_request.e +++ b/library/server/wsf/src/wsf_request.e @@ -8,6 +8,9 @@ note class WSF_REQUEST +inherit + DEBUG_OUTPUT + create {WSF_APPLICATION} make_from_wgi @@ -41,7 +44,25 @@ feature {NONE} -- Initialization initialize -- Specific initialization + local + s8: detachable READABLE_STRING_8 do + --| Content-Length + if attached content_length as s and then s.is_natural_64 then + content_length_value := s.to_natural_64 + else + content_length_value := 0 + end + + --| PATH_INFO + path_info := url_encoder.decoded_string (wgi_request.path_info) + + --| PATH_TRANSLATED + s8 := wgi_request.path_translated + if s8 /= Void then + path_translated := url_encoder.decoded_string (s8) + end + --| Here one can set its own environment entries if needed if meta_variable ({CGI_META_NAMES}.request_time) = Void then set_meta_string_variable ({CGI_META_NAMES}.request_time, date_time_utilities.unix_time_stamp (Void).out) @@ -50,6 +71,13 @@ feature {NONE} -- Initialization wgi_request: WGI_REQUEST +feature -- Status report + + debug_output: STRING_8 + do + create Result.make_from_string (request_method + " " + request_uri) + end + feature -- Status raw_post_data_recorded: BOOLEAN assign set_raw_post_data_recorded @@ -79,7 +107,7 @@ feature -- Access: Input feature {NONE} -- Access: global variable - items_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_GENERAL] + items_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_8] -- Table containing all the various variables -- Warning: this is computed each time, if you change the content of other containers -- this won't update this Result's content, unless you query it again @@ -109,7 +137,6 @@ feature {NONE} -- Access: global variable loop Result.force (vars.item, vars.item.name) end - end feature -- Access: global variable @@ -136,9 +163,6 @@ feature -- Access: global variable end end end --- if s /= Void then --- Result := s.as_string_32 --- end end string_item (a_name: READABLE_STRING_8): detachable READABLE_STRING_32 @@ -251,10 +275,6 @@ feature -- Access: CGI meta parameters - 1.1 content_length_value: NATURAL_64 -- Integer value related to `content_length" - do --- Result := wgi_request.content_length_value - check not_yet_implemented: False then end - end content_type: detachable READABLE_STRING_8 -- If the wgi_request includes a message-body, CONTENT_TYPE is set to @@ -334,7 +354,7 @@ feature -- Access: CGI meta parameters - 1.1 Result := wgi_request.gateway_interface end - path_info: READABLE_STRING_8 + path_info: READABLE_STRING_32 -- The PATH_INFO metavariable specifies a path to be interpreted -- by the CGI script. It identifies the resource or sub-resource -- to be returned by the CGI script, and it is derived from the @@ -362,11 +382,8 @@ feature -- Access: CGI meta parameters - 1.1 -- The PATH_INFO value is case-sensitive, and the server MUST -- preserve the case of the PATH_INFO element of the URI when -- making it available to scripts. - do - Result := wgi_request.path_info - end - path_translated: detachable READABLE_STRING_8 + path_translated: detachable READABLE_STRING_32 -- PATH_TRANSLATED is derived by taking any path-info component -- of the wgi_request URI (see section 6.1.6), decoding it (see -- section 3.1), parsing it as a URI in its own right, and @@ -409,9 +426,6 @@ feature -- Access: CGI meta parameters - 1.1 -- -- Servers SHOULD provide this metavariable to scripts if and -- only if the wgi_request URI includes a path-info component. - do - Result := wgi_request.path_translated - end query_string: READABLE_STRING_8 -- A URL-encoded string; the part of the Script-URI. (See @@ -707,7 +721,7 @@ feature -- Cookies Result := cookies_table end - cookie (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE + cookie (a_name: READABLE_STRING_8): detachable WSF_VALUE -- Field for name `a_name'. do Result := cookies_table.item (a_name) @@ -715,7 +729,7 @@ feature -- Cookies feature {NONE} -- Cookies - cookies_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_GENERAL] + cookies_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_32] -- Expanded cookies variable local i,j,p,n: INTEGER @@ -749,7 +763,7 @@ feature {NONE} -- Cookies v := s.substring (i + 1, j - 1) p := j + 1 end - l_cookies.force (new_string_value (k, v), k) + add_value_to_table (k, v, l_cookies) end end else @@ -768,7 +782,7 @@ feature -- Query parameters Result := query_parameters_table end - query_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE + query_parameter (a_name: READABLE_STRING_32): detachable WSF_VALUE -- Parameter for name `n'. do Result := query_parameters_table.item (a_name) @@ -776,7 +790,7 @@ feature -- Query parameters feature {NONE} -- Query parameters: implementation - query_parameters_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_GENERAL] + query_parameters_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_32] -- Variables extracted from QUERY_STRING local vars: like internal_query_parameters_table @@ -800,20 +814,19 @@ feature {NONE} -- Query parameters: implementation s := rq_uri.substring (p+1, e) end end - vars := urlencoded_parameters (s, True) + vars := urlencoded_parameters (s) vars.compare_objects internal_query_parameters_table := vars end Result := vars end - urlencoded_parameters (a_content: detachable READABLE_STRING_8; decoding: BOOLEAN): HASH_TABLE [WSF_VALUE, STRING] + urlencoded_parameters (a_content: detachable READABLE_STRING_8): HASH_TABLE [WSF_VALUE, READABLE_STRING_32] -- Import `a_content' local n, p, i, j: INTEGER - s: STRING - l_name,l_value: STRING_32 - v: WSF_VALUE + s: READABLE_STRING_8 + l_name, l_value: READABLE_STRING_8 do if a_content = Void then create Result.make (0) @@ -841,21 +854,7 @@ feature {NONE} -- Query parameters: implementation if j > 0 then l_name := s.substring (1, j - 1) l_value := s.substring (j + 1, s.count) - if decoding then - l_name := url_encoder.decoded_string (l_name) - l_value := url_encoder.decoded_string (l_value) - end - v := new_string_value (l_name, l_value) - if Result.has_key (l_name) and then attached Result.found_item as l_existing_value then - if attached {WSF_MULTIPLE_STRING_VALUE} l_existing_value as l_multi then - l_multi.add_value (v) - else - Result.force (create {WSF_MULTIPLE_STRING_VALUE}.make_with_array (<>), l_name) - check replaced: Result.found and then Result.found_item ~ l_existing_value end - end - else - Result.force (v, l_name) - end + add_value_to_table (l_name, l_value, Result) end end end @@ -863,6 +862,23 @@ feature {NONE} -- Query parameters: implementation end end + add_value_to_table (a_name: READABLE_STRING_32; a_value: READABLE_STRING_32; a_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_32]) + local + v: WSF_VALUE + do + v := new_string_value (a_name, a_value) + if a_table.has_key (v.name) and then attached a_table.found_item as l_existing_value then + if attached {WSF_MULTIPLE_STRING_VALUE} l_existing_value as l_multi then + l_multi.add_value (v) + else + a_table.force (create {WSF_MULTIPLE_STRING_VALUE}.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 + feature -- Form fields and related form_data_parameters: ITERABLE [WSF_VALUE] @@ -870,7 +886,7 @@ feature -- Form fields and related Result := form_data_parameters_table end - form_data_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE + form_data_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE -- Field for name `a_name'. do Result := form_data_parameters_table.item (a_name) @@ -887,7 +903,7 @@ feature -- Form fields and related feature {NONE} -- Form fields and related - form_data_parameters_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_GENERAL] + form_data_parameters_table: HASH_TABLE [WSF_VALUE, READABLE_STRING_32] -- Variables sent by POST request local vars: like internal_form_data_parameters_table @@ -911,7 +927,7 @@ feature {NONE} -- Form fields and related analyze_multipart_form (l_type, s, vars) else s := form_input_data (n.to_integer_32) --| FIXME truncated from NAT64 to INT32 - vars := urlencoded_parameters (s, True) + vars := urlencoded_parameters (s) end if raw_post_data_recorded then set_meta_string_variable ("RAW_POST_DATA", s) @@ -1309,7 +1325,7 @@ feature {NONE} -- Implementation: Form analyzer save_uploaded_file (l_content, l_up_file_info) uploaded_files.force (l_up_file_info, l_name) else - vars_post.force (new_string_value (l_name, l_content), l_name) + add_value_to_table (l_name, l_content, vars_post) end else error_handler.add_custom_error (0, "unamed multipart entry", Void) @@ -1407,9 +1423,6 @@ feature {NONE} -- Implementation report_bad_request_error ("Missing host header") end end --- if not has_error then --- update_path_info --- end end feature {NONE} -- Implementation: utilities @@ -1460,7 +1473,7 @@ feature {NONE} -- Implementation: utilities one_starting_slash: Result[1] = '/' and (Result.count = 1 or else Result[2] /= '/') end - new_string_value (a_name: READABLE_STRING_GENERAL; a_value: READABLE_STRING_32): WSF_STRING_VALUE + new_string_value (a_name: READABLE_STRING_8; a_value: READABLE_STRING_8): WSF_STRING_VALUE do create Result.make (a_name, a_value) end