Added first draft for RESTful library
note: the interfaces are likely to change in the future
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
note
|
||||
description: "Summary description for {APP_ACCOUNT_VERIFY_CREDENTIAL}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
APP_ACCOUNT_VERIFY_CREDENTIAL
|
||||
|
||||
inherit
|
||||
APP_REQUEST_HANDLER
|
||||
redefine
|
||||
initialize,
|
||||
execute_unauthorized
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
description := "Verify credentials"
|
||||
initialize
|
||||
end
|
||||
|
||||
initialize
|
||||
do
|
||||
Precursor
|
||||
enable_request_method_get
|
||||
enable_format_json
|
||||
enable_format_xml
|
||||
enable_format_text
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
authentication_required: BOOLEAN = True
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute_unauthorized (a_hdl_context: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||
local
|
||||
s: STRING
|
||||
lst: LIST [STRING]
|
||||
do
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
|
||||
res.write_header ({HTTP_STATUS_CODE}.unauthorized, <<["WWW-Authenticate", "Basic realm=%"My Silly demo auth, password must be the same as login such as foo:foo%""]>>)
|
||||
res.write_string ("Unauthorized")
|
||||
end
|
||||
|
||||
execute_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||
local
|
||||
l_full: BOOLEAN
|
||||
h: EWF_HEADER
|
||||
l_login: STRING_8
|
||||
s: STRING
|
||||
content_type_supported: ARRAY [STRING]
|
||||
l_format_id: INTEGER
|
||||
do
|
||||
content_type_supported := <<{HTTP_CONSTANTS}.json_app, {HTTP_CONSTANTS}.xml_text, {HTTP_CONSTANTS}.plain_text>>
|
||||
l_format_id := ctx.request_format_id ("format", content_type_supported)
|
||||
if ctx.authenticated then
|
||||
l_full := attached ctx.query_parameter ("details") as v and then v.is_case_insensitive_equal ("true")
|
||||
if attached ctx.authenticated_identifier as log then
|
||||
l_login := log.as_string_8
|
||||
|
||||
create h.make
|
||||
|
||||
create s.make_empty
|
||||
inspect l_format_id
|
||||
when {HTTP_FORMAT_CONSTANTS}.json then
|
||||
h.put_content_type_text_plain
|
||||
s.append_string ("{ %"login%": %"" + l_login + "%" }%N")
|
||||
when {HTTP_FORMAT_CONSTANTS}.xml then
|
||||
h.put_content_type_text_xml
|
||||
s.append_string ("<login>" + l_login + "</login>%N")
|
||||
when {HTTP_FORMAT_CONSTANTS}.text then -- Default
|
||||
h.put_content_type_text_plain
|
||||
s.append_string ("login: " + l_login + "%N")
|
||||
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 not s.is_empty then
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.ok)
|
||||
res.write_headers_string (h.string)
|
||||
res.write_string (s)
|
||||
end
|
||||
else
|
||||
send_error (ctx.path, 0, "User/password unknown", Void, ctx, req, res)
|
||||
end
|
||||
else
|
||||
send_error (ctx.path, 0, "Authentication rejected", Void, ctx, req, res)
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-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
|
||||
95
library/server/request/rest/tests/src/app/app_test.e
Normal file
95
library/server/request/rest/tests/src/app/app_test.e
Normal file
@@ -0,0 +1,95 @@
|
||||
note
|
||||
description: "Summary description for {APP_TEST}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
APP_TEST
|
||||
|
||||
inherit
|
||||
APP_REQUEST_HANDLER
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
description := "Return a simple test output "
|
||||
initialize
|
||||
end
|
||||
|
||||
initialize
|
||||
do
|
||||
Precursor
|
||||
enable_request_method_get
|
||||
enable_format_text
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
authentication_required: BOOLEAN = False
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||
-- Execute request handler
|
||||
local
|
||||
s: STRING
|
||||
h: EWF_HEADER
|
||||
do
|
||||
create h.make
|
||||
h.put_content_type_text_plain
|
||||
|
||||
create s.make_empty
|
||||
s.append_string ("test")
|
||||
if attached req.meta_variable ("REQUEST_COUNT") as l_request_count then
|
||||
s.append_string ("(request_count="+ l_request_count +")%N")
|
||||
end
|
||||
|
||||
-- ctx.request_format_id ("format", Void)
|
||||
|
||||
if attached ctx.request_format ("format", Void) as l_format then
|
||||
s.append_string (" format=" + l_format + "%N")
|
||||
end
|
||||
|
||||
if attached ctx.parameter ("op") as l_op then
|
||||
s.append_string (" op=" + l_op)
|
||||
if l_op.same_string ("crash") then
|
||||
(create {DEVELOPER_EXCEPTION}).raise
|
||||
elseif l_op.starts_with ("env") then
|
||||
s.append_string ("%N%NAll variables:")
|
||||
s.append (string_hash_table_string_string (req.parameters.new_cursor, False))
|
||||
s.append_string ("<br/>script_url(%"" + req.path_info + "%")=" + ctx.script_url (req.path_info) + "%N")
|
||||
-- if attached ctx.http_authorization_login_password as t then
|
||||
-- s.append_string ("Check login=" + t.login + "<br/>%N")
|
||||
-- end
|
||||
if ctx.authenticated and then attached ctx.authenticated_identifier as l_login then
|
||||
s.append_string ("Authenticated: login=" + l_login.as_string_8 + "<br/>%N")
|
||||
end
|
||||
end
|
||||
else
|
||||
s.append ("%N Try " + ctx.script_absolute_url (req.path_info + "?op=env") + " to display all variables%N")
|
||||
s.append ("%N Try " + ctx.script_absolute_url (req.path_info + "?op=crash") + " to demonstrate exception trace%N")
|
||||
end
|
||||
|
||||
res.set_status_code (200)
|
||||
res.write_headers_string (h.string)
|
||||
res.write_string (s)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-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
|
||||
148
library/server/request/rest/tests/src/app_server.e
Normal file
148
library/server/request/rest/tests/src/app_server.e
Normal file
@@ -0,0 +1,148 @@
|
||||
note
|
||||
description: "Summary description for {APP_SERVER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
APP_SERVER
|
||||
|
||||
inherit
|
||||
APP_APPLICATION
|
||||
redefine
|
||||
execute
|
||||
end
|
||||
|
||||
REST_APPLICATION_GATEWAY
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Initialize `Current'.
|
||||
do
|
||||
initialize_router
|
||||
build_gateway_and_launch
|
||||
end
|
||||
|
||||
feature {NONE} -- Handlers
|
||||
|
||||
create_router
|
||||
-- Create `router'
|
||||
do
|
||||
create router.make (5)
|
||||
end
|
||||
|
||||
setup_router
|
||||
local
|
||||
h: APP_REQUEST_HANDLER
|
||||
rah: APP_REQUEST_AGENT_HANDLER
|
||||
gh: APP_REQUEST_ROUTING_HANDLER
|
||||
do
|
||||
create {APP_ACCOUNT_VERIFY_CREDENTIAL} h.make
|
||||
router.map ("/account/verify_credentials", h)
|
||||
router.map ("/account/verify_credentials.{format}", h)
|
||||
|
||||
|
||||
create {APP_TEST} h.make
|
||||
|
||||
create gh.make (4)
|
||||
router.map ("/test", gh)
|
||||
gh.map_default (h)
|
||||
-- gh.map ("/test", h)
|
||||
gh.map ("/test/{op}", h)
|
||||
gh.map ("/test.{format}", h)
|
||||
gh.map ("/test.{format}/{op}", h)
|
||||
|
||||
|
||||
create rah.make (agent execute_exit_application)
|
||||
h := rah
|
||||
h.set_description ("tell the REST server to exit (in FCGI context, this is used to reload the FCGI server)")
|
||||
h.enable_request_method_get
|
||||
h.enable_format_text
|
||||
router.map ("/debug/exit", h)
|
||||
router.map ("/debug/exit.{format}", h)
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||
do
|
||||
request_count := request_count + 1
|
||||
Precursor (req, res)
|
||||
end
|
||||
|
||||
execute_default (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||
local
|
||||
rqst_uri: detachable STRING
|
||||
l_path_info: detachable STRING
|
||||
h: EWF_HEADER
|
||||
s: STRING
|
||||
l_redir_url: STRING
|
||||
do
|
||||
create h.make
|
||||
-- h.put_refresh (ctx.script_url ("/doc"), 2, {HTTP_STATUS_CODE}.temp_redirect)
|
||||
l_redir_url := "/doc"
|
||||
h.put_refresh (l_redir_url, 2, {HTTP_STATUS_CODE}.temp_redirect)
|
||||
h.put_content_type_text_html
|
||||
create s.make_empty
|
||||
s := "Request [" + req.path_info + "] is not available. <br/>%N";
|
||||
s.append ("You are being redirected to <a href=%"" + l_redir_url + "%">/doc</a> in 2 seconds ...%N")
|
||||
h.put_content_length (s.count)
|
||||
res.set_status_code (200)
|
||||
res.write_headers_string (h.string)
|
||||
res.write_string (s)
|
||||
end
|
||||
|
||||
-- execute_rescue (ctx: like new_request_context)
|
||||
-- -- Execute the default rescue behavior
|
||||
-- do
|
||||
-- execute_exception_trace (ctx)
|
||||
-- end
|
||||
|
||||
feature -- Implementation
|
||||
|
||||
-- execute_exception_trace (ctx: like new_request_context)
|
||||
-- local
|
||||
-- h: EWF_HEADER
|
||||
-- s: STRING
|
||||
-- do
|
||||
-- create h.make
|
||||
-- h.put_content_type_text_plain
|
||||
-- ctx.output.put_string (h.string)
|
||||
-- ctx.output.put_string ("Error occurred .. rq="+ request_count.out +"%N")
|
||||
|
||||
-- if attached (create {EXCEPTIONS}).exception_trace as l_trace then
|
||||
-- ctx.output.put_string ("<pre>" + l_trace + "</pre>")
|
||||
-- end
|
||||
-- h.recycle
|
||||
-- exit_with_code (-1)
|
||||
-- end
|
||||
|
||||
execute_exit_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||
local
|
||||
s: STRING
|
||||
do
|
||||
res.set_status_code (200)
|
||||
res.write_header (200, <<["Content-Type", "text/html"]>>)
|
||||
|
||||
create s.make_empty
|
||||
s.append_string ("Exited")
|
||||
s.append_string (" <a href=%"" + ctx.script_url ("/") + "%">start again</a>%N")
|
||||
res.write_string (s)
|
||||
exit_with_code (0)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-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
|
||||
@@ -0,0 +1,24 @@
|
||||
deferred class
|
||||
REST_APPLICATION_GATEWAY
|
||||
|
||||
inherit
|
||||
WGI_APPLICATION
|
||||
|
||||
feature -- Access
|
||||
|
||||
build_gateway_and_launch
|
||||
local
|
||||
cgi: EWF_CGI_CONNECTOR
|
||||
do
|
||||
create cgi.make (Current)
|
||||
cgi.launch
|
||||
end
|
||||
|
||||
gateway_name: STRING = "CGI"
|
||||
|
||||
exit_with_code (a_code: INTEGER)
|
||||
do
|
||||
(create {EXCEPTIONS}).die (a_code)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
deferred class
|
||||
REST_APPLICATION_GATEWAY
|
||||
|
||||
inherit
|
||||
WGI_APPLICATION
|
||||
|
||||
feature -- Access
|
||||
|
||||
build_gateway_and_launch
|
||||
local
|
||||
libfcgi: EWF_LIBFCGI_CONNECTOR
|
||||
do
|
||||
create libfcgi.make (Current)
|
||||
libfcgi.launch
|
||||
end
|
||||
|
||||
gateway_name: STRING = "libFCGI"
|
||||
|
||||
exit_with_code (a_code: INTEGER)
|
||||
do
|
||||
(create {EXCEPTIONS}).die (a_code)
|
||||
end
|
||||
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-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
|
||||
@@ -0,0 +1,44 @@
|
||||
deferred class
|
||||
REST_APPLICATION_GATEWAY
|
||||
|
||||
inherit
|
||||
WGI_APPLICATION
|
||||
|
||||
feature -- Access
|
||||
|
||||
build_gateway_and_launch
|
||||
local
|
||||
app: NINO_APPLICATION
|
||||
port_number: INTEGER
|
||||
base_url: STRING
|
||||
do
|
||||
port_number := 8080
|
||||
base_url := ""
|
||||
debug ("nino")
|
||||
print ("Example: start a Nino web server on port " + port_number.out +
|
||||
", %Nand reply Hello World for any request such as http://localhost:" + port_number.out + "/" + base_url + "%N")
|
||||
end
|
||||
create app.make_custom (agent execute, base_url)
|
||||
app.force_single_threaded
|
||||
|
||||
app.listen (port_number)
|
||||
end
|
||||
|
||||
gateway_name: STRING = "NINO"
|
||||
|
||||
exit_with_code (a_code: INTEGER)
|
||||
do
|
||||
(create {EXCEPTIONS}).die (a_code)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-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
|
||||
@@ -0,0 +1,30 @@
|
||||
note
|
||||
description: "Summary description for {APP_APPLICATION}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
APP_APPLICATION
|
||||
|
||||
inherit
|
||||
REST_APPLICATION [APP_REQUEST_HANDLER, APP_REQUEST_HANDLER_CONTEXT]
|
||||
redefine
|
||||
router
|
||||
end
|
||||
|
||||
feature {NONE} -- Router
|
||||
|
||||
router: APP_REQUEST_ROUTER
|
||||
|
||||
;note
|
||||
copyright: "Copyright (c) 1984-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
|
||||
@@ -0,0 +1,32 @@
|
||||
note
|
||||
description: "Summary description for REST_REQUEST_AGENT_HANDLER."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
APP_REQUEST_AGENT_HANDLER
|
||||
|
||||
inherit
|
||||
APP_REQUEST_HANDLER
|
||||
undefine
|
||||
execute, pre_execute, post_execute
|
||||
end
|
||||
|
||||
REST_REQUEST_AGENT_HANDLER [APP_REQUEST_HANDLER_CONTEXT]
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-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
|
||||
@@ -0,0 +1,60 @@
|
||||
note
|
||||
description : "Objects that ..."
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
deferred class
|
||||
APP_REQUEST_HANDLER
|
||||
|
||||
inherit
|
||||
REST_REQUEST_HANDLER [APP_REQUEST_HANDLER_CONTEXT]
|
||||
|
||||
APP_REQUEST_HELPER
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
string_hash_table_string_string (ht: HASH_TABLE_ITERATION_CURSOR [READABLE_STRING_GENERAL, READABLE_STRING_GENERAL]; using_pre: BOOLEAN): STRING_8
|
||||
do
|
||||
create Result.make (100)
|
||||
if using_pre then
|
||||
Result.append ("<pre>")
|
||||
end
|
||||
from
|
||||
ht.start
|
||||
until
|
||||
ht.after
|
||||
loop
|
||||
Result.append_string (ht.key.as_string_8 + " = " + ht.item.as_string_8 + "%N")
|
||||
ht.forth
|
||||
end
|
||||
if using_pre then
|
||||
Result.append ("</pre>")
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Helpers
|
||||
|
||||
format_id (s: detachable STRING): INTEGER
|
||||
do
|
||||
Result := {HTTP_FORMAT_CONSTANTS}.text
|
||||
if s /= Void then
|
||||
Result := format_constants.format_id (s)
|
||||
end
|
||||
end
|
||||
|
||||
exit_with_code (a_code: INTEGER)
|
||||
do
|
||||
(create {EXCEPTIONS}).die (a_code)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-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
|
||||
@@ -0,0 +1,86 @@
|
||||
note
|
||||
description : "Objects that ..."
|
||||
author : "$Author$"
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
class
|
||||
APP_REQUEST_HANDLER_CONTEXT
|
||||
|
||||
inherit
|
||||
REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT
|
||||
redefine
|
||||
authenticated,
|
||||
authenticated_identifier
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Auth
|
||||
|
||||
authenticated: BOOLEAN
|
||||
do
|
||||
if attached request.http_authorization as l_http_auth then
|
||||
Result := True
|
||||
end
|
||||
end
|
||||
|
||||
authenticated_identifier: detachable READABLE_STRING_32
|
||||
do
|
||||
if authenticated then
|
||||
Result := "foo"
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Format
|
||||
|
||||
get_format_id (a_format_variable_name: detachable READABLE_STRING_GENERAL; a_content_type_supported: detachable ARRAY [STRING_8])
|
||||
do
|
||||
if internal_format_id = 0 then
|
||||
internal_format_id := request_format_id (a_format_variable_name, a_content_type_supported)
|
||||
end
|
||||
end
|
||||
|
||||
get_format_name (a_format_variable_name: detachable READABLE_STRING_GENERAL; a_content_type_supported: detachable ARRAY [STRING_8])
|
||||
do
|
||||
if internal_format_name = Void then
|
||||
internal_format_name := request_format (a_format_variable_name, a_content_type_supported)
|
||||
end
|
||||
end
|
||||
|
||||
format_id: INTEGER
|
||||
do
|
||||
if internal_format_id = 0 then
|
||||
get_format_id (Void, Void)
|
||||
end
|
||||
Result := internal_format_id
|
||||
end
|
||||
|
||||
format_name: detachable READABLE_STRING_8
|
||||
do
|
||||
Result := internal_format_name
|
||||
if Result = Void then
|
||||
Result := request_format (Void, Void)
|
||||
internal_format_name := Result
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Internal
|
||||
|
||||
internal_format_id: like format_id
|
||||
|
||||
internal_format_name: like format_name
|
||||
|
||||
|
||||
;note
|
||||
copyright: "Copyright (c) 1984-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
|
||||
@@ -0,0 +1,101 @@
|
||||
note
|
||||
description: "Summary description for {APP_REQUEST_HELPER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
APP_REQUEST_HELPER
|
||||
|
||||
feature -- Helpers
|
||||
|
||||
send_error (a_path: STRING; a_error_id: INTEGER; a_error_name: STRING; a_error_message: detachable STRING; ctx: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||
local
|
||||
s: STRING
|
||||
i,nb: INTEGER
|
||||
rep_data: REST_RESPONSE
|
||||
do
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.expectation_failed)
|
||||
create rep_data.make (a_path)
|
||||
rep_data.headers.put_content_type_text_plain
|
||||
|
||||
create s.make_empty
|
||||
inspect ctx.format_id
|
||||
when {HTTP_FORMAT_CONSTANTS}.json then
|
||||
rep_data.headers.put_content_type_text_plain
|
||||
s := "{%"application%": %"" + a_path + "%""
|
||||
s.append_string (", %"error%": {")
|
||||
s.append_string ("%"id%": " + a_error_id.out)
|
||||
s.append_string (",%"name%": %"" + a_error_name + "%"")
|
||||
if a_error_message /= Void then
|
||||
s.append_string (",%"message%": %"")
|
||||
|
||||
if a_error_message.has ('%N') then
|
||||
from
|
||||
i := s.count
|
||||
s.append_string (a_error_message)
|
||||
nb := s.count
|
||||
until
|
||||
i > nb
|
||||
loop
|
||||
inspect s[i]
|
||||
when '%R' then
|
||||
if s.valid_index (i+1) and then s[i+1] = '%N' then
|
||||
s[i] := '\'
|
||||
s[i+1] := 'n'
|
||||
i := i + 1
|
||||
end
|
||||
when '%N' then
|
||||
s.insert_character ('\', i)
|
||||
s[i] := 'n'
|
||||
else
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
else
|
||||
s.append_string (a_error_message)
|
||||
end
|
||||
s.append_string ("%"")
|
||||
end
|
||||
|
||||
s.append_string ("}") -- end error
|
||||
s.append_string ("}") -- end global object
|
||||
rep_data.set_message (s)
|
||||
when {HTTP_FORMAT_CONSTANTS}.xml then
|
||||
rep_data.headers.put_content_type_text_xml
|
||||
s := "<application path=%"" + a_path + "%"><error id=%"" + a_error_id.out + "%" name=%""+ a_error_name +"%">"
|
||||
if a_error_message /= Void then
|
||||
s.append_string (a_error_message)
|
||||
end
|
||||
s.append_string ("</error></application>")
|
||||
rep_data.set_message (s)
|
||||
when {HTTP_FORMAT_CONSTANTS}.html then
|
||||
rep_data.headers.put_content_type_text_html
|
||||
s := "<strong>application</strong>: " + a_path + "<br/>%N<strong>Error</strong> (" + a_error_id.out + ") %"" + a_error_name + "%"<br/>%N"
|
||||
if a_error_message /= Void then
|
||||
s.append_string ("<blockquote>" + a_error_message + "</blockquote>")
|
||||
end
|
||||
rep_data.set_message (s)
|
||||
when {HTTP_FORMAT_CONSTANTS}.text then -- Default
|
||||
s := "Application: " + a_path + "<br/>%N"
|
||||
s.append_string ("Error (" + a_error_id.out + ") %"" + a_error_name + "%"%N")
|
||||
if a_error_message /= Void then
|
||||
s.append_string ("%T" + a_error_message + "%N")
|
||||
end
|
||||
rep_data.set_message (s)
|
||||
end
|
||||
rep_data.send (res)
|
||||
rep_data.recycle
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-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
|
||||
@@ -0,0 +1,26 @@
|
||||
note
|
||||
description: "Summary description for {REST_REQUEST_URI_TEMPLATE_ROUTER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
APP_REQUEST_ROUTER
|
||||
|
||||
inherit
|
||||
REST_REQUEST_URI_TEMPLATE_ROUTER [APP_REQUEST_HANDLER, APP_REQUEST_HANDLER_CONTEXT]
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-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
|
||||
@@ -0,0 +1,40 @@
|
||||
note
|
||||
description: "Summary description for {APP_REQUEST_ROUTING_HANDLER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
APP_REQUEST_ROUTING_HANDLER
|
||||
|
||||
inherit
|
||||
APP_REQUEST_HANDLER
|
||||
undefine
|
||||
execute,
|
||||
pre_execute,
|
||||
post_execute
|
||||
end
|
||||
|
||||
REST_REQUEST_URI_TEMPLATE_ROUTING_HANDLER [APP_REQUEST_HANDLER, APP_REQUEST_HANDLER_CONTEXT]
|
||||
redefine
|
||||
router
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Routing
|
||||
|
||||
router: APP_REQUEST_ROUTER
|
||||
|
||||
;note
|
||||
copyright: "Copyright (c) 1984-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
|
||||
Reference in New Issue
Block a user