Move "rest" library under "draft/..." since it is more an experiment rather than a real REST library
This commit is contained in:
1
draft/library/server/request/rest/license.lic
Normal file
1
draft/library/server/request/rest/license.lic
Normal file
@@ -0,0 +1 @@
|
||||
reference:forum2
|
||||
29
draft/library/server/request/rest/rest-safe.ecf
Normal file
29
draft/library/server/request/rest/rest-safe.ecf
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="rest" uuid="97FA9457-7820-4A21-8A13-C8D0E9CCEC62" library_target="rest">
|
||||
<target name="rest">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="wsf" location="..\..\wsf\wsf-safe.ecf" readonly="false"/>
|
||||
<library name="http" location="..\..\..\protocol\http\http-safe.ecf"/>
|
||||
<library name="router" location="..\..\request\router\router-safe.ecf" readonly="false"/>
|
||||
<library name="uri_template" location="..\..\..\protocol\uri_template\uri_template-safe.ecf" readonly="false"/>
|
||||
<cluster name="contrib" location=".\src\contrib\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/html$</exclude>
|
||||
</file_rule>
|
||||
<cluster name="html" location="$|doc\html\" recursive="true" hidden="true"/>
|
||||
</cluster>
|
||||
<cluster name="src" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/contrib$</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
</target>
|
||||
</system>
|
||||
28
draft/library/server/request/rest/rest.ecf
Normal file
28
draft/library/server/request/rest/rest.ecf
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="rest" uuid="97FA9457-7820-4A21-8A13-C8D0E9CCEC62" library_target="rest">
|
||||
<target name="rest">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="wsf" location="..\..\wsf\wsf.ecf"/>
|
||||
<library name="http" location="..\..\..\protocol\http\http.ecf"/>
|
||||
<library name="router" location="..\..\request\router\router.ecf" readonly="false"/>
|
||||
<library name="uri_template" location="..\..\..\protocol\uri_template\uri_template.ecf"/>
|
||||
<cluster name="contrib" location=".\src\contrib\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/html$</exclude>
|
||||
</file_rule>
|
||||
<cluster name="html" location="$|doc\html\" recursive="true" hidden="true"/>
|
||||
</cluster>
|
||||
<cluster name="src" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/contrib$</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
</target>
|
||||
</system>
|
||||
@@ -0,0 +1,184 @@
|
||||
note
|
||||
description: "Summary description for {HTML_PAGE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
HTML_PAGE
|
||||
|
||||
inherit
|
||||
HTML_UTILITIES
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_title: like title)
|
||||
do
|
||||
create {ARRAYED_LIST [like html_attributes.item]} html_attributes.make (0)
|
||||
create head.make (a_title)
|
||||
create {ARRAYED_LIST [like body_attributes.item]} body_attributes.make (0)
|
||||
create body.make_empty
|
||||
initialize
|
||||
end
|
||||
|
||||
initialize
|
||||
-- Initialize
|
||||
do
|
||||
create headers.make
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
headers: WSF_HEADER
|
||||
|
||||
feature -- Recycle
|
||||
|
||||
recycle
|
||||
do
|
||||
html_attributes.wipe_out
|
||||
headers.recycle
|
||||
head.recycle
|
||||
body_attributes.wipe_out
|
||||
body.wipe_out
|
||||
internal_header_string := Void
|
||||
internal_message_string := Void
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
html_attributes: LIST [TUPLE [name: STRING; value: STRING]]
|
||||
|
||||
head: HTML_PAGE_HEAD
|
||||
|
||||
body_attributes: LIST [TUPLE [name: STRING; value: STRING]]
|
||||
|
||||
body: STRING
|
||||
|
||||
feature -- Query
|
||||
|
||||
title: detachable STRING
|
||||
do
|
||||
Result := head.title
|
||||
end
|
||||
|
||||
add_html_ttribute (a: like html_attributes.item)
|
||||
do
|
||||
html_attributes.force (a)
|
||||
end
|
||||
|
||||
add_body_attribute (a: like body_attributes.item)
|
||||
do
|
||||
body_attributes.force (a)
|
||||
end
|
||||
|
||||
set_body (s: like body)
|
||||
-- Set `body' to `s'
|
||||
do
|
||||
body := s
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_title (t: like title)
|
||||
do
|
||||
head.title := t
|
||||
end
|
||||
|
||||
feature -- Output
|
||||
|
||||
compute
|
||||
-- Compute the string output
|
||||
local
|
||||
s, t: STRING
|
||||
do
|
||||
--| HTML beginning
|
||||
create s.make (128)
|
||||
s.append_string ("<html")
|
||||
s.append_string (attributes_to_string (html_attributes))
|
||||
s.append_string (">%N")
|
||||
|
||||
--| Head
|
||||
head.compute --| Be sure to have a fresh string
|
||||
t := head.string
|
||||
if not t.is_empty then
|
||||
s.append_string (t)
|
||||
s.append_character ('%N')
|
||||
end
|
||||
|
||||
--| Body
|
||||
s.append_string ("<body")
|
||||
s.append_string (attributes_to_string (body_attributes))
|
||||
s.append_string (">%N")
|
||||
s.append_string (body)
|
||||
s.append_string ("</body>")
|
||||
|
||||
--| End
|
||||
s.append_string ("</html>")
|
||||
|
||||
--| Http headers
|
||||
headers.put_content_length (s.count)
|
||||
internal_header_string := headers.string
|
||||
internal_message_string := s
|
||||
end
|
||||
|
||||
header_string: STRING
|
||||
local
|
||||
o: like internal_header_string
|
||||
do
|
||||
o := internal_header_string
|
||||
if o = Void then
|
||||
compute
|
||||
o := internal_header_string
|
||||
if o = Void then
|
||||
check output_computed: False end
|
||||
create o.make_empty
|
||||
end
|
||||
end
|
||||
Result := o
|
||||
end
|
||||
|
||||
message_string: STRING
|
||||
local
|
||||
o: like internal_message_string
|
||||
do
|
||||
o := internal_message_string
|
||||
if o = Void then
|
||||
compute
|
||||
o := internal_message_string
|
||||
if o = Void then
|
||||
check output_computed: False end
|
||||
create o.make_empty
|
||||
end
|
||||
end
|
||||
Result := o
|
||||
end
|
||||
|
||||
send (buf: WSF_RESPONSE)
|
||||
do
|
||||
buf.set_status_code (200)
|
||||
buf.write_headers_string (header_string)
|
||||
buf.write_string (message_string)
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: output
|
||||
|
||||
internal_header_string: detachable like header_string
|
||||
|
||||
internal_message_string: detachable like message_string
|
||||
|
||||
invariant
|
||||
header_attached: headers /= Void
|
||||
|
||||
;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,111 @@
|
||||
note
|
||||
description: "Summary description for {HTML_PAGE_HEAD}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
HTML_PAGE_HEAD
|
||||
|
||||
inherit
|
||||
HTML_UTILITIES
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_title: like title)
|
||||
do
|
||||
initialize
|
||||
title := a_title
|
||||
end
|
||||
|
||||
initialize
|
||||
do
|
||||
create text.make_empty
|
||||
create {ARRAYED_LIST [like attributes.item]} attributes.make (0)
|
||||
end
|
||||
|
||||
feature -- Recycle
|
||||
|
||||
recycle
|
||||
do
|
||||
attributes.wipe_out
|
||||
title := Void
|
||||
text.wipe_out
|
||||
internal_string := Void
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
attributes: LIST [TUPLE [name: STRING; value: STRING]]
|
||||
|
||||
title: detachable STRING assign set_title
|
||||
|
||||
text: STRING
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_title (t: like title)
|
||||
do
|
||||
title := t
|
||||
end
|
||||
|
||||
feature -- Output
|
||||
|
||||
compute
|
||||
-- Compute the string output
|
||||
local
|
||||
s: STRING
|
||||
do
|
||||
create s.make_empty
|
||||
if attached title as t then
|
||||
s.append_string ("<title>" + t + "</title>%N")
|
||||
end
|
||||
if text.count > 0 then
|
||||
s.append_string (text)
|
||||
s.append_character ('%N')
|
||||
end
|
||||
if s.count > 0 then
|
||||
internal_string := "<head" + attributes_to_string (attributes) + ">%N" + s + "</head>"
|
||||
else
|
||||
internal_string := s
|
||||
end
|
||||
end
|
||||
|
||||
string: STRING
|
||||
--
|
||||
local
|
||||
o: like internal_string
|
||||
do
|
||||
o := internal_string
|
||||
if o = Void then
|
||||
compute
|
||||
o := internal_string
|
||||
if o = Void then
|
||||
check output_computed: False end
|
||||
create o.make_empty
|
||||
end
|
||||
end
|
||||
Result := o
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: output
|
||||
|
||||
internal_string: detachable like string
|
||||
|
||||
invariant
|
||||
text_attached: text /= Void
|
||||
|
||||
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,90 @@
|
||||
note
|
||||
description: "Summary description for {HTML_UTILITIES}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
HTML_UTILITIES
|
||||
|
||||
feature -- Encoding
|
||||
|
||||
html_special_chars_encoded_string (s: STRING): STRING
|
||||
local
|
||||
c: CHARACTER
|
||||
i,n: INTEGER
|
||||
do
|
||||
from
|
||||
i := 1
|
||||
n := s.count
|
||||
create Result.make (n + 10)
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
c := s[i]
|
||||
inspect c
|
||||
when '&' then
|
||||
Result.append_string ("&")
|
||||
when '%"' then
|
||||
Result.append_string (""")
|
||||
when '%'' then
|
||||
Result.append_string ("'")
|
||||
when '<' then
|
||||
Result.append_string ("<")
|
||||
when '>' then
|
||||
Result.append_string (">")
|
||||
else
|
||||
Result.extend (c)
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Helpers
|
||||
|
||||
strings_to_string (lst: LIST [STRING]; sep: STRING): STRING
|
||||
do
|
||||
create Result.make_empty
|
||||
if lst.count > 0 then
|
||||
from
|
||||
lst.start
|
||||
until
|
||||
lst.after
|
||||
loop
|
||||
Result.append_string (lst.item)
|
||||
Result.append_string (sep)
|
||||
lst.forth
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
attributes_to_string (atts: LIST [TUPLE [name: STRING; value: STRING]]): STRING
|
||||
do
|
||||
create Result.make_empty
|
||||
if atts.count > 0 then
|
||||
from
|
||||
atts.start
|
||||
until
|
||||
atts.after
|
||||
loop
|
||||
Result.append_character (' ')
|
||||
Result.append_string (atts.item.name)
|
||||
Result.append_character ('=')
|
||||
Result.append_character ('%"')
|
||||
Result.append_string (html_special_chars_encoded_string (atts.item.value))
|
||||
Result.append_character ('%"')
|
||||
atts.forth
|
||||
end
|
||||
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
|
||||
@@ -0,0 +1,321 @@
|
||||
note
|
||||
description: "Summary description for {REST_API_DOCUMENTATION}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
REST_API_DOCUMENTATION [C -> REST_REQUEST_HANDLER_CONTEXT]
|
||||
|
||||
inherit
|
||||
REST_REQUEST_HANDLER [C]
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_router: like router; a_base_doc_url: like base_doc_url)
|
||||
do
|
||||
router := a_router
|
||||
base_doc_url := a_base_doc_url
|
||||
description := "Technical documention for the API"
|
||||
end
|
||||
|
||||
feature {NONE} -- Access: Implementation
|
||||
|
||||
router: REST_REQUEST_ROUTER [REST_REQUEST_HANDLER [C], C]
|
||||
|
||||
base_doc_url: READABLE_STRING_8
|
||||
|
||||
feature -- Access
|
||||
|
||||
authentication_required (req: WSF_REQUEST): BOOLEAN
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
rep: like new_html_page
|
||||
s: STRING
|
||||
rq: detachable REST_REQUEST_HANDLER [C]
|
||||
rq_resource: detachable READABLE_STRING_GENERAL
|
||||
-- l_dft_format_name: detachable STRING
|
||||
hdl_cursor: like router.new_cursor
|
||||
do
|
||||
rep := new_html_page
|
||||
rep.headers.put_content_type_text_html
|
||||
create s.make_empty
|
||||
|
||||
if
|
||||
attached {WSF_STRING} ctx.path_parameter ("resource") as l_resource_value and then
|
||||
attached l_resource_value.string as l_resource
|
||||
then
|
||||
from
|
||||
hdl_cursor := router.new_cursor
|
||||
until
|
||||
hdl_cursor.after or rq /= Void
|
||||
loop
|
||||
if hdl_cursor.item.resource.same_string_general (l_resource) then
|
||||
rq := hdl_cursor.item.handler
|
||||
rq_resource := l_resource
|
||||
end
|
||||
hdl_cursor.forth
|
||||
end
|
||||
end
|
||||
-- if a_args /= Void and then not a_args.is_empty then
|
||||
-- rq := router.handler_by_path (a_args)
|
||||
-- if rq = Void then
|
||||
-- rq := handler_manager.smart_handler_by_path (a_args)
|
||||
---- if attached {REST_REQUEST_GROUP_HANDLER} rq as grp then
|
||||
---- rq := grp.handlers.handler_by_path (a_args)
|
||||
---- end
|
||||
-- end
|
||||
-- if
|
||||
-- rq /= Void and then
|
||||
-- attached rq.path_information (a_args) as l_info
|
||||
-- then
|
||||
-- l_dft_format_name := l_info.format
|
||||
-- end
|
||||
-- end
|
||||
|
||||
|
||||
if rq /= Void and then rq_resource /= Void then
|
||||
rep.set_big_title ("API: Technical documentation for ["+ rq_resource.as_string_8 +"]")
|
||||
|
||||
s.append_string ("<div class=%"api%">")
|
||||
s.append_string ("<h2 class=%"api-name%" >")
|
||||
|
||||
s.append_string ("<a href=%"" + base_doc_url + "%">.. Show all features ..</a>")
|
||||
s.append_string ("</h2></div>%N")
|
||||
|
||||
process_request_handler_doc (rq, rq_resource.as_string_8, s, ctx, req, res, Void)
|
||||
else
|
||||
rep.set_big_title ("API: Technical documentation")
|
||||
|
||||
from
|
||||
hdl_cursor := router.new_cursor
|
||||
until
|
||||
hdl_cursor.after
|
||||
loop
|
||||
if attached hdl_cursor.item as l_item then
|
||||
rq := l_item.handler
|
||||
rep.add_shortcut (l_item.resource)
|
||||
s.append ("<a name=%"" + rep.last_added_shortcut + "%"/>")
|
||||
process_request_handler_doc (rq, l_item.resource, s, ctx, req, res, Void)
|
||||
hdl_cursor.forth
|
||||
end
|
||||
end
|
||||
end
|
||||
rep.set_body (s)
|
||||
rep.send (res)
|
||||
rep.recycle
|
||||
end
|
||||
|
||||
process_request_handler_doc (rq: REST_REQUEST_HANDLER [C]; a_resource: STRING; buf: STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE; a_dft_format: detachable STRING)
|
||||
local
|
||||
l_dft_format_name: detachable STRING
|
||||
s: STRING
|
||||
l_uri_tpl: URI_TEMPLATE
|
||||
do
|
||||
s := buf
|
||||
|
||||
if a_dft_format /= Void then
|
||||
if rq.supported_format_names.has (a_dft_format) then
|
||||
l_dft_format_name := a_dft_format
|
||||
end
|
||||
end
|
||||
|
||||
s.append_string ("<div class=%"api%">")
|
||||
s.append_string ("<h2 class=%"api-name%" ><a href=%""+ url (req, base_doc_url, a_resource, False) +"%">"+ a_resource +"</a></h2>")
|
||||
s.append_string ("<div class=%"inner%">")
|
||||
-- if rq.hidden (req) then
|
||||
-- s.append_string ("<div class=%"api-description%">This feature is hidden</div>%N")
|
||||
-- else
|
||||
if attached rq.description as desc then
|
||||
s.append_string ("<div class=%"api-description%">" + desc + "</div>")
|
||||
end
|
||||
-- if attached {REST_REQUEST_GROUP_HANDLER} rq as grp then
|
||||
-- s.append_string ("<div class=%"api-format%">Handler: <strong>")
|
||||
-- if attached grp.handlers.new_cursor as l_handlers_cursor then
|
||||
-- from
|
||||
|
||||
-- until
|
||||
-- l_handlers_cursor.after
|
||||
-- loop
|
||||
-- s.append_string (" ")
|
||||
-- s.append_string ("<a class=%"api-handler%" href=%"")
|
||||
-- s.append_string (url (ctx, l_handlers_cursor.item.path, False))
|
||||
-- s.append_string ("%">"+ l_handlers_cursor.item.path +"</a>")
|
||||
-- l_handlers_cursor.forth
|
||||
-- end
|
||||
-- end
|
||||
-- s.append_string ("</strong></div>")
|
||||
-- end
|
||||
if attached rq.supported_format_names as l_formats and then not l_formats.is_empty then
|
||||
s.append_string ("<div class=%"api-format%">Supported formats: <strong>")
|
||||
if attached l_formats.new_cursor as l_formats_cursor then
|
||||
from
|
||||
|
||||
until
|
||||
l_formats_cursor.after
|
||||
loop
|
||||
s.append_string (" ")
|
||||
s.append_string ("<a class=%"api-name api-format")
|
||||
if l_formats_cursor.item ~ l_dft_format_name then
|
||||
s.append_string (" selected")
|
||||
end
|
||||
s.append_string ("%" href=%"" + url (req, base_doc_url, a_resource, False) + "." + l_formats_cursor.item + "%">"+ l_formats_cursor.item +"</a>")
|
||||
l_formats_cursor.forth
|
||||
end
|
||||
end
|
||||
s.append_string ("</strong></div>")
|
||||
end
|
||||
if attached rq.supported_request_method_names as l_methods and then not l_methods.is_empty then
|
||||
s.append_string ("<div class=%"api-method%">Supported request methods: <strong>")
|
||||
if attached l_methods.new_cursor as l_methods_cursor then
|
||||
from
|
||||
|
||||
until
|
||||
l_methods_cursor.after
|
||||
loop
|
||||
s.append_string (" ")
|
||||
s.append_string (l_methods_cursor.item)
|
||||
l_methods_cursor.forth
|
||||
end
|
||||
end
|
||||
s.append_string ("</strong></div>")
|
||||
end
|
||||
s.append_string ("<div class=%"api-auth%">Authentication required: <strong>" + rq.authentication_required (req).out + "</strong></div>")
|
||||
if attached {REST_REQUEST_URI_TEMPLATE_ROUTER_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT], REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT]} router as l_uri_template_router then
|
||||
create l_uri_tpl.make (a_resource)
|
||||
if attached l_uri_tpl.query_variable_names as l_query_variable_names and then not l_query_variable_names.is_empty then
|
||||
s.append_string ("<div class=%"api-uri-template%">Query parameters: ")
|
||||
-- s.append_string (rq.path)
|
||||
from
|
||||
l_query_variable_names.start
|
||||
until
|
||||
l_query_variable_names.after
|
||||
loop
|
||||
if l_query_variable_names.isfirst then
|
||||
s.append_string ("?")
|
||||
else
|
||||
s.append_string ("&")
|
||||
end
|
||||
if attached l_query_variable_names.item as l_query_param then
|
||||
s.append_string ("<strong>" + l_query_param + "</strong>")
|
||||
s.append_string ("=<em>" + l_query_param + "</em>")
|
||||
end
|
||||
l_query_variable_names.forth
|
||||
end
|
||||
s.append_string ("</div>%N")
|
||||
end
|
||||
if attached l_uri_tpl.path_variable_names as l_path_variable_names and then not l_path_variable_names.is_empty then
|
||||
s.append_string ("<div class=%"api-uri-template%">Path Segment parameters: ")
|
||||
-- s.append_string (rq.path)
|
||||
from
|
||||
l_path_variable_names.start
|
||||
until
|
||||
l_path_variable_names.after
|
||||
loop
|
||||
if attached l_path_variable_names.item as l_seg_param then
|
||||
s.append_string ("<em>{" + l_seg_param + "}</em>")
|
||||
end
|
||||
l_path_variable_names.forth
|
||||
end
|
||||
s.append_string ("</div>%N")
|
||||
end
|
||||
|
||||
end
|
||||
-- if attached rq._parameters as l_uri_params and then not l_uri_params.is_empty then
|
||||
-- s.append_string ("<div class=%"api-uri-template%">URI Template: ")
|
||||
-- s.append_string (rq.path)
|
||||
-- if attached l_uri_params.new_cursor as l_uri_params_cursor then
|
||||
-- from
|
||||
|
||||
-- until
|
||||
-- l_uri_params_cursor.after
|
||||
-- loop
|
||||
-- if attached l_uri_params_cursor.item as l_uri_param then
|
||||
-- s.append_string ("/<strong>" + l_uri_param.name + "</strong>")
|
||||
-- s.append_string ("/<em>{" + l_uri_param.name + "}</em>")
|
||||
-- end
|
||||
-- l_uri_params_cursor.forth
|
||||
-- end
|
||||
-- end
|
||||
-- s.append_string ("</div>%N")
|
||||
-- end
|
||||
-- if attached rq.parameters as l_params and then not l_params.is_empty then
|
||||
-- s.append_string ("<div class=%"api-params%">Parameters: ")
|
||||
|
||||
-- --| show form only if we have a default format
|
||||
-- if l_dft_format_name = Void then
|
||||
-- s.append_string ("<span class=%"note%">to test the parameter(s), please first select a supported format.</span>%N")
|
||||
-- else
|
||||
-- if rq.method_post_supported then
|
||||
-- s.append_string ("<form id=%""+ rq.path +"%" method=%"POST%" action=%"" + ctx.script_url (rq.path) + "." + l_dft_format_name + "%">%N")
|
||||
-- else
|
||||
-- s.append_string ("<form id=%""+ rq.path +"%" method=%"GET%" action=%"" + ctx.script_url (rq.path) + "." + l_dft_format_name + "%">%N")
|
||||
-- end
|
||||
-- end
|
||||
-- s.append_string ("<ul>")
|
||||
-- if attached l_params.new_cursor as l_params_cursor then
|
||||
-- from
|
||||
|
||||
-- until
|
||||
-- l_params_cursor.after
|
||||
-- loop
|
||||
-- if attached l_params_cursor.item as l_param then
|
||||
-- s.append_string ("<li><strong>" + l_param.name + "</strong>")
|
||||
-- if l_param.optional then
|
||||
-- s.append_string (" <em>(Optional)</em>")
|
||||
-- end
|
||||
-- if attached l_param.description as l_param_desc then
|
||||
-- s.append_string (": <em>" + l_param_desc + "</em>")
|
||||
-- end
|
||||
-- if l_dft_format_name /= Void then
|
||||
-- s.append (" <input name=%"" + l_param.name + "%" type=%"text%" />")
|
||||
-- end
|
||||
-- s.append_string ("</li>")
|
||||
-- end
|
||||
-- l_params_cursor.forth
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- if l_dft_format_name /= Void then
|
||||
-- s.append_string ("<input type=%"submit%" value=%"Test "+ rq.path + "." + l_dft_format_name + "%"/>")
|
||||
-- s.append_string ("</form>")
|
||||
-- end
|
||||
-- s.append_string ("</ul></div>")
|
||||
-- else
|
||||
-- if l_dft_format_name /= Void then
|
||||
-- s.append_string ("<a class=%"api-name%" href=%"" + ctx.script_url (a_resource + "." + l_dft_format_name) + "%">Test "+ a_resource + "." + l_dft_format_name + "</a>")
|
||||
-- else
|
||||
-- s.append_string ("<a class=%"api-name%" href=%"" + ctx.script_url (a_resource) + "%">Test "+ a_resource +"</a>")
|
||||
-- end
|
||||
-- end
|
||||
s.append_string ("</div>%N")
|
||||
-- end
|
||||
s.append_string ("</div>%N") -- inner
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
new_html_page: REST_API_DOCUMENTATION_HTML_PAGE
|
||||
do
|
||||
create Result.make ("API Documentation")
|
||||
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,124 @@
|
||||
note
|
||||
description: "Summary description for {REST_API_DOCUMENTATION_HTML_PAGE}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
REST_API_DOCUMENTATION_HTML_PAGE
|
||||
|
||||
inherit
|
||||
HTML_PAGE
|
||||
redefine
|
||||
head,
|
||||
initialize,
|
||||
recycle,
|
||||
compute
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
initialize
|
||||
do
|
||||
Precursor
|
||||
create {LINKED_LIST [like shortcuts.item]} shortcuts.make
|
||||
end
|
||||
|
||||
feature -- Recyle
|
||||
|
||||
recycle
|
||||
do
|
||||
Precursor
|
||||
shortcuts.wipe_out
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
head: REST_API_DOCUMENTATION_HTML_PAGE_HEAD
|
||||
|
||||
big_title: detachable STRING
|
||||
|
||||
shortcuts: LIST [TUPLE [name: STRING; anchor: STRING]]
|
||||
|
||||
add_shortcut (s: STRING)
|
||||
local
|
||||
t: STRING
|
||||
do
|
||||
t := s.string
|
||||
t.replace_substring_all ("/", "-")
|
||||
shortcuts.force ([s,t])
|
||||
end
|
||||
|
||||
last_added_shortcut: STRING
|
||||
do
|
||||
if shortcuts.count > 0 and then attached shortcuts.last as sht then
|
||||
Result := sht.anchor
|
||||
else
|
||||
create Result.make_empty
|
||||
end
|
||||
end
|
||||
|
||||
shortcuts_to_html: detachable STRING
|
||||
do
|
||||
if not shortcuts.is_empty then
|
||||
from
|
||||
create Result.make_from_string ("<strong>Shortcuts:</strong> | ")
|
||||
shortcuts.start
|
||||
until
|
||||
shortcuts.after
|
||||
loop
|
||||
Result.append_string ("<a href=%"#"+ shortcuts.item.anchor +"%">"+ shortcuts.item.name +"</a> | ")
|
||||
shortcuts.forth
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_big_title (t: like big_title)
|
||||
do
|
||||
big_title := t
|
||||
end
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
compute
|
||||
local
|
||||
l_old_body: STRING
|
||||
sh, bt: detachable STRING
|
||||
do
|
||||
sh := shortcuts_to_html
|
||||
bt := big_title
|
||||
if sh /= Void or bt /= Void then
|
||||
l_old_body := body
|
||||
if bt /= Void then
|
||||
bt := "<h1>" + bt + "</h2>%N"
|
||||
if sh /= Void then
|
||||
body := bt + sh + l_old_body
|
||||
else
|
||||
body := bt + l_old_body
|
||||
end
|
||||
elseif sh /= Void then
|
||||
body := sh + l_old_body
|
||||
end
|
||||
Precursor
|
||||
body := l_old_body
|
||||
else
|
||||
Precursor
|
||||
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
|
||||
@@ -0,0 +1,75 @@
|
||||
note
|
||||
description: "Summary description for {REST_API_DOCUMENTATION_HTML_PAGE_HEAD}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
REST_API_DOCUMENTATION_HTML_PAGE_HEAD
|
||||
|
||||
inherit
|
||||
HTML_PAGE_HEAD
|
||||
redefine
|
||||
initialize,
|
||||
compute
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
initialize
|
||||
do
|
||||
Precursor
|
||||
style := "[
|
||||
body {margin: 0px;}
|
||||
a { text-decoration: none; }
|
||||
h1 { padding: 10px; border: solid 2px #000; background-color: #009; color: #fff;}
|
||||
div.api { padding: 5px; margin-bottom: 10px;}
|
||||
div.api .api-description { padding: 5px 5px 5px 0px; font-style: italic; color: #090;}
|
||||
div.api div.inner { padding-left: 40px;}
|
||||
div.api h2>a { color: #009; text-decoration: none;}
|
||||
div.api a.api-format { color: #009; text-decoration: none;}
|
||||
div.api a.api-format.selected { padding: 0 4px 0 4px; color: #009; text-decoration: none; border: solid 1px #99c; background-color: #eeeeff;}
|
||||
div.api>h2 { margin: 2px; padding: 2px 2px 2px 10px; display: inline-block; border: dotted 1px #cce; width: 100%; color: #009; background-color: #E7F3F8; text-decoration: none; font-weight: bold; font-size: 120%;}
|
||||
div.api span.note { font-style: italic;}
|
||||
]"
|
||||
end
|
||||
|
||||
feature {REST_API_DOCUMENTATION_HTML_PAGE} -- Access
|
||||
|
||||
style: STRING
|
||||
|
||||
feature -- Output
|
||||
|
||||
compute
|
||||
-- Compute the string output
|
||||
local
|
||||
s: detachable STRING
|
||||
p: INTEGER
|
||||
do
|
||||
Precursor
|
||||
s := internal_string
|
||||
if s /= Void then
|
||||
p := s.substring_index ("</head>", 1)
|
||||
if p > 0 then
|
||||
s.insert_string ("<style>%N" + style + "%N</style>%N", p)
|
||||
else
|
||||
s.append_string ("<style>%N" + style + "%N</style>%N")
|
||||
end
|
||||
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
|
||||
@@ -0,0 +1,47 @@
|
||||
note
|
||||
description: "Summary description for REST_REQUEST_GROUP_HANDLER."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
REST_REQUEST_GROUP_HANDLER [H -> REST_REQUEST_HANDLER [C], C -> REST_REQUEST_HANDLER_CONTEXT]
|
||||
|
||||
inherit
|
||||
REQUEST_ROUTING_HANDLER [H, C]
|
||||
redefine
|
||||
execute
|
||||
end
|
||||
|
||||
REST_REQUEST_HANDLER [C]
|
||||
redefine
|
||||
execute
|
||||
select
|
||||
execute_application
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- status
|
||||
|
||||
authentication_required: BOOLEAN
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||
do
|
||||
Precursor {REST_REQUEST_HANDLER} (ctx, req, res)
|
||||
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
|
||||
156
draft/library/server/request/rest/src/response/rest_response.e
Normal file
156
draft/library/server/request/rest/src/response/rest_response.e
Normal file
@@ -0,0 +1,156 @@
|
||||
note
|
||||
description: "Summary description for {REST_RESPONSE}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
REST_RESPONSE
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_api: like api)
|
||||
do
|
||||
api := a_api
|
||||
initialize
|
||||
end
|
||||
|
||||
initialize
|
||||
do
|
||||
create headers.make
|
||||
end
|
||||
|
||||
feature -- Recycle
|
||||
|
||||
recycle
|
||||
do
|
||||
headers.recycle
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
headers: WSF_HEADER
|
||||
|
||||
api: STRING
|
||||
-- Associated api query string.
|
||||
|
||||
message: detachable STRING_8
|
||||
-- Associated message to send with the response.
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_message (m: like message)
|
||||
-- Set `message' to `m'
|
||||
do
|
||||
message := m
|
||||
end
|
||||
|
||||
append_message (m: attached like message)
|
||||
-- Append message `m' to current `message' value
|
||||
-- create `message' is Void
|
||||
require
|
||||
m_not_empty: m /= Void and then not m.is_empty
|
||||
do
|
||||
if attached message as msg then
|
||||
msg.append (m)
|
||||
else
|
||||
set_message (m.string)
|
||||
end
|
||||
end
|
||||
|
||||
append_message_file_content (fn: STRING)
|
||||
-- Append file content from `fn' to the response
|
||||
--| To use with care.
|
||||
--| You should avoid using this for big or binary content ...
|
||||
local
|
||||
f: RAW_FILE
|
||||
do
|
||||
create f.make (fn)
|
||||
if f.exists and then f.is_readable then
|
||||
f.open_read
|
||||
from
|
||||
until
|
||||
f.exhausted
|
||||
loop
|
||||
f.read_stream (1024)
|
||||
append_message (f.last_string)
|
||||
end
|
||||
f.close
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Output
|
||||
|
||||
update_content_length (a_overwrite: BOOLEAN)
|
||||
-- Update content length
|
||||
-- if the header already exists it won't change it,
|
||||
-- unless `a_overwrite' is set to True
|
||||
local
|
||||
hds: like headers
|
||||
len: INTEGER
|
||||
do
|
||||
hds := headers
|
||||
if a_overwrite or else not hds.has_content_length then
|
||||
if attached message as m then
|
||||
len := m.count
|
||||
-- if {PLATFORM}.is_windows then
|
||||
-- len := len + m.occurrences ('%N') --| FIXME: find better solution
|
||||
-- end
|
||||
else
|
||||
len := 0
|
||||
end
|
||||
hds.put_content_length (len)
|
||||
end
|
||||
end
|
||||
|
||||
compute
|
||||
-- Compute the string output
|
||||
do
|
||||
update_content_length (False)
|
||||
internal_headers_string := headers.string
|
||||
end
|
||||
|
||||
headers_string: STRING
|
||||
local
|
||||
o: like internal_headers_string
|
||||
do
|
||||
o := internal_headers_string
|
||||
if o = Void then
|
||||
compute
|
||||
o := internal_headers_string
|
||||
if o = Void then
|
||||
check output_computed: False end
|
||||
create o.make_empty
|
||||
end
|
||||
end
|
||||
Result := o
|
||||
end
|
||||
|
||||
send (res: WSF_RESPONSE)
|
||||
do
|
||||
compute
|
||||
res.set_status_code (200)
|
||||
res.write_headers_string (headers_string)
|
||||
if attached message as m then
|
||||
res.write_string (m)
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: output
|
||||
|
||||
internal_headers_string: detachable like headers_string
|
||||
|
||||
;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,52 @@
|
||||
note
|
||||
description: "Summary description for REST_REQUEST_AGENT_HANDLER."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
REST_REQUEST_AGENT_HANDLER [C -> REST_REQUEST_HANDLER_CONTEXT]
|
||||
|
||||
inherit
|
||||
REQUEST_AGENT_HANDLER [C]
|
||||
rename
|
||||
execute as execute_application
|
||||
end
|
||||
|
||||
REST_REQUEST_HANDLER [C]
|
||||
select
|
||||
execute
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- status
|
||||
|
||||
authentication_required (req: WSF_REQUEST): BOOLEAN
|
||||
do
|
||||
Result := internal_authentication_required
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_authentication_required (b: like authentication_required)
|
||||
do
|
||||
internal_authentication_required := b
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
internal_authentication_required: BOOLEAN
|
||||
|
||||
;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
|
||||
339
draft/library/server/request/rest/src/rest_request_handler.e
Normal file
339
draft/library/server/request/rest/src/rest_request_handler.e
Normal file
@@ -0,0 +1,339 @@
|
||||
note
|
||||
description: "Summary description for {REST_REQUEST_HANDLER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
REST_REQUEST_HANDLER [C -> REST_REQUEST_HANDLER_CONTEXT]
|
||||
|
||||
inherit
|
||||
REQUEST_HANDLER [C]
|
||||
redefine
|
||||
execute
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
authentication_required (req: WSF_REQUEST): BOOLEAN
|
||||
-- Is authentication required
|
||||
-- might depend on the request environment
|
||||
-- or the associated resources
|
||||
deferred
|
||||
end
|
||||
|
||||
description: detachable STRING
|
||||
-- Optional description
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_description (s: like description)
|
||||
-- Set `description' to `s'
|
||||
do
|
||||
description := s
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
local
|
||||
rescued: BOOLEAN
|
||||
do
|
||||
if not rescued then
|
||||
if request_method_name_supported (req.request_method) then
|
||||
if authentication_required (req) and then not authenticated (ctx) then
|
||||
execute_unauthorized (ctx, req, res)
|
||||
else
|
||||
pre_execute (ctx, req, res)
|
||||
execute_application (ctx, req, res)
|
||||
post_execute (ctx, req, res)
|
||||
end
|
||||
else
|
||||
execute_request_method_not_allowed (req, res, supported_request_method_names)
|
||||
end
|
||||
else
|
||||
rescue_execute (ctx, req, res)
|
||||
end
|
||||
rescue
|
||||
rescued := True
|
||||
retry
|
||||
end
|
||||
|
||||
execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
deferred
|
||||
end
|
||||
|
||||
pre_execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
do
|
||||
end
|
||||
|
||||
post_execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
do
|
||||
end
|
||||
|
||||
rescue_execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
do
|
||||
post_execute (ctx, req, res)
|
||||
end
|
||||
|
||||
execute_unauthorized (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
do
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
|
||||
res.write_header ({HTTP_STATUS_CODE}.unauthorized, Void)
|
||||
res.write_string ("Unauthorized")
|
||||
end
|
||||
|
||||
feature -- Auth
|
||||
|
||||
authenticated (ctx: C): BOOLEAN
|
||||
-- Is authenticated?
|
||||
do
|
||||
--| To redefine if needed
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
supported_formats: INTEGER
|
||||
-- Support request format result such as json, xml, ...
|
||||
|
||||
feature {NONE} -- Status report
|
||||
|
||||
format_id_supported (a_id: INTEGER): BOOLEAN
|
||||
do
|
||||
Result := (supported_formats & a_id) = a_id
|
||||
end
|
||||
|
||||
format_name_supported (n: STRING): BOOLEAN
|
||||
-- Is format `n' supported?
|
||||
do
|
||||
Result := format_id_supported (format_constants.format_id (n))
|
||||
end
|
||||
|
||||
format_constants: HTTP_FORMAT_CONSTANTS
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
supported_format_names: LIST [STRING]
|
||||
-- Supported format names ...
|
||||
do
|
||||
create {LINKED_LIST [STRING]} Result.make
|
||||
if format_json_supported then
|
||||
Result.extend (format_constants.json_name)
|
||||
end
|
||||
if format_xml_supported then
|
||||
Result.extend (format_constants.xml_name)
|
||||
end
|
||||
if format_text_supported then
|
||||
Result.extend (format_constants.text_name)
|
||||
end
|
||||
if format_html_supported then
|
||||
Result.extend (format_constants.html_name)
|
||||
end
|
||||
if format_rss_supported then
|
||||
Result.extend (format_constants.rss_name)
|
||||
end
|
||||
if format_atom_supported then
|
||||
Result.extend (format_constants.atom_name)
|
||||
end
|
||||
end
|
||||
|
||||
format_json_supported: BOOLEAN
|
||||
do
|
||||
Result := format_id_supported ({HTTP_FORMAT_CONSTANTS}.json)
|
||||
end
|
||||
|
||||
format_xml_supported: BOOLEAN
|
||||
do
|
||||
Result := format_id_supported ({HTTP_FORMAT_CONSTANTS}.xml)
|
||||
end
|
||||
|
||||
format_text_supported: BOOLEAN
|
||||
do
|
||||
Result := format_id_supported ({HTTP_FORMAT_CONSTANTS}.text)
|
||||
end
|
||||
|
||||
format_html_supported: BOOLEAN
|
||||
do
|
||||
Result := format_id_supported ({HTTP_FORMAT_CONSTANTS}.html)
|
||||
end
|
||||
|
||||
format_rss_supported: BOOLEAN
|
||||
do
|
||||
Result := format_id_supported ({HTTP_FORMAT_CONSTANTS}.rss)
|
||||
end
|
||||
|
||||
format_atom_supported: BOOLEAN
|
||||
do
|
||||
Result := format_id_supported ({HTTP_FORMAT_CONSTANTS}.atom)
|
||||
end
|
||||
|
||||
feature -- Element change: formats
|
||||
|
||||
reset_supported_formats
|
||||
do
|
||||
supported_formats := 0
|
||||
end
|
||||
|
||||
enable_format_json
|
||||
do
|
||||
enable_format ({HTTP_FORMAT_CONSTANTS}.json)
|
||||
end
|
||||
|
||||
enable_format_xml
|
||||
do
|
||||
enable_format ({HTTP_FORMAT_CONSTANTS}.xml)
|
||||
end
|
||||
|
||||
enable_format_text
|
||||
do
|
||||
enable_format ({HTTP_FORMAT_CONSTANTS}.text)
|
||||
end
|
||||
|
||||
enable_format_html
|
||||
do
|
||||
enable_format ({HTTP_FORMAT_CONSTANTS}.html)
|
||||
end
|
||||
|
||||
enable_format (f: INTEGER)
|
||||
do
|
||||
supported_formats := supported_formats | f
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
supported_request_methods: INTEGER
|
||||
-- Support request method such as GET, POST, ...
|
||||
|
||||
feature {NONE} -- Status report
|
||||
|
||||
request_method_id_supported (a_id: INTEGER): BOOLEAN
|
||||
do
|
||||
Result := (supported_request_methods & a_id) = a_id
|
||||
end
|
||||
|
||||
request_method_name_supported (n: STRING): BOOLEAN
|
||||
-- Is request method `n' supported?
|
||||
do
|
||||
Result := request_method_id_supported (request_method_constants.method_id (n))
|
||||
end
|
||||
|
||||
request_method_constants: HTTP_REQUEST_METHOD_CONSTANTS
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
supported_request_method_names: LIST [STRING]
|
||||
-- Support request method such as GET, POST, ...
|
||||
do
|
||||
create {LINKED_LIST [STRING]} Result.make
|
||||
if method_get_supported then
|
||||
Result.extend (request_method_constants.method_get)
|
||||
end
|
||||
if method_post_supported then
|
||||
Result.extend (request_method_constants.method_post)
|
||||
end
|
||||
if method_put_supported then
|
||||
Result.extend (request_method_constants.method_put)
|
||||
end
|
||||
if method_patch_supported then
|
||||
Result.extend (request_method_constants.method_patch)
|
||||
end
|
||||
if method_delete_supported then
|
||||
Result.extend (request_method_constants.method_delete)
|
||||
end
|
||||
if method_head_supported then
|
||||
Result.extend (request_method_constants.method_head)
|
||||
end
|
||||
end
|
||||
|
||||
method_get_supported: BOOLEAN
|
||||
do
|
||||
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.get)
|
||||
end
|
||||
|
||||
method_post_supported: BOOLEAN
|
||||
do
|
||||
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.post)
|
||||
end
|
||||
|
||||
method_put_supported: BOOLEAN
|
||||
do
|
||||
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.put)
|
||||
end
|
||||
|
||||
method_patch_supported: BOOLEAN
|
||||
do
|
||||
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.patch)
|
||||
end
|
||||
|
||||
method_delete_supported: BOOLEAN
|
||||
do
|
||||
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.delete)
|
||||
end
|
||||
|
||||
method_head_supported: BOOLEAN
|
||||
do
|
||||
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.head)
|
||||
end
|
||||
|
||||
feature -- Element change: request methods
|
||||
|
||||
reset_supported_request_methods
|
||||
do
|
||||
supported_request_methods := 0
|
||||
end
|
||||
|
||||
enable_request_method_get
|
||||
do
|
||||
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.get)
|
||||
end
|
||||
|
||||
enable_request_method_post
|
||||
do
|
||||
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.post)
|
||||
end
|
||||
|
||||
enable_request_method_put
|
||||
do
|
||||
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.put)
|
||||
end
|
||||
|
||||
enable_request_method_patch
|
||||
do
|
||||
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.patch)
|
||||
end
|
||||
|
||||
enable_request_method_delete
|
||||
do
|
||||
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.delete)
|
||||
end
|
||||
|
||||
enable_request_method_head
|
||||
do
|
||||
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.head)
|
||||
end
|
||||
|
||||
enable_request_method (m: INTEGER)
|
||||
do
|
||||
supported_request_methods := supported_request_methods | m
|
||||
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,67 @@
|
||||
note
|
||||
description: "Summary description for {REST_REQUEST_HANDLER_CONTEXT}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
REST_REQUEST_HANDLER_CONTEXT
|
||||
|
||||
inherit
|
||||
REQUEST_HANDLER_CONTEXT
|
||||
|
||||
feature -- Status report
|
||||
|
||||
script_absolute_url (a_path: STRING): STRING
|
||||
-- Absolute Url for the script if any, extended by `a_path'
|
||||
do
|
||||
Result := request.absolute_script_url (a_path)
|
||||
end
|
||||
|
||||
script_url (a_path: STRING): STRING
|
||||
-- Url relative to script name if any, extended by `a_path'
|
||||
require
|
||||
a_path_attached: a_path /= Void
|
||||
do
|
||||
Result := request.script_url (a_path)
|
||||
end
|
||||
|
||||
url (args: detachable STRING; abs: BOOLEAN): STRING
|
||||
-- Associated url based on `path' and `args'
|
||||
-- if `abs' then return absolute url
|
||||
local
|
||||
s,t: detachable STRING
|
||||
do
|
||||
s := args
|
||||
if s /= Void and then s.count > 0 then
|
||||
create t.make_from_string (path)
|
||||
if s[1] /= '/' then
|
||||
t.append_character ('/')
|
||||
t.append (s)
|
||||
else
|
||||
t.append (s)
|
||||
end
|
||||
s := t
|
||||
else
|
||||
s := path
|
||||
end
|
||||
if abs then
|
||||
Result := script_absolute_url (s)
|
||||
else
|
||||
Result := script_url (s)
|
||||
end
|
||||
ensure
|
||||
result_attached: Result /= Void
|
||||
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
|
||||
23
draft/library/server/request/rest/src/rest_request_router.e
Normal file
23
draft/library/server/request/rest/src/rest_request_router.e
Normal file
@@ -0,0 +1,23 @@
|
||||
note
|
||||
description: "Summary description for {REST_REQUEST_ROUTER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
REST_REQUEST_ROUTER [H -> REST_REQUEST_HANDLER [C], C -> REST_REQUEST_HANDLER_CONTEXT]
|
||||
|
||||
inherit
|
||||
REQUEST_ROUTER [H, C]
|
||||
|
||||
;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
|
||||
23
draft/library/server/request/rest/src/rest_service.e
Normal file
23
draft/library/server/request/rest/src/rest_service.e
Normal file
@@ -0,0 +1,23 @@
|
||||
note
|
||||
description: "Summary description for {DEFAULT_REST_SERVICE}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
REST_SERVICE
|
||||
|
||||
inherit
|
||||
REST_SERVICE_I [REST_REQUEST_HANDLER [REST_REQUEST_HANDLER_CONTEXT], REST_REQUEST_HANDLER_CONTEXT]
|
||||
|
||||
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
|
||||
31
draft/library/server/request/rest/src/rest_service_i.e
Normal file
31
draft/library/server/request/rest/src/rest_service_i.e
Normal file
@@ -0,0 +1,31 @@
|
||||
note
|
||||
description: "Summary description for {REST_SERVICE}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
REST_SERVICE_I [H -> REST_REQUEST_HANDLER [C], C -> REST_REQUEST_HANDLER_CONTEXT]
|
||||
|
||||
inherit
|
||||
ROUTED_SERVICE_I [H, C]
|
||||
redefine
|
||||
router
|
||||
end
|
||||
|
||||
feature -- Setup
|
||||
|
||||
router: REST_REQUEST_ROUTER [H, C]
|
||||
-- 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,24 @@
|
||||
note
|
||||
description: "Summary description for {DEFAULT_REST_REQUEST_URI_HANDLER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
REST_REQUEST_URI_HANDLER
|
||||
|
||||
inherit
|
||||
REST_REQUEST_HANDLER [REST_REQUEST_URI_HANDLER_CONTEXT]
|
||||
|
||||
|
||||
;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,28 @@
|
||||
note
|
||||
description: "Summary description for {REQUEST_URI_HANDLER_CONTEXT}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
REST_REQUEST_URI_HANDLER_CONTEXT
|
||||
|
||||
inherit
|
||||
REQUEST_URI_HANDLER_CONTEXT
|
||||
|
||||
REST_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 {DEFAULT_REST_REQUEST_URI_ROUTER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
REST_REQUEST_URI_ROUTER
|
||||
|
||||
inherit
|
||||
REST_REQUEST_URI_ROUTER_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_HANDLER_CONTEXT], REST_REQUEST_URI_HANDLER_CONTEXT]
|
||||
redefine
|
||||
map_agent_with_request_methods
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Mapping
|
||||
|
||||
map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REST_REQUEST_URI_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]];
|
||||
rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
||||
local
|
||||
h: REST_REQUEST_AGENT_HANDLER [REST_REQUEST_URI_HANDLER_CONTEXT]
|
||||
do
|
||||
create h.make (a_action)
|
||||
map_with_request_methods (a_id, h, rqst_methods)
|
||||
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,36 @@
|
||||
note
|
||||
description: "Summary description for {REST_REQUEST_URI_ROUTER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
REST_REQUEST_URI_ROUTER_I [H -> REST_REQUEST_HANDLER [C], C -> REST_REQUEST_URI_HANDLER_CONTEXT create make end]
|
||||
|
||||
inherit
|
||||
REQUEST_URI_ROUTER_I [H, C]
|
||||
|
||||
REST_REQUEST_ROUTER [H, C]
|
||||
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Mapping
|
||||
|
||||
-- map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: like {REST_REQUEST_AGENT_HANDLER}.action; rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
||||
-- do
|
||||
-- Precursor (a_id, a_action, rqst_methods)
|
||||
-- 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,33 @@
|
||||
note
|
||||
description: "Summary description for {DEFAULT_REST_REQUEST_URI_ROUTING_HANDLER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
REST_REQUEST_URI_ROUTING_HANDLER
|
||||
|
||||
inherit
|
||||
REST_REQUEST_URI_ROUTING_HANDLER_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_HANDLER_CONTEXT], REST_REQUEST_URI_HANDLER_CONTEXT]
|
||||
redefine
|
||||
router
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Routing
|
||||
|
||||
router: REST_REQUEST_URI_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,64 @@
|
||||
note
|
||||
description: "Summary description for {REQUEST_ROUTING_HANDLER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
REST_REQUEST_URI_ROUTING_HANDLER_I [H -> REST_REQUEST_HANDLER [C],
|
||||
C -> REST_REQUEST_URI_HANDLER_CONTEXT create make end]
|
||||
|
||||
inherit
|
||||
REQUEST_URI_ROUTING_HANDLER_I [H, C]
|
||||
redefine
|
||||
router,
|
||||
execute
|
||||
end
|
||||
|
||||
REST_REQUEST_HANDLER [C]
|
||||
undefine
|
||||
execute
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Status report
|
||||
|
||||
authentication_required (req: WSF_REQUEST): BOOLEAN
|
||||
do
|
||||
Result := internal_authentication_required
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
internal_authentication_required: BOOLEAN
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
do
|
||||
Precursor {REQUEST_URI_ROUTING_HANDLER_I} (ctx, req, res)
|
||||
end
|
||||
|
||||
execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
do
|
||||
check should_not_occur: False end
|
||||
end
|
||||
|
||||
|
||||
feature {NONE} -- Routing
|
||||
|
||||
router: REST_REQUEST_URI_ROUTER_I [H, C]
|
||||
|
||||
;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
|
||||
30
draft/library/server/request/rest/src/uri/rest_uri_service.e
Normal file
30
draft/library/server/request/rest/src/uri/rest_uri_service.e
Normal file
@@ -0,0 +1,30 @@
|
||||
note
|
||||
description: "Summary description for {DEFAULT_REST_URI_SERVICE}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
REST_URI_SERVICE
|
||||
|
||||
inherit
|
||||
REST_SERVICE_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_HANDLER_CONTEXT], REST_REQUEST_URI_HANDLER_CONTEXT]
|
||||
redefine
|
||||
router
|
||||
end
|
||||
|
||||
feature -- Router
|
||||
|
||||
router: REST_REQUEST_URI_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,24 @@
|
||||
note
|
||||
description: "Summary description for {DEFAULT_REST_REQUEST_URI_TEMPLATE_HANDLER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
REST_REQUEST_URI_TEMPLATE_HANDLER
|
||||
|
||||
inherit
|
||||
REST_REQUEST_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT]
|
||||
|
||||
|
||||
;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,28 @@
|
||||
note
|
||||
description: "Summary description for {REQUEST_URI_TEMPLATE_HANDLER_CONTEXT}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT
|
||||
|
||||
inherit
|
||||
REQUEST_URI_TEMPLATE_HANDLER_CONTEXT
|
||||
|
||||
REST_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 {DEFAULT_REST_REQUEST_URI_TEMPLATE_ROUTER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
REST_REQUEST_URI_TEMPLATE_ROUTER
|
||||
|
||||
inherit
|
||||
REST_REQUEST_URI_TEMPLATE_ROUTER_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT], REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT]
|
||||
redefine
|
||||
map_agent_with_request_methods
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Mapping
|
||||
|
||||
map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]];
|
||||
rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
||||
local
|
||||
h: REST_REQUEST_AGENT_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT]
|
||||
do
|
||||
create h.make (a_action)
|
||||
map_with_request_methods (a_id, h, rqst_methods)
|
||||
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,28 @@
|
||||
note
|
||||
description: "Summary description for {REST_REQUEST_URI_TEMPLATE_ROUTER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
REST_REQUEST_URI_TEMPLATE_ROUTER_I [H -> REST_REQUEST_HANDLER [C], C -> REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT create make end]
|
||||
|
||||
inherit
|
||||
REQUEST_URI_TEMPLATE_ROUTER_I [H, C]
|
||||
|
||||
REST_REQUEST_ROUTER [H, C]
|
||||
|
||||
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,33 @@
|
||||
note
|
||||
description: "Summary description for {DEFAULT_REST_REQUEST_URI_TEMPLATE_ROUTING_HANDLER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
REST_REQUEST_URI_TEMPLATE_ROUTING_HANDLER
|
||||
|
||||
inherit
|
||||
REST_REQUEST_URI_TEMPLATE_ROUTING_HANDLER_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT], REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT]
|
||||
redefine
|
||||
router
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Routing
|
||||
|
||||
router: REST_REQUEST_URI_TEMPLATE_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,65 @@
|
||||
note
|
||||
description: "Summary description for {REQUEST_ROUTING_HANDLER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
REST_REQUEST_URI_TEMPLATE_ROUTING_HANDLER_I [H -> REST_REQUEST_HANDLER [C],
|
||||
C -> REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT create make end]
|
||||
|
||||
inherit
|
||||
REQUEST_URI_TEMPLATE_ROUTING_HANDLER_I [H, C]
|
||||
redefine
|
||||
router,
|
||||
execute
|
||||
end
|
||||
|
||||
REST_REQUEST_HANDLER [C]
|
||||
undefine
|
||||
execute
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Status report
|
||||
|
||||
authentication_required (req: WSF_REQUEST): BOOLEAN
|
||||
do
|
||||
Result := internal_authentication_required
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
internal_authentication_required: BOOLEAN
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
do
|
||||
pre_execute (ctx, req, res)
|
||||
Precursor {REQUEST_URI_TEMPLATE_ROUTING_HANDLER_I} (ctx, req, res)
|
||||
post_execute (ctx, req, res)
|
||||
end
|
||||
|
||||
execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
do
|
||||
check should_not_occur: False end
|
||||
end
|
||||
|
||||
feature {NONE} -- Routing
|
||||
|
||||
router: REST_REQUEST_URI_TEMPLATE_ROUTER_I [H, C]
|
||||
|
||||
;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 {DEFAULT_URI_TEMPLATE_REST_SERVICE}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
REST_URI_TEMPLATE_SERVICE
|
||||
|
||||
inherit
|
||||
REST_SERVICE_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT], REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT]
|
||||
redefine
|
||||
router
|
||||
end
|
||||
|
||||
feature -- Router
|
||||
|
||||
router: REST_REQUEST_URI_TEMPLATE_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
|
||||
26
draft/library/server/request/rest/tests/htdocs/.htaccess
Normal file
26
draft/library/server/request/rest/tests/htdocs/.htaccess
Normal file
@@ -0,0 +1,26 @@
|
||||
Options Indexes FollowSymLinks ExecCGI
|
||||
|
||||
<IfModule mod_fcgid.c>
|
||||
AddHandler fcgid-script .eapp
|
||||
FcgidWrapper c:/_dev/Dev-Process/web-framework/library/server/request/rest/tests/htdocs/../EIFGENs/rest_sample_cgi/W_code/sample.exe .eapp
|
||||
|
||||
</IfModule>
|
||||
|
||||
Options +ExecCGI
|
||||
AddHandler cgi-script exe
|
||||
|
||||
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine on
|
||||
RewriteBase /REST
|
||||
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_URI} !=/favicon.ico
|
||||
RewriteRule ^(.*)$ sample.eapp/$1
|
||||
|
||||
# To let CGI app knows about HTTP_AUTHORIZATION
|
||||
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
|
||||
|
||||
</IfModule>
|
||||
31
draft/library/server/request/rest/tests/htdocs/README.txt
Normal file
31
draft/library/server/request/rest/tests/htdocs/README.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
= How to make this works with Apache =
|
||||
* In the apache's configuration file, be sure to add the following, or similar
|
||||
LoadModule fcgid_module modules/mod_fcgid.so
|
||||
<IfModule mod_fcgid.c>
|
||||
FcgidIdleTimeout 60
|
||||
FcgidBusyScanInterval 120
|
||||
FcgidProcessLifeTime 1600
|
||||
#7200
|
||||
FcgidMaxProcesses 5
|
||||
FcgidMaxProcessesPerClass 100
|
||||
FcgidMinProcessesPerClass 100
|
||||
FcgidConnectTimeout 8
|
||||
FcgidIOTimeout 3000
|
||||
FcgidBusyTimeout 3200
|
||||
FcgidMaxRequestLen 10000000
|
||||
FcgidPassHeader Authorization
|
||||
</IfModule>
|
||||
|
||||
|
||||
alias /REST/ "c:/_dev/Dev-Process/src/server/htdocs/"
|
||||
<directory "c:/_dev/Dev-Process/src/server/htdocs/">
|
||||
AllowOverride All
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</directory>
|
||||
|
||||
* You can use <Location>, but then the AllowOverride All, should be somewhere else, since <Location> does not allow it.
|
||||
|
||||
* And then, check the .htaccess from this folder for additional settings (but required)
|
||||
|
||||
|
||||
24
draft/library/server/request/rest/tests/htdocs/build.eant
Normal file
24
draft/library/server/request/rest/tests/htdocs/build.eant
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<project name="update_htdocs" default="menu">
|
||||
|
||||
<target name="menu">
|
||||
<echo message="1 - update_cgi_link" />
|
||||
<echo message="2 - update_htaccess" />
|
||||
<echo message="0 - quit" />
|
||||
<input message="Your choice :" variable="answer" defaultvalue="0" validargs="1,2,0" answer_required="true" />
|
||||
<geant target="update_cgi_link" if="$answer=1" />
|
||||
<geant target="update_htaccess" if="$answer=2" />
|
||||
</target>
|
||||
|
||||
<target name="update_cgi_link">
|
||||
<echo message="Update CGI link" />
|
||||
<exec executable="junction CGI ..\EIFGENs\rest_sample_cgi\W_code" accept_errors="true" exit_code_variable="return_code" dir="$cwd" />
|
||||
</target>
|
||||
|
||||
<target name="update_htaccess">
|
||||
<replace file="htaccess" to_file=".htaccess" token="##SAMPLE-CGI-DIR##" replace="$cwd/../EIFGENs/rest_sample_cgi/W_code" flags="g" />
|
||||
<replace file=".htaccess" to_file=".htaccess" token="\" replace="/" flags="g" />
|
||||
</target>
|
||||
|
||||
</project>
|
||||
26
draft/library/server/request/rest/tests/htdocs/htaccess
Normal file
26
draft/library/server/request/rest/tests/htdocs/htaccess
Normal file
@@ -0,0 +1,26 @@
|
||||
Options Indexes FollowSymLinks ExecCGI
|
||||
|
||||
<IfModule mod_fcgid.c>
|
||||
AddHandler fcgid-script .eapp
|
||||
FcgidWrapper ##SAMPLE-CGI-DIR##/sample.exe .eapp
|
||||
|
||||
</IfModule>
|
||||
|
||||
Options +ExecCGI
|
||||
AddHandler cgi-script exe
|
||||
|
||||
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine on
|
||||
RewriteBase /REST
|
||||
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_URI} !=/favicon.ico
|
||||
RewriteRule ^(.*)$ sample.eapp/$1
|
||||
|
||||
# To let CGI app knows about HTTP_AUTHORIZATION
|
||||
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
|
||||
|
||||
</IfModule>
|
||||
55
draft/library/server/request/rest/tests/sample.ecf
Normal file
55
draft/library/server/request/rest/tests/sample.ecf
Normal file
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="common" uuid="4E02DF53-9DF0-44B6-B8A8-7554E0B94957">
|
||||
<target name="common">
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option cat_call_detection="false" is_attached_by_default="true" void_safety="all" syntax="provisional">
|
||||
</option>
|
||||
<setting name="console_application" value="true"/>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="rest" location="..\rest-safe.ecf" readonly="false"/>
|
||||
<library name="wsf" location="..\..\..\wsf\wsf-safe.ecf" readonly="false"/>
|
||||
<library name="http" location="..\..\..\..\protocol\http\http-safe.ecf" readonly="false"/>
|
||||
</target>
|
||||
<target name="sample_fcgi" extends="common">
|
||||
<root class="APP_SERVER" feature="make"/>
|
||||
<setting name="executable_name" value="sample"/>
|
||||
<library name="ewsgi_fcgi" location="..\..\..\ewsgi\connectors\libfcgi\libfcgi-safe.ecf" readonly="false"/>
|
||||
<cluster name="src" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/gateway$</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
<cluster name="gateway" location=".\src\gateway\fcgi\" recursive="true"/>
|
||||
</target>
|
||||
<target name="sample_cgi" extends="common">
|
||||
<root class="APP_SERVER" feature="make"/>
|
||||
<setting name="executable_name" value="sample"/>
|
||||
<library name="ewsgi_cgi" location="..\..\..\ewsgi\connectors\cgi\cgi-safe.ecf" readonly="false"/>
|
||||
<cluster name="src" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/gateway$</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
<cluster name="gateway" location=".\src\gateway\cgi\" recursive="true"/>
|
||||
|
||||
</target>
|
||||
<target name="sample_nino" extends="common">
|
||||
<root class="APP_SERVER" feature="make"/>
|
||||
<setting name="executable_name" value="sample"/>
|
||||
<library name="ewsgi_nino" location="..\..\..\ewsgi\connectors\nino\nino-safe.ecf" readonly="false"/>
|
||||
<library name="default_nino" location="..\..\..\wsf\default\nino-safe.ecf" readonly="false"/>
|
||||
|
||||
|
||||
<cluster name="src" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/gateway$</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
<cluster name="gateway" location=".\src\gateway\nino\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
@@ -0,0 +1,112 @@
|
||||
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 (req: WSF_REQUEST): BOOLEAN
|
||||
do
|
||||
Result := True
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute_unauthorized (a_hdl_context: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
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: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
l_full: BOOLEAN
|
||||
h: WSF_HEADER
|
||||
l_login: STRING_8
|
||||
s: STRING
|
||||
content_type_supported: ARRAY [STRING]
|
||||
l_format_id: INTEGER
|
||||
do
|
||||
content_type_supported := <<{HTTP_CONSTANTS}.application_json, {HTTP_CONSTANTS}.text_xml, {HTTP_CONSTANTS}.text_plain>>
|
||||
l_format_id := ctx.request_format_id ("format", content_type_supported)
|
||||
if authenticated (ctx) then
|
||||
l_full := attached ctx.query_parameter ("details") as v and then v.is_case_insensitive_equal ("true")
|
||||
if attached authenticated_identifier (ctx) 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
|
||||
97
draft/library/server/request/rest/tests/src/app/app_test.e
Normal file
97
draft/library/server/request/rest/tests/src/app/app_test.e
Normal file
@@ -0,0 +1,97 @@
|
||||
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 (req: WSF_REQUEST): BOOLEAN
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
local
|
||||
s: STRING
|
||||
h: WSF_HEADER
|
||||
do
|
||||
create h.make
|
||||
h.put_content_type_text_plain
|
||||
|
||||
create s.make_empty
|
||||
s.append_string ("test")
|
||||
if attached {WSF_STRING} req.meta_variable ("REQUEST_COUNT") as l_request_count_val then
|
||||
s.append_string ("(request_count="+ l_request_count_val.string +")%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.string_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 (wgi_value_iteration_to_string (req.items, 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 authenticated (ctx) and then attached authenticated_identifier (ctx) 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
|
||||
150
draft/library/server/request/rest/tests/src/app_server.e
Normal file
150
draft/library/server/request/rest/tests/src/app_server.e
Normal file
@@ -0,0 +1,150 @@
|
||||
note
|
||||
description: "Summary description for {APP_SERVER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
APP_SERVER
|
||||
|
||||
inherit
|
||||
APP_SERVICE
|
||||
redefine
|
||||
execute
|
||||
end
|
||||
|
||||
REST_SERVICE_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: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
do
|
||||
request_count := request_count + 1
|
||||
Precursor (req, res)
|
||||
end
|
||||
|
||||
execute_default (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
rqst_uri: detachable STRING
|
||||
l_path_info: detachable STRING
|
||||
h: WSF_HEADER
|
||||
s: STRING
|
||||
l_redir_url: STRING
|
||||
do
|
||||
create h.make
|
||||
-- h.put_refresh (ctx.script_url ("/doc"), 2)
|
||||
l_redir_url := "/doc"
|
||||
h.put_refresh (l_redir_url, 2)
|
||||
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 ({HTTP_STATUS_CODE}.temp_redirect)
|
||||
res.write_headers_string (h.string)
|
||||
res.write_string (s)
|
||||
end
|
||||
|
||||
request_count: INTEGER
|
||||
|
||||
-- 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: WSF_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: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
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_SERVICE_GATEWAY
|
||||
|
||||
inherit
|
||||
WSF_SERVICE
|
||||
|
||||
feature -- Access
|
||||
|
||||
build_gateway_and_launch
|
||||
local
|
||||
cgi: WGI_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_SERVICE_GATEWAY
|
||||
|
||||
inherit
|
||||
WSF_SERVICE
|
||||
|
||||
feature -- Access
|
||||
|
||||
build_gateway_and_launch
|
||||
local
|
||||
libfcgi: WGI_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_SERVICE_GATEWAY
|
||||
|
||||
inherit
|
||||
WSF_SERVICE
|
||||
|
||||
feature -- Access
|
||||
|
||||
build_gateway_and_launch
|
||||
local
|
||||
app: NINO_SERVICE
|
||||
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 wgi_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,35 @@
|
||||
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]
|
||||
undefine
|
||||
authenticated
|
||||
end
|
||||
|
||||
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,85 @@
|
||||
note
|
||||
description : "Objects that ..."
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
deferred class
|
||||
APP_REQUEST_HANDLER
|
||||
|
||||
inherit
|
||||
REST_REQUEST_HANDLER [APP_REQUEST_HANDLER_CONTEXT]
|
||||
redefine
|
||||
authenticated
|
||||
end
|
||||
|
||||
APP_REQUEST_HELPER
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
initialize
|
||||
-- Initialize various attributes
|
||||
do
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
wgi_value_iteration_to_string (v: ITERABLE [WSF_VALUE]; using_pre: BOOLEAN): STRING_8
|
||||
do
|
||||
create Result.make (100)
|
||||
if using_pre then
|
||||
Result.append ("<pre>")
|
||||
end
|
||||
across
|
||||
v as cur
|
||||
loop
|
||||
Result.append_string (cur.item.name.as_string_8 + " = " + cur.item.string_representation.as_string_8 + "%N")
|
||||
end
|
||||
if using_pre then
|
||||
Result.append ("</pre>")
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Auth
|
||||
|
||||
authenticated (ctx: APP_REQUEST_HANDLER_CONTEXT): BOOLEAN
|
||||
-- Is authenticated?
|
||||
do
|
||||
--| To redefine if needed
|
||||
if attached ctx.request.http_authorization as l_http_authorization then
|
||||
Result := True
|
||||
end
|
||||
end
|
||||
|
||||
authenticated_identifier (ctx: APP_REQUEST_HANDLER_CONTEXT): detachable READABLE_STRING_32
|
||||
do
|
||||
if attached ctx.request.http_authorization as l_http_authorization then
|
||||
Result := "foo" -- Implement it as you want
|
||||
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,67 @@
|
||||
note
|
||||
description : "Objects that ..."
|
||||
author : "$Author$"
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
class
|
||||
APP_REQUEST_HANDLER_CONTEXT
|
||||
|
||||
inherit
|
||||
REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
|
||||
feature -- Format
|
||||
|
||||
get_format_id (a_format_variable_name: detachable READABLE_STRING_8; 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_8; 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: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
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_I [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,42 @@
|
||||
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
|
||||
end
|
||||
|
||||
REST_REQUEST_URI_TEMPLATE_ROUTING_HANDLER_I [APP_REQUEST_HANDLER, APP_REQUEST_HANDLER_CONTEXT]
|
||||
undefine
|
||||
authenticated,
|
||||
pre_execute,
|
||||
post_execute
|
||||
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
|
||||
@@ -0,0 +1,30 @@
|
||||
note
|
||||
description: "Summary description for {APP_SERVICE}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
APP_SERVICE
|
||||
|
||||
inherit
|
||||
REST_SERVICE_I [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
|
||||
Reference in New Issue
Block a user