diff --git a/library/server/ewsgi/connectors/standalone/src/httpd/configuration/httpd_configuration_i.e b/library/server/ewsgi/connectors/standalone/src/httpd/configuration/httpd_configuration_i.e index 5a5e98ab..b251e97d 100644 --- a/library/server/ewsgi/connectors/standalone/src/httpd/configuration/httpd_configuration_i.e +++ b/library/server/ewsgi/connectors/standalone/src/httpd/configuration/httpd_configuration_i.e @@ -92,10 +92,10 @@ feature -- Access: SSL is_secure: BOOLEAN -- Is SSL/TLS session?. - ca_crt: STRING + ca_crt: IMMUTABLE_STRING_8 -- the signed certificate. - ca_key: STRING + ca_key: IMMUTABLE_STRING_8 -- private key to the certificate. ssl_protocol: NATURAL @@ -218,20 +218,16 @@ feature -- Element change feature -- Element change - set_ca_crt (a_value: STRING) - -- Set `ca_crt' with `a_value' + set_ca_crt (a_value: separate READABLE_STRING_8) + -- Set `ca_crt' from `a_value'. do - ca_crt := a_value - ensure - ca_crt_set: ca_crt = a_value + create ca_crt.make_from_separate (a_value) end set_ca_key (a_value: STRING) - -- Set `ca_key' with `a_value' + -- Set `ca_key' with `a_value'. do - ca_key := a_value - ensure - ca_key_set: ca_key = a_value + create ca_key.make_from_separate (a_value) end set_ssl_protocol (a_version: NATURAL) diff --git a/library/server/ewsgi/connectors/standalone/src/httpd/network/httpd_stream_socket.e b/library/server/ewsgi/connectors/standalone/src/httpd/network/httpd_stream_socket.e index 4f4f1154..f3f3209d 100644 --- a/library/server/ewsgi/connectors/standalone/src/httpd/network/httpd_stream_socket.e +++ b/library/server/ewsgi/connectors/standalone/src/httpd/network/httpd_stream_socket.e @@ -12,6 +12,8 @@ class create make_server_by_address_and_port, make_server_by_port, + make_client_by_address_and_port, + make_client_by_port, make_from_separate, make_empty @@ -30,6 +32,16 @@ feature {NONE} -- Initialization create {TCP_STREAM_SOCKET} socket.make_server_by_port (a_port) end + make_client_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER) + do + create {TCP_STREAM_SOCKET} socket.make_client_by_address_and_port (an_address, a_port) + end + + make_client_by_port (a_peer_port: INTEGER; a_peer_host: STRING) + do + create {TCP_STREAM_SOCKET} socket.make_client_by_port (a_peer_port, a_peer_host) + end + make_from_separate (s: separate HTTPD_STREAM_SOCKET) require descriptor_available: s.descriptor_available @@ -164,6 +176,11 @@ feature -- Status Report end end + exists: BOOLEAN + do + Result := socket.exists + end + is_blocking: BOOLEAN do Result := socket.is_blocking @@ -176,6 +193,13 @@ feature -- Status Report end end + is_connected: BOOLEAN + do + if attached {TCP_STREAM_SOCKET} socket as l_socket then + Result := l_socket.is_connected + end + end + is_created: BOOLEAN do if attached {NETWORK_SOCKET} socket as l_socket then @@ -220,6 +244,16 @@ feature -- Status Report end end + connect + do + socket.connect + end + + close + do + socket.close + end + listen (a_queue: INTEGER) do socket.listen (a_queue) diff --git a/library/server/ewsgi/connectors/standalone/src/httpd/network/tcp_stream_socket.e b/library/server/ewsgi/connectors/standalone/src/httpd/network/tcp_stream_socket.e index 2e88f192..774b3bb5 100644 --- a/library/server/ewsgi/connectors/standalone/src/httpd/network/tcp_stream_socket.e +++ b/library/server/ewsgi/connectors/standalone/src/httpd/network/tcp_stream_socket.e @@ -15,6 +15,8 @@ inherit create make_server_by_address_and_port, make_server_by_port, + make_client_by_address_and_port, + make_client_by_port, make_from_separate, make_empty diff --git a/library/server/ewsgi/connectors/standalone/src/httpd/package.iron b/library/server/ewsgi/connectors/standalone/src/httpd/package.iron new file mode 100644 index 00000000..bb34ce9f --- /dev/null +++ b/library/server/ewsgi/connectors/standalone/src/httpd/package.iron @@ -0,0 +1,20 @@ +package httpd + +project + httpd = "httpd-safe.ecf" + httpd = "httpd.ecf" + +note + title: HTTP server + description: "[ + Simple HTTP listener and handler, that can be extended easily. + ]" + tags: http,httpd,server,web + collection: EWF + copyright: 2011-2016, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others + license: Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt) + link[license]: http://www.eiffel.com/licensing/forum.txt + link[source]: "Github" https://github.com/EiffelWebFramework/EWF/library/server/httpd + link[doc]: "Documentation" http://eiffelwebframework.github.io/EWF/ + +end diff --git a/library/server/ewsgi/connectors/standalone/src/httpd/ssl/httpd_stream_ssl_socket.e b/library/server/ewsgi/connectors/standalone/src/httpd/ssl/httpd_stream_ssl_socket.e index e1f25ca0..8b0be0da 100644 --- a/library/server/ewsgi/connectors/standalone/src/httpd/ssl/httpd_stream_ssl_socket.e +++ b/library/server/ewsgi/connectors/standalone/src/httpd/ssl/httpd_stream_ssl_socket.e @@ -22,7 +22,9 @@ inherit create make_ssl_server_by_address_and_port, make_ssl_server_by_port, - make_server_by_address_and_port, make_server_by_port + make_server_by_address_and_port, make_server_by_port, + make_ssl_client_by_address_and_port, make_ssl_client_by_port, + make_client_by_address_and_port, make_client_by_port create {HTTPD_STREAM_SOCKET} make @@ -49,6 +51,26 @@ feature {NONE} -- Initialization set_certificates (a_crt, a_key) end + make_ssl_client_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER; a_ssl_protocol: NATURAL; a_crt: STRING; a_key: STRING) + local + l_socket: SSL_TCP_STREAM_SOCKET + do + create l_socket.make_client_by_address_and_port (an_address, a_port) + l_socket.set_tls_protocol (a_ssl_protocol) + socket := l_socket + set_certificates (a_crt, a_key) + end + + make_ssl_client_by_port (a_peer_port: INTEGER; a_peer_host: STRING; a_ssl_protocol: NATURAL; a_crt: STRING; a_key: STRING) + local + l_socket: SSL_TCP_STREAM_SOCKET + do + create l_socket.make_client_by_port (a_peer_port, a_peer_host) + l_socket.set_tls_protocol (a_ssl_protocol) + socket := l_socket + set_certificates (a_crt, a_key) + end + feature -- Output put_readable_string_8 (s: READABLE_STRING_8) diff --git a/library/server/ewsgi/connectors/standalone/src/httpd/ssl/ssl_tcp_stream_socket.e b/library/server/ewsgi/connectors/standalone/src/httpd/ssl/ssl_tcp_stream_socket.e index f1043ad7..de71f479 100644 --- a/library/server/ewsgi/connectors/standalone/src/httpd/ssl/ssl_tcp_stream_socket.e +++ b/library/server/ewsgi/connectors/standalone/src/httpd/ssl/ssl_tcp_stream_socket.e @@ -12,6 +12,7 @@ inherit create make_server_by_address_and_port, make_server_by_port, + make_client_by_address_and_port, make_client_by_port, make_empty create {SSL_NETWORK_STREAM_SOCKET} diff --git a/library/server/wsf/package.iron b/library/server/wsf/package.iron index 99d760f5..f766b25f 100644 --- a/library/server/wsf/package.iron +++ b/library/server/wsf/package.iron @@ -1,13 +1,3 @@ -note - title: Web Server Foundation - description: Core of the Eiffel Web Framework, used to build web server application. - tags: ewf,server,httpd,request,connector - license: Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt) - link[license]: https://github.com/EiffelWebFramework/EWF/blob/master/LICENSE - link[source]: "Github" https://github.com/EiffelWebFramework/EWF - link[doc]: "Documentation" http://eiffelwebframework.github.io/EWF/ - -end package wsf @@ -37,6 +27,7 @@ project default_standalone = "default/standalone-safe.ecf" default_standalone = "default/standalone.ecf" + note title: Web Server Foundation description: "[ diff --git a/tests/all-safe.ecf b/tests/all-safe.ecf index 05168254..22204869 100644 --- a/tests/all-safe.ecf +++ b/tests/all-safe.ecf @@ -17,6 +17,7 @@ + @@ -30,6 +31,7 @@ + diff --git a/tests/dev/hello-safe.ecf b/tests/dev/hello-safe.ecf index 94095ccb..e61bc494 100644 --- a/tests/dev/hello-safe.ecf +++ b/tests/dev/hello-safe.ecf @@ -1,14 +1,15 @@ - + /EIFGENs$ /\.git$ /\.svn$ @@ -16,20 +17,20 @@ - + - + - + - + diff --git a/tests/dev/src/hello_routed_world.e b/tests/dev/src/hello_routed_world.e index fa588fe1..f0d3a62f 100644 --- a/tests/dev/src/hello_routed_world.e +++ b/tests/dev/src/hello_routed_world.e @@ -8,243 +8,24 @@ class HELLO_ROUTED_WORLD inherit - WSF_URI_TEMPLATE_ROUTED_SERVICE - - WSF_HANDLER_HELPER - - WSF_DEFAULT_SERVICE + WSF_DEFAULT_SERVICE [HELLO_ROUTED_WORLD_EXECUTION] + redefine + initialize + end create - make + make_and_launch feature {NONE} -- Initialization - make + initialize do - initialize_router + Precursor set_service_option ("port", 8099) - make_and_launch end - create_router - do - create router.make (5) - end - - setup_router - local - ra: WSF_AGENT_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT] - hello: WSF_URI_TEMPLATE_ROUTING_HANDLER - www: WSF_FILE_SYSTEM_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT] - do - router.map_agent ("/refresh", agent execute_refresh) - router.map_agent ("/home", agent execute_home) - create www.make (document_root) - www.set_directory_index (<<"index.html">>) - - router.map ("/www{/path}{?query}", www) - - --| Map all "/hello*" using a ROUTING_HANDLER - create hello.make (3) - router.map ("/hello", hello) - - create ra.make (agent handle_hello) - hello.map ("/hello/{name}.{format}", ra) - hello.map ("/hello.{format}/{name}", ra) - hello.map ("/hello/{name}", ra) - - create ra.make (agent handle_anonymous_hello) - hello.map ("/hello", ra) - hello.map ("/hello.{format}", ra) - - --| Various various route, directly on the "router" - router.map_agent_with_request_methods ("/method/any", agent handle_method_any, Void) - router.map_agent_with_request_methods ("/method/guess", agent handle_method_get_or_post, <<"GET", "POST">>) - router.map_agent_with_request_methods ("/method/custom", agent handle_method_get, <<"GET">>) - router.map_agent_with_request_methods ("/method/custom", agent handle_method_post, <<"POST">>) - end - - - document_root: READABLE_STRING_8 - local - e: EXECUTION_ENVIRONMENT - dn: DIRECTORY_NAME - once - create e - create dn.make_from_string (e.current_working_directory) - dn.extend ("htdocs") - Result := dn.string - if Result[Result.count] = Operating_environment.directory_separator then - Result := Result.substring (1, Result.count - 1) - end - end - -feature -- Execution - - - execute_default (req: WSF_REQUEST; res: WSF_RESPONSE) - local - l_url: STRING - do - l_url := req.absolute_script_url ("/home") - res.redirect_now_with_content (l_url, "You are now being redirected to " + l_url, {HTTP_MIME_TYPES}.text_html) - end - - execute_refresh (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) - local - h: HTTP_HEADER - l_url: STRING - e: EXECUTION_ENVIRONMENT - n: INTEGER - i: INTEGER - s: STRING_8 - do - l_url := req.absolute_script_url ("/home") - - - - n := 3 - create h.make - h.put_refresh (l_url, 5) - h.put_location (l_url) - h.put_content_type_text_plain - h.put_transfer_encoding_chunked --- h.put_content_length (0) --- res.set_status_code ({HTTP_STATUS_CODE}.moved_permanently) - res.set_status_code ({HTTP_STATUS_CODE}.ok) - res.put_header_text (h.string) - - from - create e - create s.make (255) - until - n = 0 - loop - if n > 1 then - s.append ("%NRedirected to " + l_url + " in " + n.out + " seconds :%N") - else - s.append ("%NRedirected to " + l_url + " in 1 second :%N") - end - res.put_chunk (s, Void); s.wipe_out - from - i := 1 - until - i = 1001 - loop - s.append_character ('.') - if i \\ 100 = 0 then - s.append_character ('%N') - end - res.put_chunk (s, Void); s.wipe_out - e.sleep (1_000_000) - i := i + 1 - end - n := n - 1 - end - s.append ("%NYou are now being redirected...%N") - res.put_chunk (s, Void); s.wipe_out - res.put_chunk_end - end - - execute_home (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) - local - l_body: STRING_8 - do - create l_body.make (255) - l_body.append ("Hello World ?!%N") - l_body.append ("

Please try the following links

%N") - if attached req.item ("REQUEST_COUNT") as rqc then - l_body.append ("request #"+ rqc.as_string.string + "%N") - end - l_body.append ("%N") - - res.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", l_body.count.out]>>) - res.put_string (l_body) - end - - execute_hello (req: WSF_REQUEST; res: WSF_RESPONSE; a_name: detachable READABLE_STRING_32; ctx: WSF_HANDLER_CONTEXT) - local - l_response_content_type: detachable STRING - h: HTTP_HEADER - content_type_supported: ARRAY [STRING] - l_body: STRING_8 - do - if a_name /= Void then - l_body := "Hello %"" + a_name + "%" !%N" - else - l_body := "Hello anonymous visitor !%N" - end - content_type_supported := <<{HTTP_MIME_TYPES}.application_json, {HTTP_MIME_TYPES}.text_html, {HTTP_MIME_TYPES}.text_xml, {HTTP_MIME_TYPES}.text_plain>> - inspect ctx.request_format_id ("format", content_type_supported) - when {HTTP_FORMAT_CONSTANTS}.json then - l_response_content_type := {HTTP_MIME_TYPES}.application_json - l_body := "{%N%"application%": %"/hello%",%N %"message%": %"" + l_body + "%" %N}" - when {HTTP_FORMAT_CONSTANTS}.html then - l_response_content_type := {HTTP_MIME_TYPES}.text_html - when {HTTP_FORMAT_CONSTANTS}.xml then - l_response_content_type := {HTTP_MIME_TYPES}.text_xml - l_body := "/hello" + l_body + "%N" - when {HTTP_FORMAT_CONSTANTS}.text then - l_response_content_type := {HTTP_MIME_TYPES}.text_plain - else - execute_content_type_not_allowed (req, res, content_type_supported, - <<{HTTP_FORMAT_CONSTANTS}.json_name, {HTTP_FORMAT_CONSTANTS}.html_name, {HTTP_FORMAT_CONSTANTS}.xml_name, {HTTP_FORMAT_CONSTANTS}.text_name>> - ) - end - if l_response_content_type /= Void then - create h.make - h.put_content_type (l_response_content_type) - h.put_content_length (l_body.count) - res.set_status_code ({HTTP_STATUS_CODE}.ok) - res.put_header_text (h.string) - res.put_string (l_body) - end - end - - handle_hello (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) - do - execute_hello (req, res, ctx.string_parameter ("name"), ctx) - end - - handle_anonymous_hello (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) - do - execute_hello (req, res, ctx.string_parameter ("name"), ctx) - end - - handle_method_any (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) - do - execute_hello (req, res, req.request_method, ctx) - end - - handle_method_get (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) - do - execute_hello (req, res, "GET", ctx) - end - - - handle_method_post (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) - do - execute_hello (req, res, "POST", ctx) - end - - handle_method_get_or_post (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) - do - execute_hello (req, res, "GET or POST", ctx) - end - - - note - copyright: "2011-2011, Eiffel Software and others" + copyright: "2011-2016, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software diff --git a/tests/dev/src/hello_routed_world_execution.e b/tests/dev/src/hello_routed_world_execution.e new file mode 100644 index 00000000..6dd3e6d9 --- /dev/null +++ b/tests/dev/src/hello_routed_world_execution.e @@ -0,0 +1,272 @@ +note + description : "Objects that ..." + author : "$Author$" + date : "$Date$" + revision : "$Revision$" + +class + HELLO_ROUTED_WORLD_EXECUTION + +inherit + WSF_ROUTED_EXECUTION + redefine + execute_default + end + + WSF_URI_TEMPLATE_HELPER_FOR_ROUTED_EXECUTION + +create + make + +feature {NONE} -- Initialization + + setup_router + local + ra: WSF_URI_TEMPLATE_AGENT_HANDLER + hello: WSF_URI_TEMPLATE_ROUTING_HANDLER + www: WSF_FILE_SYSTEM_HANDLER + do + map_uri_template_agent ("/refresh", agent execute_refresh, Void) + map_uri_template_agent ("/home", agent execute_home, Void) + create www.make (document_root) + www.set_directory_index (<<"index.html">>) + router.handle ("/www{/path}{?query}", www, Void) + + --| Map all "/hello*" using a ROUTING_HANDLER + create hello.make (3) + router.handle ("/hello", hello, Void) + + create ra.make (agent handle_hello) + hello.router.handle ("/hello/{name}.{format}", ra, Void) + hello.router.handle ("/hello.{format}/{name}", ra, Void) + hello.router.handle ("/hello/{name}", ra, Void) + + create ra.make (agent handle_anonymous_hello) + hello.router.handle ("/hello", ra, Void) + hello.router.handle ("/hello.{format}", ra, Void) + + --| Various various route, directly on the "router" + map_uri_template_agent ("/method/any", agent handle_method_any, Void) + map_uri_template_agent ("/method/guess", agent handle_method_get_or_post, <<"GET", "POST">>) + map_uri_template_agent ("/method/custom", agent handle_method_get, <<"GET">>) + map_uri_template_agent ("/method/custom", agent handle_method_post, <<"POST">>) + end + + + document_root: READABLE_STRING_8 + local + e: EXECUTION_ENVIRONMENT + dn: DIRECTORY_NAME + once + create e + create dn.make_from_string (e.current_working_directory) + dn.extend ("htdocs") + Result := dn.string + if Result[Result.count] = Operating_environment.directory_separator then + Result := Result.substring (1, Result.count - 1) + end + end + +feature -- Execution + + + execute_default (req: WSF_REQUEST; res: WSF_RESPONSE) + local + l_url: STRING + do + l_url := req.absolute_script_url ("/home") + res.redirect_now_with_content (l_url, "You are now being redirected to " + l_url, {HTTP_MIME_TYPES}.text_html) + end + + execute_refresh (req: WSF_REQUEST; res: WSF_RESPONSE) --ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; + local + h: HTTP_HEADER + l_url: STRING + e: EXECUTION_ENVIRONMENT + n: INTEGER + i: INTEGER + s: STRING_8 + do + l_url := req.absolute_script_url ("/home") + + + + n := 3 + create h.make + h.put_refresh (l_url, 5) + h.put_location (l_url) + h.put_content_type_text_plain + h.put_transfer_encoding_chunked +-- h.put_content_length (0) +-- res.set_status_code ({HTTP_STATUS_CODE}.moved_permanently) + res.set_status_code ({HTTP_STATUS_CODE}.ok) + res.put_header_text (h.string) + + from + create e + create s.make (255) + until + n = 0 + loop + if n > 1 then + s.append ("%NRedirected to " + l_url + " in " + n.out + " seconds :%N") + else + s.append ("%NRedirected to " + l_url + " in 1 second :%N") + end + res.put_chunk (s, Void); s.wipe_out + from + i := 1 + until + i = 1001 + loop + s.append_character ('.') + if i \\ 100 = 0 then + s.append_character ('%N') + end + res.put_chunk (s, Void); s.wipe_out + e.sleep (1_000_000) + i := i + 1 + end + n := n - 1 + end + s.append ("%NYou are now being redirected...%N") + res.put_chunk (s, Void); s.wipe_out + res.put_chunk_end + end + + execute_home (req: WSF_REQUEST; res: WSF_RESPONSE) -- ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; + local + l_body: STRING_8 + do + create l_body.make (255) + l_body.append ("Hello World ?!%N") + l_body.append ("

Please try the following links

%N") + if attached req.item ("REQUEST_COUNT") as rqc then + l_body.append ("request #"+ rqc.as_string.url_encoded_value + "%N") + end + l_body.append ("%N") + + res.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", l_body.count.out]>>) + res.put_string (l_body) + end + + execute_hello (req: WSF_REQUEST; res: WSF_RESPONSE; a_name: detachable READABLE_STRING_32) + local + l_response_content_type: detachable STRING + h: HTTP_HEADER + content_type_supported: ARRAY [STRING] + l_body: STRING_8 + l_format: detachable READABLE_STRING_GENERAL + l_http_format_constants: HTTP_FORMAT_CONSTANTS + do + if a_name /= Void then + l_body := "Hello %"" + a_name + "%" !%N" + else + l_body := "Hello anonymous visitor !%N" + end + content_type_supported := <<{HTTP_MIME_TYPES}.application_json, {HTTP_MIME_TYPES}.text_html, {HTTP_MIME_TYPES}.text_xml, {HTTP_MIME_TYPES}.text_plain>> + if attached {WSF_STRING} req.path_parameter ("format") as s_format then + l_format := s_format.value + end + if l_format = Void then + across + content_type_supported as ic + until + l_format /= Void + loop + if req.is_content_type_accepted (ic.item) then + l_format := ic.item + end + end + end + if l_format /= Void then + create l_http_format_constants + inspect + l_http_format_constants.format_id (l_format) + when {HTTP_FORMAT_CONSTANTS}.json then + l_response_content_type := {HTTP_MIME_TYPES}.application_json + l_body := "{%N%"application%": %"/hello%",%N %"message%": %"" + l_body + "%" %N}" + when {HTTP_FORMAT_CONSTANTS}.html then + l_response_content_type := {HTTP_MIME_TYPES}.text_html + when {HTTP_FORMAT_CONSTANTS}.xml then + l_response_content_type := {HTTP_MIME_TYPES}.text_xml + l_body := "/hello" + l_body + "%N" + when {HTTP_FORMAT_CONSTANTS}.text then + l_response_content_type := {HTTP_MIME_TYPES}.text_plain + else + l_response_content_type := Void + end + end + + if l_response_content_type /= Void then + create h.make + h.put_content_type (l_response_content_type) + h.put_content_length (l_body.count) + res.set_status_code ({HTTP_STATUS_CODE}.ok) + res.put_header_text (h.string) + res.put_string (l_body) + else + res.send (create {WSF_PRECONDITION_FAILED_MESSAGE}.make (req)) -- FIXME: better error message! + end + end + + string_path_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable STRING_32 + do + if attached {WSF_STRING} req.path_parameter (a_name) as s then + Result := s.value + end + end + + handle_hello (req: WSF_REQUEST; res: WSF_RESPONSE) + do + execute_hello (req, res, string_path_parameter (req, "name")) + end + + handle_anonymous_hello (req: WSF_REQUEST; res: WSF_RESPONSE) + do + execute_hello (req, res, string_path_parameter (req, "name")) + end + + handle_method_any (req: WSF_REQUEST; res: WSF_RESPONSE) + do + execute_hello (req, res, req.request_method) + end + + handle_method_get (req: WSF_REQUEST; res: WSF_RESPONSE) + do + execute_hello (req, res, "GET") + end + + + handle_method_post (req: WSF_REQUEST; res: WSF_RESPONSE) + do + execute_hello (req, res, "POST") + end + + handle_method_get_or_post (req: WSF_REQUEST; res: WSF_RESPONSE) + do + execute_hello (req, res, "GET or POST") + end + + + +note + copyright: "2011-2016, 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