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