Adopted convention name and value or values for WSF_VALUE and descendant (WSF_STRING ...)
kept `key' as redirection, and also string as obsolete redirection. Router: provide a way to pass the request methods without using manifest string, thanks to WSF_ROUTER_METHODS so instead of using manifest array or manifest strings, just create an instance of WSF_ROUTER_METHODS for convenience, WSF_ROUTER provides a few `methods_...' returning prebuilt WSF_ROUTER_METHODS objects Improved code related to unicode handling in URL, and parameters (before the framework was doing too much)
This commit is contained in:
@@ -30,11 +30,10 @@ feature {NONE} -- Initialization
|
|||||||
do
|
do
|
||||||
router.map_agent ("/hello", agent execute_hello)
|
router.map_agent ("/hello", agent execute_hello)
|
||||||
|
|
||||||
|
router.map_with_request_methods ("/users/{user}/message/{mesgid}", create {USER_MESSAGE_HANDLER}, router.methods_GET_POST)
|
||||||
|
router.map_with_request_methods ("/users/{user}/message/", create {USER_MESSAGE_HANDLER}, router.methods_GET_POST)
|
||||||
|
|
||||||
router.map_with_request_methods ("/users/{user}/message/{mesgid}", create {USER_MESSAGE_HANDLER}, <<"GET", "POST">>)
|
router.map_agent_response_with_request_methods ("/users/{user}/{?op}", agent response_user, router.methods_GET)
|
||||||
router.map_with_request_methods ("/users/{user}/message/", create {USER_MESSAGE_HANDLER}, <<"GET", "POST">>)
|
|
||||||
|
|
||||||
router.map_agent_response_with_request_methods ("/users/{user}/{?op}", agent response_user, <<"GET">>)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Execution
|
feature -- Execution
|
||||||
@@ -50,6 +49,7 @@ feature -- Execution
|
|||||||
local
|
local
|
||||||
mesg: WSF_HTML_PAGE_RESPONSE
|
mesg: WSF_HTML_PAGE_RESPONSE
|
||||||
s: STRING_8
|
s: STRING_8
|
||||||
|
l_user_name: READABLE_STRING_32
|
||||||
do
|
do
|
||||||
--| It is now returning a WSF_HTML_PAGE_RESPONSE
|
--| It is now returning a WSF_HTML_PAGE_RESPONSE
|
||||||
--| Since it is easier for building html page
|
--| Since it is easier for building html page
|
||||||
@@ -59,9 +59,12 @@ feature -- Execution
|
|||||||
--| this could be a query, or a form parameter
|
--| this could be a query, or a form parameter
|
||||||
if attached {WSF_STRING} req.item ("user") as u then
|
if attached {WSF_STRING} req.item ("user") as u then
|
||||||
--| If yes, say hello world #name
|
--| If yes, say hello world #name
|
||||||
s := "<p>Hello " + u.html_encoded_string + "!</p>"
|
|
||||||
s.append ("Display a <a href=%"/users/" + u.url_encoded_string + "/message/%">message</a></p>")
|
l_user_name := (create {HTML_ENCODER}).decoded_string (u.value)
|
||||||
s.append ("<p>Click <a href=%"/users/" + u.url_encoded_string + "/?op=quit%">here</a> to quit.</p>")
|
|
||||||
|
s := "<p>Hello " + mesg.html_encoded_string (l_user_name) + "!</p>"
|
||||||
|
s.append ("Display a <a href=%"/users/" + u.url_encoded_value + "/message/%">message</a></p>")
|
||||||
|
s.append ("<p>Click <a href=%"/users/" + u.url_encoded_value + "/?op=quit%">here</a> to quit.</p>")
|
||||||
mesg.set_body (s)
|
mesg.set_body (s)
|
||||||
--| We should html encode this name
|
--| We should html encode this name
|
||||||
--| but to keep the example simple, we don't do that for now.
|
--| but to keep the example simple, we don't do that for now.
|
||||||
@@ -69,7 +72,7 @@ feature -- Execution
|
|||||||
--| Otherwise, ask for name
|
--| Otherwise, ask for name
|
||||||
s := (create {HTML_ENCODER}).encoded_string ({STRING_32} "Hello / ahoj / नमस्ते / Ciào / مرحبا / Hola / 你好 / Hallo / Selam / Bonjour ")
|
s := (create {HTML_ENCODER}).encoded_string ({STRING_32} "Hello / ahoj / नमस्ते / Ciào / مرحبا / Hola / 你好 / Hallo / Selam / Bonjour ")
|
||||||
s.append ("[
|
s.append ("[
|
||||||
<form action="/hello" method="POST">
|
<form action="/hello" method="GET">
|
||||||
What is your name?</p>
|
What is your name?</p>
|
||||||
<input type="text" name="user"/>
|
<input type="text" name="user"/>
|
||||||
<input type="submit" value="Validate"/>
|
<input type="submit" value="Validate"/>
|
||||||
@@ -96,30 +99,33 @@ feature -- Execution
|
|||||||
html: WSF_HTML_PAGE_RESPONSE
|
html: WSF_HTML_PAGE_RESPONSE
|
||||||
redir: WSF_HTML_DELAYED_REDIRECTION_RESPONSE
|
redir: WSF_HTML_DELAYED_REDIRECTION_RESPONSE
|
||||||
s: STRING_8
|
s: STRING_8
|
||||||
|
l_username: STRING_32
|
||||||
do
|
do
|
||||||
if attached {WSF_STRING} ctx.path_parameter ("user") as u then
|
if attached {WSF_STRING} ctx.path_parameter ("user") as u then
|
||||||
|
l_username := (create {HTML_ENCODER}).general_decoded_string (u.value)
|
||||||
if
|
if
|
||||||
attached {WSF_STRING} req.query_parameter ("op") as l_op
|
attached {WSF_STRING} req.query_parameter ("op") as l_op
|
||||||
then
|
then
|
||||||
if l_op.is_case_insensitive_equal ("quit") then
|
if l_op.is_case_insensitive_equal ("quit") then
|
||||||
create redir.make (req.script_url ("/hello"), 5)
|
create redir.make (req.script_url ("/hello"), 5)
|
||||||
redir.set_title ("Bye " + u.url_encoded_string)
|
redir.set_title ("Bye " + u.url_encoded_value)
|
||||||
redir.set_body ("Bye " + u.url_encoded_string + ",<br/> see you soon.<p>You will be redirected to " +
|
redir.set_body ("Bye " + u.url_encoded_value + ",<br/> see you soon.<p>You will be redirected to " +
|
||||||
redir.url_location + " in " + redir.delay.out + " second(s) ...</p>"
|
redir.url_location + " in " + redir.delay.out + " second(s) ...</p>"
|
||||||
)
|
)
|
||||||
Result := redir
|
Result := redir
|
||||||
else
|
else
|
||||||
create html.make
|
create html.make
|
||||||
html.set_title ("Bad request")
|
html.set_title ("Bad request")
|
||||||
html.set_body ("Bad request: unknown operation '" + l_op.url_encoded_string + "'.")
|
html.set_body ("Bad request: unknown operation '" + l_op.url_encoded_value + "'.")
|
||||||
Result := html
|
Result := html
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
s := "<p>User <em>'" + u.url_encoded_string + "'</em>!</p>"
|
|
||||||
s.append ("Display a <a href=%"/users/" + u.url_encoded_string + "/message/%">message</a></p>")
|
|
||||||
s.append ("<p>Click <a href=%"/users/" + u.url_encoded_string + "/?op=quit%">here</a> to quit.</p>")
|
|
||||||
create html.make
|
create html.make
|
||||||
html.set_title ("User '" + u.url_encoded_string + "'")
|
|
||||||
|
s := "<p>User <em>'" + html.html_encoded_string (l_username) + "'</em>!</p>"
|
||||||
|
s.append ("Display a <a href=%"/users/" + u.url_encoded_value + "/message/%">message</a></p>")
|
||||||
|
s.append ("<p>Click <a href=%"/users/" + u.url_encoded_value + "/?op=quit%">here</a> to quit.</p>")
|
||||||
|
html.set_title ("User '" + u.url_encoded_value + "'")
|
||||||
html.set_body (s)
|
html.set_body (s)
|
||||||
Result := html
|
Result := html
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -14,12 +14,15 @@ inherit
|
|||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
response (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_RESPONSE_MESSAGE
|
response (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_RESPONSE_MESSAGE
|
||||||
|
local
|
||||||
|
l_username: READABLE_STRING_32
|
||||||
do
|
do
|
||||||
if attached {WSF_STRING} ctx.path_parameter ("user") as u then
|
if attached {WSF_STRING} ctx.path_parameter ("user") as u then
|
||||||
|
l_username := html_decoded_string (u.value)
|
||||||
if req.is_request_method ("GET") then
|
if req.is_request_method ("GET") then
|
||||||
Result := user_message_get (u, ctx, req)
|
Result := user_message_get (l_username, ctx, req)
|
||||||
elseif req.is_request_method ("POST") then
|
elseif req.is_request_method ("POST") then
|
||||||
Result := user_message_response_post (u, ctx, req)
|
Result := user_message_response_post (l_username, ctx, req)
|
||||||
else
|
else
|
||||||
Result := unsupported_method_response (req)
|
Result := unsupported_method_response (req)
|
||||||
end
|
end
|
||||||
@@ -43,12 +46,12 @@ feature -- Access
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
user_message_get (u: WSF_STRING; ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_HTML_PAGE_RESPONSE
|
user_message_get (u: READABLE_STRING_32; ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_HTML_PAGE_RESPONSE
|
||||||
local
|
local
|
||||||
s: STRING_8
|
s: STRING_8
|
||||||
do
|
do
|
||||||
create Result.make
|
create Result.make
|
||||||
s := "<p>No message from user '" + u.html_encoded_string + "'.</p>"
|
s := "<p>No message from user '" + Result.html_encoded_string (u) + "'.</p>"
|
||||||
s.append ("<form action=%""+ req.request_uri +"%" method=%"POST%">")
|
s.append ("<form action=%""+ req.request_uri +"%" method=%"POST%">")
|
||||||
s.append ("<textarea name=%"message%" rows=%"10%" cols=%"70%" ></textarea>")
|
s.append ("<textarea name=%"message%" rows=%"10%" cols=%"70%" ></textarea>")
|
||||||
s.append ("<input type=%"submit%" value=%"Ok%" />")
|
s.append ("<input type=%"submit%" value=%"Ok%" />")
|
||||||
@@ -56,18 +59,32 @@ feature -- Access
|
|||||||
Result.set_body (s)
|
Result.set_body (s)
|
||||||
end
|
end
|
||||||
|
|
||||||
user_message_response_post (u: WSF_STRING; ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_HTML_PAGE_RESPONSE
|
user_message_response_post (u: READABLE_STRING_32; ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_HTML_PAGE_RESPONSE
|
||||||
local
|
local
|
||||||
s: STRING_8
|
s: STRING_8
|
||||||
do
|
do
|
||||||
create Result.make
|
create Result.make
|
||||||
s := "<p>Message from user '<a href=%"/users/" + u.url_encoded_string + "/%">" + u.html_encoded_string + "</a>'.</p>"
|
s := "<p>Message from user '<a href=%"/users/" + url_encoded_string (u) + "/%">" + Result.html_encoded_string (u) + "</a>'.</p>"
|
||||||
if attached {WSF_STRING} req.form_parameter ("message") as m and then not m.is_empty then
|
if attached {WSF_STRING} req.form_parameter ("message") as m and then not m.is_empty then
|
||||||
s.append ("<textarea>"+ m.string +"</textarea>")
|
s.append ("<textarea>"+ m.value +"</textarea>")
|
||||||
else
|
else
|
||||||
s.append ("<strong>No or empty message!</strong>")
|
s.append ("<strong>No or empty message!</strong>")
|
||||||
end
|
end
|
||||||
Result.set_body (s)
|
Result.set_body (s)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
url_encoded_string (s: READABLE_STRING_32): STRING_8
|
||||||
|
do
|
||||||
|
Result := (create {UTF8_URL_ENCODER}).encoded_string (s)
|
||||||
|
end
|
||||||
|
|
||||||
|
html_decoded_string (v: READABLE_STRING_32): READABLE_STRING_32
|
||||||
|
do
|
||||||
|
if v.is_valid_as_string_8 then
|
||||||
|
Result := (create {HTML_ENCODER}).decoded_string (v)
|
||||||
|
else
|
||||||
|
Result := v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -13,6 +13,35 @@ note
|
|||||||
class
|
class
|
||||||
HTTP_REQUEST_METHODS
|
HTTP_REQUEST_METHODS
|
||||||
|
|
||||||
|
feature -- Query
|
||||||
|
|
||||||
|
method (m: READABLE_STRING_8): READABLE_STRING_8
|
||||||
|
-- Return the associated constant object if any
|
||||||
|
-- otherwise the uppercased version of `m'
|
||||||
|
do
|
||||||
|
if m.is_case_insensitive_equal (method_get) then
|
||||||
|
Result := method_get
|
||||||
|
elseif m.is_case_insensitive_equal (method_post) then
|
||||||
|
Result := method_post
|
||||||
|
elseif m.is_case_insensitive_equal (method_head) then
|
||||||
|
Result := method_head
|
||||||
|
elseif m.is_case_insensitive_equal (method_trace) then
|
||||||
|
Result := method_trace
|
||||||
|
elseif m.is_case_insensitive_equal (method_options) then
|
||||||
|
Result := method_options
|
||||||
|
elseif m.is_case_insensitive_equal (method_put) then
|
||||||
|
Result := method_put
|
||||||
|
elseif m.is_case_insensitive_equal (method_delete) then
|
||||||
|
Result := method_delete
|
||||||
|
elseif m.is_case_insensitive_equal (method_connect) then
|
||||||
|
Result := method_connect
|
||||||
|
elseif m.is_case_insensitive_equal (method_patch) then
|
||||||
|
Result := method_patch
|
||||||
|
else
|
||||||
|
Result := m.as_upper
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Safe Methods
|
feature -- Safe Methods
|
||||||
|
|
||||||
method_head: STRING = "HEAD"
|
method_head: STRING = "HEAD"
|
||||||
@@ -63,7 +92,7 @@ feature -- Other Methods
|
|||||||
-- Is used to apply partial modifications to a resource
|
-- Is used to apply partial modifications to a resource
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2011, Eiffel Software and others"
|
copyright: "2011-2012, Jocelyn Fiat, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
source: "[
|
source: "[
|
||||||
Eiffel Software
|
Eiffel Software
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ create
|
|||||||
feature -- Mapping agent
|
feature -- Mapping agent
|
||||||
|
|
||||||
map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: WSF_URI_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]];
|
map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: WSF_URI_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]];
|
||||||
rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
rqst_methods: detachable WSF_ROUTER_METHODS)
|
||||||
local
|
local
|
||||||
h: WSF_AGENT_HANDLER [WSF_URI_HANDLER_CONTEXT]
|
h: WSF_AGENT_HANDLER [WSF_URI_HANDLER_CONTEXT]
|
||||||
do
|
do
|
||||||
@@ -29,7 +29,7 @@ feature -- Mapping agent
|
|||||||
end
|
end
|
||||||
|
|
||||||
map_agent_response_with_request_methods (a_id: READABLE_STRING_8; a_action: FUNCTION [ANY, TUPLE [ctx: WSF_URI_HANDLER_CONTEXT; req: WSF_REQUEST], WSF_RESPONSE_MESSAGE];
|
map_agent_response_with_request_methods (a_id: READABLE_STRING_8; a_action: FUNCTION [ANY, TUPLE [ctx: WSF_URI_HANDLER_CONTEXT; req: WSF_REQUEST], WSF_RESPONSE_MESSAGE];
|
||||||
rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
rqst_methods: detachable WSF_ROUTER_METHODS)
|
||||||
local
|
local
|
||||||
h: WSF_AGENT_RESPONSE_HANDLER [WSF_URI_HANDLER_CONTEXT]
|
h: WSF_AGENT_RESPONSE_HANDLER [WSF_URI_HANDLER_CONTEXT]
|
||||||
do
|
do
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ feature -- Initialization
|
|||||||
|
|
||||||
feature {WSF_ROUTED_SERVICE_I} -- Status report
|
feature {WSF_ROUTED_SERVICE_I} -- Status report
|
||||||
|
|
||||||
handlers_matching_map (a_resource: READABLE_STRING_8; rqst_methods: detachable ARRAY [READABLE_STRING_8]): detachable LIST [H]
|
handlers_matching_map (a_resource: READABLE_STRING_8; rqst_methods: detachable WSF_ROUTER_METHODS): detachable LIST [H]
|
||||||
local
|
local
|
||||||
l_res: READABLE_STRING_8
|
l_res: READABLE_STRING_8
|
||||||
do
|
do
|
||||||
@@ -79,7 +79,7 @@ feature {WSF_ROUTED_SERVICE_I} -- Default: implementation
|
|||||||
|
|
||||||
feature -- Registration
|
feature -- Registration
|
||||||
|
|
||||||
map_with_request_methods (p: READABLE_STRING_8; h: H; rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
map_with_request_methods (p: READABLE_STRING_8; h: H; rqst_methods: detachable WSF_ROUTER_METHODS)
|
||||||
local
|
local
|
||||||
l_uri: READABLE_STRING_8
|
l_uri: READABLE_STRING_8
|
||||||
do
|
do
|
||||||
@@ -88,7 +88,7 @@ feature -- Registration
|
|||||||
else
|
else
|
||||||
l_uri := p
|
l_uri := p
|
||||||
end
|
end
|
||||||
handlers.force ([h, l_uri, formatted_request_methods (rqst_methods)])
|
handlers.force ([h, l_uri, rqst_methods])
|
||||||
h.on_handler_mapped (l_uri, rqst_methods)
|
h.on_handler_mapped (l_uri, rqst_methods)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -109,10 +109,13 @@ feature {WSF_ROUTED_SERVICE_I} -- Handler
|
|||||||
local
|
local
|
||||||
h: detachable H
|
h: detachable H
|
||||||
ctx: detachable C
|
ctx: detachable C
|
||||||
|
rq_method: READABLE_STRING_8
|
||||||
do
|
do
|
||||||
h := handler_by_path (source_uri (req), req.request_method)
|
rq_method := request_method (req)
|
||||||
|
|
||||||
|
h := handler_by_path (source_uri (req), rq_method)
|
||||||
if h = Void then
|
if h = Void then
|
||||||
if attached smart_handler_by_path (source_uri (req), req.request_method) as info then
|
if attached smart_handler_by_path (source_uri (req), rq_method) as info then
|
||||||
h := info.handler
|
h := info.handler
|
||||||
ctx := handler_context (info.path, req)
|
ctx := handler_context (info.path, req)
|
||||||
end
|
end
|
||||||
@@ -131,16 +134,7 @@ feature {WSF_ROUTED_SERVICE_I} -- Handler
|
|||||||
|
|
||||||
feature {NONE} -- Access: Implementation
|
feature {NONE} -- Access: Implementation
|
||||||
|
|
||||||
smart_handler (req: WSF_REQUEST): detachable TUPLE [path: READABLE_STRING_8; handler: H]
|
handler_by_path (a_path: READABLE_STRING_GENERAL; rqst_method: READABLE_STRING_8): detachable H
|
||||||
require
|
|
||||||
req_valid: req /= Void and then source_uri (req) /= Void
|
|
||||||
do
|
|
||||||
Result := smart_handler_by_path (source_uri (req), req.request_method)
|
|
||||||
ensure
|
|
||||||
req_path_info_unchanged: source_uri (req).same_string (old source_uri (req))
|
|
||||||
end
|
|
||||||
|
|
||||||
handler_by_path (a_path: READABLE_STRING_GENERAL; rqst_method: READABLE_STRING_GENERAL): detachable H
|
|
||||||
require
|
require
|
||||||
a_path_valid: a_path /= Void
|
a_path_valid: a_path /= Void
|
||||||
local
|
local
|
||||||
@@ -163,7 +157,7 @@ feature {NONE} -- Access: Implementation
|
|||||||
a_path_unchanged: a_path.same_string (old a_path)
|
a_path_unchanged: a_path.same_string (old a_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
smart_handler_by_path (a_path: READABLE_STRING_8; rqst_method: READABLE_STRING_GENERAL): detachable TUPLE [path: READABLE_STRING_8; handler: H]
|
smart_handler_by_path (a_path: READABLE_STRING_8; rqst_method: READABLE_STRING_8): detachable TUPLE [path: READABLE_STRING_8; handler: H]
|
||||||
require
|
require
|
||||||
a_path_valid: a_path /= Void
|
a_path_valid: a_path /= Void
|
||||||
local
|
local
|
||||||
@@ -207,7 +201,7 @@ feature {NONE} -- Context factory
|
|||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
new_cursor: ITERATION_CURSOR [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable ARRAY [READABLE_STRING_8]]]
|
new_cursor: ITERATION_CURSOR [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable WSF_ROUTER_METHODS]]
|
||||||
-- Fresh cursor associated with current structure
|
-- Fresh cursor associated with current structure
|
||||||
do
|
do
|
||||||
Result := handlers.new_cursor
|
Result := handlers.new_cursor
|
||||||
@@ -215,7 +209,7 @@ feature -- Access
|
|||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
handlers: ARRAYED_LIST [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable ARRAY [READABLE_STRING_8]]]
|
handlers: ARRAYED_LIST [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable WSF_ROUTER_METHODS]]
|
||||||
-- Handlers indexed by the template expression
|
-- Handlers indexed by the template expression
|
||||||
-- see `templates'
|
-- see `templates'
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ create
|
|||||||
feature -- Mapping agent
|
feature -- Mapping agent
|
||||||
|
|
||||||
map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]];
|
map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]];
|
||||||
rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
rqst_methods: detachable WSF_ROUTER_METHODS)
|
||||||
local
|
local
|
||||||
h: WSF_AGENT_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT]
|
h: WSF_AGENT_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT]
|
||||||
do
|
do
|
||||||
@@ -31,7 +31,7 @@ feature -- Mapping agent
|
|||||||
end
|
end
|
||||||
|
|
||||||
map_agent_response_with_request_methods (a_id: READABLE_STRING_8; a_action: FUNCTION [ANY, TUPLE [ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST], WSF_RESPONSE_MESSAGE];
|
map_agent_response_with_request_methods (a_id: READABLE_STRING_8; a_action: FUNCTION [ANY, TUPLE [ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST], WSF_RESPONSE_MESSAGE];
|
||||||
rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
rqst_methods: detachable WSF_ROUTER_METHODS)
|
||||||
local
|
local
|
||||||
h: WSF_AGENT_RESPONSE_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT]
|
h: WSF_AGENT_RESPONSE_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT]
|
||||||
do
|
do
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ feature -- Initialization
|
|||||||
|
|
||||||
feature -- Status report
|
feature -- Status report
|
||||||
|
|
||||||
handlers_matching_map (a_resource: READABLE_STRING_8; rqst_methods: detachable ARRAY [READABLE_STRING_8]): detachable LIST [H]
|
handlers_matching_map (a_resource: READABLE_STRING_8; rqst_methods: detachable WSF_ROUTER_METHODS): detachable LIST [H]
|
||||||
local
|
local
|
||||||
l_res: READABLE_STRING_8
|
l_res: READABLE_STRING_8
|
||||||
do
|
do
|
||||||
@@ -75,7 +75,7 @@ feature -- Registration
|
|||||||
map_with_uri_template_and_request_methods (uri, h, Void)
|
map_with_uri_template_and_request_methods (uri, h, Void)
|
||||||
end
|
end
|
||||||
|
|
||||||
map_with_uri_template_and_request_methods (uri: URI_TEMPLATE; h: H; rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
map_with_uri_template_and_request_methods (uri: URI_TEMPLATE; h: H; rqst_methods: detachable WSF_ROUTER_METHODS)
|
||||||
require
|
require
|
||||||
uri_is_valid: uri.is_valid
|
uri_is_valid: uri.is_valid
|
||||||
has_not_such_map: not has_map (uri.template, rqst_methods, h)
|
has_not_such_map: not has_map (uri.template, rqst_methods, h)
|
||||||
@@ -86,12 +86,12 @@ feature -- Registration
|
|||||||
l_uri := based_uri (uri)
|
l_uri := based_uri (uri)
|
||||||
l_tpl := l_uri.template
|
l_tpl := l_uri.template
|
||||||
|
|
||||||
handlers.force ([h, l_tpl, formatted_request_methods (rqst_methods)])
|
handlers.force ([h, l_tpl, rqst_methods])
|
||||||
templates.force (l_uri, l_tpl)
|
templates.force (l_uri, l_tpl)
|
||||||
h.on_handler_mapped (l_tpl, rqst_methods)
|
h.on_handler_mapped (l_tpl, rqst_methods)
|
||||||
end
|
end
|
||||||
|
|
||||||
map_with_request_methods (tpl: READABLE_STRING_8; h: H; rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
map_with_request_methods (tpl: READABLE_STRING_8; h: H; rqst_methods: detachable WSF_ROUTER_METHODS)
|
||||||
do
|
do
|
||||||
map_with_uri_template_and_request_methods (create {URI_TEMPLATE}.make (tpl), h, rqst_methods)
|
map_with_uri_template_and_request_methods (create {URI_TEMPLATE}.make (tpl), h, rqst_methods)
|
||||||
end
|
end
|
||||||
@@ -124,12 +124,12 @@ feature {WSF_ROUTED_SERVICE_I} -- Handler
|
|||||||
l_handlers: like handlers
|
l_handlers: like handlers
|
||||||
t: READABLE_STRING_8
|
t: READABLE_STRING_8
|
||||||
p: READABLE_STRING_8
|
p: READABLE_STRING_8
|
||||||
l_req_method: READABLE_STRING_GENERAL
|
l_req_method: READABLE_STRING_8
|
||||||
l_res: URI_TEMPLATE_MATCH_RESULT
|
l_res: URI_TEMPLATE_MATCH_RESULT
|
||||||
do
|
do
|
||||||
p := source_uri (req)
|
p := source_uri (req)
|
||||||
from
|
from
|
||||||
l_req_method := req.request_method
|
l_req_method := request_method (req)
|
||||||
l_handlers := handlers
|
l_handlers := handlers
|
||||||
l_handlers.start
|
l_handlers.start
|
||||||
until
|
until
|
||||||
@@ -178,7 +178,7 @@ feature {NONE} -- Context factory
|
|||||||
|
|
||||||
feature -- Access: ITERABLE
|
feature -- Access: ITERABLE
|
||||||
|
|
||||||
new_cursor: ITERATION_CURSOR [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable ARRAY [READABLE_STRING_8]]]
|
new_cursor: ITERATION_CURSOR [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable WSF_ROUTER_METHODS]]
|
||||||
-- Fresh cursor associated with current structure
|
-- Fresh cursor associated with current structure
|
||||||
do
|
do
|
||||||
Result := handlers.new_cursor
|
Result := handlers.new_cursor
|
||||||
@@ -186,7 +186,7 @@ feature -- Access: ITERABLE
|
|||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
handlers: ARRAYED_LIST [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable ARRAY [READABLE_STRING_8]]]
|
handlers: ARRAYED_LIST [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable WSF_ROUTER_METHODS]]
|
||||||
-- Handlers indexed by the template expression
|
-- Handlers indexed by the template expression
|
||||||
-- see `templates'
|
-- see `templates'
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ feature -- Execution
|
|||||||
-- i.e: path of the file system resource if any
|
-- i.e: path of the file system resource if any
|
||||||
do
|
do
|
||||||
if attached {WSF_STRING} ctx.item ("path") as v_path then
|
if attached {WSF_STRING} ctx.item ("path") as v_path then
|
||||||
Result := v_path.string.as_string_8
|
Result := v_path.value.as_string_8
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ feature -- Execution: report
|
|||||||
|
|
||||||
feature {WSF_ROUTER} -- Routes change
|
feature {WSF_ROUTER} -- Routes change
|
||||||
|
|
||||||
on_handler_mapped (a_resource: READABLE_STRING_8; a_rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
on_handler_mapped (a_resource: READABLE_STRING_8; a_rqst_methods: detachable WSF_ROUTER_METHODS)
|
||||||
-- Callback called when a router map a route to Current handler
|
-- Callback called when a router map a route to Current handler
|
||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ deferred class
|
|||||||
WSF_ROUTER [H -> WSF_HANDLER [C], C -> WSF_HANDLER_CONTEXT]
|
WSF_ROUTER [H -> WSF_HANDLER [C], C -> WSF_HANDLER_CONTEXT]
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
ITERABLE [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable ARRAY [READABLE_STRING_8]]]
|
ITERABLE [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable WSF_ROUTER_METHODS]]
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ feature {NONE} -- Initialization
|
|||||||
|
|
||||||
feature -- Status report
|
feature -- Status report
|
||||||
|
|
||||||
has_map (a_resource: READABLE_STRING_8; rqst_methods: detachable ARRAY [READABLE_STRING_8]; a_handler: detachable H): BOOLEAN
|
has_map (a_resource: READABLE_STRING_8; rqst_methods: detachable WSF_ROUTER_METHODS; a_handler: detachable H): BOOLEAN
|
||||||
-- Has a map corresponding to `a_resource' and `rqst_methods' other than `a_handler'?
|
-- Has a map corresponding to `a_resource' and `rqst_methods' other than `a_handler'?
|
||||||
do
|
do
|
||||||
if attached handlers_matching_map (a_resource, rqst_methods) as lst then
|
if attached handlers_matching_map (a_resource, rqst_methods) as lst then
|
||||||
@@ -30,7 +30,7 @@ feature -- Status report
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
handlers_matching_map (a_resource: READABLE_STRING_8; rqst_methods: detachable ARRAY [READABLE_STRING_8]): detachable LIST [H]
|
handlers_matching_map (a_resource: READABLE_STRING_8; rqst_methods: detachable WSF_ROUTER_METHODS): detachable LIST [H]
|
||||||
-- Existing handlers matching map with `a_resource' and `rqst_methods'
|
-- Existing handlers matching map with `a_resource' and `rqst_methods'
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
@@ -53,7 +53,7 @@ feature -- Mapping
|
|||||||
map (a_resource, h)
|
map (a_resource, h)
|
||||||
end
|
end
|
||||||
|
|
||||||
map_with_request_methods (a_resource: READABLE_STRING_8; h: H; rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
map_with_request_methods (a_resource: READABLE_STRING_8; h: H; rqst_methods: detachable WSF_ROUTER_METHODS)
|
||||||
-- Map handler `h' with `a_resource' and `rqst_methods'
|
-- Map handler `h' with `a_resource' and `rqst_methods'
|
||||||
require
|
require
|
||||||
has_not_such_map: not has_map (a_resource, rqst_methods, h)
|
has_not_such_map: not has_map (a_resource, rqst_methods, h)
|
||||||
@@ -69,7 +69,7 @@ feature -- Mapping agent
|
|||||||
end
|
end
|
||||||
|
|
||||||
map_agent_with_request_methods (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]];
|
map_agent_with_request_methods (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]];
|
||||||
rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
rqst_methods: detachable WSF_ROUTER_METHODS)
|
||||||
-- Map `a_action' as an handler with `a_resource' and `rqst_methods'
|
-- Map `a_action' as an handler with `a_resource' and `rqst_methods'
|
||||||
local
|
local
|
||||||
rah: WSF_AGENT_HANDLER [C]
|
rah: WSF_AGENT_HANDLER [C]
|
||||||
@@ -91,7 +91,7 @@ feature -- Mapping response agent
|
|||||||
end
|
end
|
||||||
|
|
||||||
map_agent_response_with_request_methods (a_resource: READABLE_STRING_8; a_function: FUNCTION [ANY, TUPLE [ctx: C; req: WSF_REQUEST], WSF_RESPONSE_MESSAGE];
|
map_agent_response_with_request_methods (a_resource: READABLE_STRING_8; a_function: FUNCTION [ANY, TUPLE [ctx: C; req: WSF_REQUEST], WSF_RESPONSE_MESSAGE];
|
||||||
rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
rqst_methods: detachable WSF_ROUTER_METHODS)
|
||||||
-- Map response as Result `a_function' as an handler with `a_resource' and `rqst_methods'
|
-- Map response as Result `a_function' as an handler with `a_resource' and `rqst_methods'
|
||||||
local
|
local
|
||||||
rah: WSF_AGENT_RESPONSE_HANDLER [C]
|
rah: WSF_AGENT_RESPONSE_HANDLER [C]
|
||||||
@@ -203,7 +203,7 @@ feature -- status report
|
|||||||
|
|
||||||
feature -- Traversing
|
feature -- Traversing
|
||||||
|
|
||||||
new_cursor: ITERATION_CURSOR [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable ARRAY [READABLE_STRING_8]]]
|
new_cursor: ITERATION_CURSOR [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable WSF_ROUTER_METHODS]]
|
||||||
-- Fresh cursor associated with current structure
|
-- Fresh cursor associated with current structure
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
@@ -225,51 +225,108 @@ feature {WSF_ROUTED_SERVICE_I} -- Handler
|
|||||||
source_uri_unchanged: source_uri (req).same_string (old source_uri (req))
|
source_uri_unchanged: source_uri (req).same_string (old source_uri (req))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Request methods helper
|
||||||
|
|
||||||
|
methods_head: WSF_ROUTER_METHODS
|
||||||
|
once ("THREAD")
|
||||||
|
create Result
|
||||||
|
Result.enable_head
|
||||||
|
Result.lock
|
||||||
|
end
|
||||||
|
|
||||||
|
methods_options: WSF_ROUTER_METHODS
|
||||||
|
once ("THREAD")
|
||||||
|
create Result
|
||||||
|
Result.enable_options
|
||||||
|
Result.lock
|
||||||
|
end
|
||||||
|
|
||||||
|
methods_get: WSF_ROUTER_METHODS
|
||||||
|
once ("THREAD")
|
||||||
|
create Result
|
||||||
|
Result.enable_get
|
||||||
|
Result.lock
|
||||||
|
end
|
||||||
|
|
||||||
|
methods_post: WSF_ROUTER_METHODS
|
||||||
|
once ("THREAD")
|
||||||
|
create Result
|
||||||
|
Result.enable_post
|
||||||
|
Result.lock
|
||||||
|
end
|
||||||
|
|
||||||
|
methods_put: WSF_ROUTER_METHODS
|
||||||
|
once ("THREAD")
|
||||||
|
create Result
|
||||||
|
Result.enable_put
|
||||||
|
Result.lock
|
||||||
|
end
|
||||||
|
|
||||||
|
methods_delete: WSF_ROUTER_METHODS
|
||||||
|
once ("THREAD")
|
||||||
|
create Result
|
||||||
|
Result.enable_delete
|
||||||
|
Result.lock
|
||||||
|
end
|
||||||
|
|
||||||
|
methods_get_post: WSF_ROUTER_METHODS
|
||||||
|
once ("THREAD")
|
||||||
|
create Result.make (2)
|
||||||
|
Result.enable_get
|
||||||
|
Result.enable_post
|
||||||
|
Result.lock
|
||||||
|
end
|
||||||
|
|
||||||
|
methods_put_post: WSF_ROUTER_METHODS
|
||||||
|
once ("THREAD")
|
||||||
|
create Result.make (2)
|
||||||
|
Result.enable_put
|
||||||
|
Result.enable_post
|
||||||
|
Result.lock
|
||||||
|
end
|
||||||
|
|
||||||
feature {NONE} -- Access: Implementation
|
feature {NONE} -- Access: Implementation
|
||||||
|
|
||||||
is_matching_request_methods (a_request_method: READABLE_STRING_GENERAL; a_rqst_methods: like formatted_request_methods): BOOLEAN
|
request_method (req: WSF_REQUEST): READABLE_STRING_8
|
||||||
-- `a_request_method' is matching `a_rqst_methods' contents
|
-- Request method from `req' to be used in the router implementation.
|
||||||
local
|
local
|
||||||
i,n: INTEGER
|
m: READABLE_STRING_8
|
||||||
m: READABLE_STRING_GENERAL
|
do
|
||||||
|
m := req.request_method
|
||||||
|
if m.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_get) then
|
||||||
|
Result := {HTTP_REQUEST_METHODS}.method_get
|
||||||
|
elseif m.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_post) then
|
||||||
|
Result := {HTTP_REQUEST_METHODS}.method_post
|
||||||
|
elseif m.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_head) then
|
||||||
|
Result := {HTTP_REQUEST_METHODS}.method_head
|
||||||
|
elseif m.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_trace) then
|
||||||
|
Result := {HTTP_REQUEST_METHODS}.method_trace
|
||||||
|
elseif m.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_options) then
|
||||||
|
Result := {HTTP_REQUEST_METHODS}.method_options
|
||||||
|
elseif m.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_put) then
|
||||||
|
Result := {HTTP_REQUEST_METHODS}.method_put
|
||||||
|
elseif m.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_delete) then
|
||||||
|
Result := {HTTP_REQUEST_METHODS}.method_delete
|
||||||
|
elseif m.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_connect) then
|
||||||
|
Result := {HTTP_REQUEST_METHODS}.method_connect
|
||||||
|
elseif m.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_patch) then
|
||||||
|
Result := {HTTP_REQUEST_METHODS}.method_patch
|
||||||
|
else
|
||||||
|
Result := m.as_upper
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
is_matching_request_methods (a_request_method: READABLE_STRING_8; a_rqst_methods: detachable WSF_ROUTER_METHODS): BOOLEAN
|
||||||
|
-- `a_request_method' is matching `a_rqst_methods' contents
|
||||||
do
|
do
|
||||||
if a_rqst_methods /= Void and then not a_rqst_methods.is_empty then
|
if a_rqst_methods /= Void and then not a_rqst_methods.is_empty then
|
||||||
m := a_request_method
|
Result := a_rqst_methods.has (a_request_method)
|
||||||
from
|
|
||||||
i := a_rqst_methods.lower
|
|
||||||
n := a_rqst_methods.upper
|
|
||||||
until
|
|
||||||
i > n or Result
|
|
||||||
loop
|
|
||||||
Result := m.same_string (a_rqst_methods [i])
|
|
||||||
i := i + 1
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
Result := True
|
Result := True
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
formatted_request_methods (rqst_methods: like formatted_request_methods): detachable ARRAY [READABLE_STRING_8]
|
note
|
||||||
-- Formatted request methods values
|
|
||||||
local
|
|
||||||
i,l,u: INTEGER
|
|
||||||
do
|
|
||||||
if rqst_methods /= Void and then not rqst_methods.is_empty then
|
|
||||||
l := rqst_methods.lower
|
|
||||||
u := rqst_methods.upper
|
|
||||||
create Result.make_filled (rqst_methods[l], l, u)
|
|
||||||
from
|
|
||||||
i := l + 1
|
|
||||||
until
|
|
||||||
i > u
|
|
||||||
loop
|
|
||||||
Result[i] := rqst_methods[i].as_string_8.as_upper
|
|
||||||
i := i + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
;note
|
|
||||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
source: "[
|
source: "[
|
||||||
|
|||||||
402
library/server/wsf/router/wsf_router_methods.e
Normal file
402
library/server/wsf/router/wsf_router_methods.e
Normal file
@@ -0,0 +1,402 @@
|
|||||||
|
note
|
||||||
|
description: "[
|
||||||
|
Object that is use in relation with WSF_ROUTER, to precise which request methods is accepted.
|
||||||
|
For convenience, `make_from_iterable' is available, so that you can use <<"GET", "POST">> for instance
|
||||||
|
but remember manifest string are evil ...
|
||||||
|
Since in HTTP you can use your own custom request method, this is not possible to catch any typo
|
||||||
|
( for instance if you write "POST" instead of "P0ST" this is hard to find the error,
|
||||||
|
but in one case it uses upper "o" and in the other case this is zero "0"
|
||||||
|
)
|
||||||
|
|
||||||
|
The recommanded way to use is for instance
|
||||||
|
create {WSF_ROUTER_METHODS}.make_get_post
|
||||||
|
create methods; methods.enable_get; methods.enable_post
|
||||||
|
|
||||||
|
This sounds heavy, but this is much safer.
|
||||||
|
|
||||||
|
( note: in addition internally this first checks using reference comparison
|
||||||
|
and then compare string value, so it brings optimization for accepted request methods.
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
WSF_ROUTER_METHODS
|
||||||
|
|
||||||
|
inherit
|
||||||
|
ITERABLE [READABLE_STRING_8]
|
||||||
|
redefine
|
||||||
|
default_create
|
||||||
|
end
|
||||||
|
|
||||||
|
HTTP_REQUEST_METHODS
|
||||||
|
redefine
|
||||||
|
default_create
|
||||||
|
end
|
||||||
|
|
||||||
|
create
|
||||||
|
default_create,
|
||||||
|
make,
|
||||||
|
make_from_iterable,
|
||||||
|
make_from_string
|
||||||
|
|
||||||
|
convert
|
||||||
|
to_array: {ARRAY [READABLE_STRING_8]},
|
||||||
|
make_from_iterable ({ITERABLE [READABLE_STRING_8], ITERABLE [STRING_8], ARRAY [READABLE_STRING_8], ARRAY [STRING_8]}),
|
||||||
|
make_from_string ({READABLE_STRING_8, STRING_8})
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
default_create
|
||||||
|
do
|
||||||
|
Precursor
|
||||||
|
make (1)
|
||||||
|
end
|
||||||
|
|
||||||
|
make (n: INTEGER)
|
||||||
|
do
|
||||||
|
create methods.make (n)
|
||||||
|
end
|
||||||
|
|
||||||
|
make_from_iterable (v: ITERABLE [READABLE_STRING_8])
|
||||||
|
do
|
||||||
|
make (1)
|
||||||
|
across
|
||||||
|
v as vc
|
||||||
|
loop
|
||||||
|
smart_add_method (vc.item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
make_from_string (v: READABLE_STRING_8)
|
||||||
|
do
|
||||||
|
make_from_iterable (v.split (','))
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
is_locked: BOOLEAN
|
||||||
|
-- Is Current locked? And then can not be modified?
|
||||||
|
|
||||||
|
is_empty: BOOLEAN
|
||||||
|
do
|
||||||
|
Result := methods.count = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
has (a_method: READABLE_STRING_8): BOOLEAN
|
||||||
|
-- Has `a_method' enabled?
|
||||||
|
require
|
||||||
|
a_method_is_uppercase: a_method.same_string (a_method.as_upper)
|
||||||
|
do
|
||||||
|
-- First look for string object itself,
|
||||||
|
-- in case `a_method' comes from one of the HTTP_REQUEST_METHODS constants
|
||||||
|
Result := across methods as c some c.item = a_method end
|
||||||
|
if not Result then
|
||||||
|
-- If not found, look for the same string value
|
||||||
|
Result := across methods as c some c.item.same_string_general (a_method) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
new_cursor: ITERATION_CURSOR [READABLE_STRING_8]
|
||||||
|
-- Fresh cursor associated with current structure
|
||||||
|
do
|
||||||
|
Result := methods.new_cursor
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status change
|
||||||
|
|
||||||
|
lock
|
||||||
|
-- Lock current and prevent any change in methods
|
||||||
|
-- Once it is locked, it is impossible to unlock.
|
||||||
|
do
|
||||||
|
is_locked := True
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Element change
|
||||||
|
|
||||||
|
enable_get
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
get_disabled: not has (method_get)
|
||||||
|
do
|
||||||
|
methods.extend (method_get)
|
||||||
|
ensure
|
||||||
|
get_enabled: has (method_get)
|
||||||
|
end
|
||||||
|
|
||||||
|
disable_get
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
get_enabled: has (method_get)
|
||||||
|
do
|
||||||
|
prune_method (method_get)
|
||||||
|
ensure
|
||||||
|
get_disabled: not has (method_get)
|
||||||
|
end
|
||||||
|
|
||||||
|
enable_post
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
post_disabled: not has (method_post)
|
||||||
|
do
|
||||||
|
methods.extend (method_post)
|
||||||
|
ensure
|
||||||
|
post_enabled: has (method_post)
|
||||||
|
end
|
||||||
|
|
||||||
|
disable_post
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
post_enabled: has (method_post)
|
||||||
|
do
|
||||||
|
prune_method (method_post)
|
||||||
|
ensure
|
||||||
|
post_disabled: not has (method_post)
|
||||||
|
end
|
||||||
|
|
||||||
|
enable_put
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
put_disabled: not has (method_put)
|
||||||
|
do
|
||||||
|
methods.extend (method_put)
|
||||||
|
ensure
|
||||||
|
put_enabled: has (method_put)
|
||||||
|
end
|
||||||
|
|
||||||
|
disable_put
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
put_enabled: has (method_put)
|
||||||
|
do
|
||||||
|
prune_method (method_put)
|
||||||
|
ensure
|
||||||
|
put_disabled: not has (method_put)
|
||||||
|
end
|
||||||
|
|
||||||
|
enable_delete
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
delete_disabled: not has (method_delete)
|
||||||
|
do
|
||||||
|
methods.extend (method_delete)
|
||||||
|
ensure
|
||||||
|
delete_enabled: has (method_delete)
|
||||||
|
end
|
||||||
|
|
||||||
|
disable_delete
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
delete_enabled: has (method_delete)
|
||||||
|
do
|
||||||
|
prune_method (method_delete)
|
||||||
|
ensure
|
||||||
|
delete_disabled: not has (method_delete)
|
||||||
|
end
|
||||||
|
|
||||||
|
enable_options
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
options_disabled: not has (method_options)
|
||||||
|
do
|
||||||
|
methods.extend (method_options)
|
||||||
|
ensure
|
||||||
|
options_enabled: has (method_options)
|
||||||
|
end
|
||||||
|
|
||||||
|
disable_options
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
options_enabled: has (method_options)
|
||||||
|
do
|
||||||
|
prune_method (method_options)
|
||||||
|
ensure
|
||||||
|
options_disabled: not has (method_options)
|
||||||
|
end
|
||||||
|
|
||||||
|
enable_head
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
head_disabled: not has (method_head)
|
||||||
|
do
|
||||||
|
methods.extend (method_head)
|
||||||
|
ensure
|
||||||
|
head_enabled: has (method_head)
|
||||||
|
end
|
||||||
|
|
||||||
|
disable_head
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
head_enabled: has (method_head)
|
||||||
|
do
|
||||||
|
prune_method (method_head)
|
||||||
|
ensure
|
||||||
|
head_disabled: not has (method_head)
|
||||||
|
end
|
||||||
|
|
||||||
|
enable_trace
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
trace_disabled: not has (method_trace)
|
||||||
|
do
|
||||||
|
methods.extend (method_trace)
|
||||||
|
ensure
|
||||||
|
trace_enabled: has (method_trace)
|
||||||
|
end
|
||||||
|
|
||||||
|
disable_trace
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
trace_enabled: has (method_trace)
|
||||||
|
do
|
||||||
|
prune_method (method_trace)
|
||||||
|
ensure
|
||||||
|
trace_disabled: not has (method_trace)
|
||||||
|
end
|
||||||
|
|
||||||
|
enable_connect
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
connect_disabled: not has (method_connect)
|
||||||
|
do
|
||||||
|
methods.extend (method_connect)
|
||||||
|
ensure
|
||||||
|
connect_enabled: has (method_connect)
|
||||||
|
end
|
||||||
|
|
||||||
|
disable_connect
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
connect_enabled: has (method_connect)
|
||||||
|
do
|
||||||
|
prune_method (method_connect)
|
||||||
|
ensure
|
||||||
|
connect_disabled: not has (method_connect)
|
||||||
|
end
|
||||||
|
|
||||||
|
enable_patch
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
patch_disabled: not has (method_patch)
|
||||||
|
do
|
||||||
|
methods.extend (method_patch)
|
||||||
|
ensure
|
||||||
|
patch_enabled: has (method_patch)
|
||||||
|
end
|
||||||
|
|
||||||
|
disable_patch
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
patch_enabled: has (method_patch)
|
||||||
|
do
|
||||||
|
prune_method (method_patch)
|
||||||
|
ensure
|
||||||
|
patch_disabled: not has (method_patch)
|
||||||
|
end
|
||||||
|
|
||||||
|
enable_custom (m: READABLE_STRING_8)
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
not_blank: not across m as mc some mc.item.is_space end
|
||||||
|
custom_disabled: not has (m.as_upper)
|
||||||
|
do
|
||||||
|
methods.extend (m.as_upper)
|
||||||
|
ensure
|
||||||
|
custom_enabled: has (m.as_upper)
|
||||||
|
end
|
||||||
|
|
||||||
|
disable_custom (m: READABLE_STRING_8)
|
||||||
|
require
|
||||||
|
is_not_locked: not is_locked
|
||||||
|
not_blank: not across m as mc some mc.item.is_space end
|
||||||
|
custom_enabled: has (m.as_upper)
|
||||||
|
do
|
||||||
|
prune_method (m.as_upper)
|
||||||
|
ensure
|
||||||
|
custom_disabled: not has (m.as_upper)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
methods: ARRAYED_LIST [READABLE_STRING_8]
|
||||||
|
|
||||||
|
to_array: ARRAY [READABLE_STRING_8]
|
||||||
|
do
|
||||||
|
Result := methods.to_array
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
smart_add_method (v: READABLE_STRING_8)
|
||||||
|
do
|
||||||
|
if v.is_case_insensitive_equal (method_get) then
|
||||||
|
enable_get
|
||||||
|
elseif v.is_case_insensitive_equal (method_post) then
|
||||||
|
enable_post
|
||||||
|
elseif v.is_case_insensitive_equal (method_put) then
|
||||||
|
enable_put
|
||||||
|
elseif v.is_case_insensitive_equal (method_delete) then
|
||||||
|
enable_delete
|
||||||
|
elseif v.is_case_insensitive_equal (method_head) then
|
||||||
|
enable_delete
|
||||||
|
elseif v.is_case_insensitive_equal (method_options) then
|
||||||
|
enable_options
|
||||||
|
elseif v.is_case_insensitive_equal (method_trace) then
|
||||||
|
enable_trace
|
||||||
|
elseif v.is_case_insensitive_equal (method_connect) then
|
||||||
|
enable_connect
|
||||||
|
elseif v.is_case_insensitive_equal (method_patch) then
|
||||||
|
enable_patch
|
||||||
|
else
|
||||||
|
enable_custom (v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
add_method (v: READABLE_STRING_8)
|
||||||
|
require
|
||||||
|
is_upper_case: v.same_string (v.as_upper)
|
||||||
|
do
|
||||||
|
if not is_locked then
|
||||||
|
methods.extend (v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
prune_method (v: READABLE_STRING_8)
|
||||||
|
require
|
||||||
|
is_upper_case: v.same_string (v.as_upper)
|
||||||
|
local
|
||||||
|
m: READABLE_STRING_8
|
||||||
|
do
|
||||||
|
if not is_locked then
|
||||||
|
from
|
||||||
|
methods.start
|
||||||
|
until
|
||||||
|
methods.after
|
||||||
|
loop
|
||||||
|
m := methods.item
|
||||||
|
if m = v or else m.same_string (v) then
|
||||||
|
methods.remove
|
||||||
|
else
|
||||||
|
methods.forth
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
invariant
|
||||||
|
methods_are_uppercase: across methods as c all c.item.same_string (c.item.as_upper) end
|
||||||
|
|
||||||
|
;note
|
||||||
|
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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
|
||||||
@@ -82,7 +82,8 @@ feature -- Mapping
|
|||||||
router.map (a_resource, h)
|
router.map (a_resource, h)
|
||||||
end
|
end
|
||||||
|
|
||||||
map_with_request_methods (a_resource: READABLE_STRING_8; h: H; rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
map_with_request_methods (a_resource: READABLE_STRING_8; h: H;
|
||||||
|
rqst_methods: detachable WSF_ROUTER_METHODS)
|
||||||
-- Map handler `h' with `a_resource' and `rqst_methods'
|
-- Map handler `h' with `a_resource' and `rqst_methods'
|
||||||
do
|
do
|
||||||
router.map_with_request_methods (a_resource, h, rqst_methods)
|
router.map_with_request_methods (a_resource, h, rqst_methods)
|
||||||
@@ -94,7 +95,7 @@ feature -- Mapping
|
|||||||
end
|
end
|
||||||
|
|
||||||
map_agent_with_request_methods (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]];
|
map_agent_with_request_methods (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]];
|
||||||
rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
rqst_methods: detachable WSF_ROUTER_METHODS)
|
||||||
do
|
do
|
||||||
router.map_agent_with_request_methods (a_resource, a_action, rqst_methods)
|
router.map_agent_with_request_methods (a_resource, a_action, rqst_methods)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {WSF_ANY}."
|
description: "[
|
||||||
author: ""
|
{WSF_ANY} represents a parameter holding any object.
|
||||||
|
]"
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
@@ -15,11 +16,11 @@ create
|
|||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
make (a_name: READABLE_STRING_8; a_value: like item)
|
make (a_name: READABLE_STRING_8; a_value: like value)
|
||||||
do
|
do
|
||||||
name := url_decoded_string (a_name)
|
name := url_decoded_string (a_name)
|
||||||
url_encoded_name := a_name
|
url_encoded_name := a_name
|
||||||
item := a_value
|
value := a_value
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
@@ -28,7 +29,7 @@ feature -- Access
|
|||||||
|
|
||||||
url_encoded_name: READABLE_STRING_8
|
url_encoded_name: READABLE_STRING_8
|
||||||
|
|
||||||
item: detachable ANY
|
value: detachable ANY
|
||||||
|
|
||||||
feature -- Element change
|
feature -- Element change
|
||||||
|
|
||||||
@@ -50,8 +51,8 @@ feature -- Query
|
|||||||
-- String representation of Current
|
-- String representation of Current
|
||||||
-- if possible
|
-- if possible
|
||||||
do
|
do
|
||||||
if attached item as i then
|
if attached value as v then
|
||||||
Result := i.generating_type
|
Result := v.generating_type
|
||||||
else
|
else
|
||||||
Result := "Void"
|
Result := "Void"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {WSF_MULTIPLE_STRING}."
|
description: "[
|
||||||
author: ""
|
{WSF_MULTIPLE_STRING} represents a sequence of name=value parameters
|
||||||
|
]"
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ feature {NONE} -- Initialization
|
|||||||
make_with_value (a_value: WSF_VALUE)
|
make_with_value (a_value: WSF_VALUE)
|
||||||
do
|
do
|
||||||
name := a_value.name
|
name := a_value.name
|
||||||
create {LINKED_LIST [WSF_STRING]} string_values.make
|
create {LINKED_LIST [WSF_STRING]} values.make
|
||||||
add_value (a_value)
|
add_value (a_value)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -58,11 +59,25 @@ feature -- Access
|
|||||||
|
|
||||||
name: READABLE_STRING_32
|
name: READABLE_STRING_32
|
||||||
|
|
||||||
string_values: LIST [WSF_STRING]
|
values: LIST [WSF_STRING]
|
||||||
|
|
||||||
first_string_value: WSF_STRING
|
frozen string_values: like values
|
||||||
|
obsolete
|
||||||
|
"Use `values' [2012-May-31]"
|
||||||
do
|
do
|
||||||
Result := string_values.first
|
Result := values
|
||||||
|
end
|
||||||
|
|
||||||
|
first_value: WSF_STRING
|
||||||
|
do
|
||||||
|
Result := values.first
|
||||||
|
end
|
||||||
|
|
||||||
|
frozen first_string_value: WSF_STRING
|
||||||
|
obsolete
|
||||||
|
"Use `first_value' [2012-May-31]"
|
||||||
|
do
|
||||||
|
Result := first_value
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Element change
|
feature -- Element change
|
||||||
@@ -79,15 +94,15 @@ feature -- Status report
|
|||||||
is_string: BOOLEAN
|
is_string: BOOLEAN
|
||||||
-- Is Current as a WSF_STRING representation?
|
-- Is Current as a WSF_STRING representation?
|
||||||
do
|
do
|
||||||
Result := string_values.count = 1
|
Result := values.count = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Conversion
|
feature -- Conversion
|
||||||
|
|
||||||
as_string: WSF_STRING
|
as_string: WSF_STRING
|
||||||
do
|
do
|
||||||
if string_values.count = 1 then
|
if values.count = 1 then
|
||||||
Result := first_string_value
|
Result := first_value
|
||||||
else
|
else
|
||||||
Result := Precursor
|
Result := Precursor
|
||||||
end
|
end
|
||||||
@@ -97,19 +112,19 @@ feature -- Traversing
|
|||||||
|
|
||||||
new_cursor: ITERATION_CURSOR [WSF_STRING]
|
new_cursor: ITERATION_CURSOR [WSF_STRING]
|
||||||
do
|
do
|
||||||
Result := string_values.new_cursor
|
Result := values.new_cursor
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Helper
|
feature -- Helper
|
||||||
|
|
||||||
string_representation: STRING_32
|
string_representation: STRING_32
|
||||||
do
|
do
|
||||||
if string_values.count = 1 then
|
if values.count = 1 then
|
||||||
create Result.make_from_string (first_string_value)
|
create Result.make_from_string (first_value)
|
||||||
else
|
else
|
||||||
create Result.make_from_string ("[")
|
create Result.make_from_string ("[")
|
||||||
across
|
across
|
||||||
string_values as c
|
values as c
|
||||||
loop
|
loop
|
||||||
if Result.count > 1 then
|
if Result.count > 1 then
|
||||||
Result.append_character (',')
|
Result.append_character (',')
|
||||||
@@ -139,7 +154,7 @@ feature -- Element change
|
|||||||
|
|
||||||
add_string_value (s: WSF_STRING)
|
add_string_value (s: WSF_STRING)
|
||||||
do
|
do
|
||||||
string_values.extend (s)
|
values.extend (s)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Visitor
|
feature -- Visitor
|
||||||
@@ -150,7 +165,7 @@ feature -- Visitor
|
|||||||
end
|
end
|
||||||
|
|
||||||
invariant
|
invariant
|
||||||
string_values_not_empty: string_values.count >= 1
|
string_values_not_empty: values.count >= 1
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {WSF_STRING}."
|
description: "[
|
||||||
author: ""
|
{WSF_STRING} represents a String parameter
|
||||||
|
]"
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
@@ -25,21 +26,70 @@ feature {NONE} -- Initialization
|
|||||||
make (a_name: READABLE_STRING_8; a_string: READABLE_STRING_8)
|
make (a_name: READABLE_STRING_8; a_string: READABLE_STRING_8)
|
||||||
do
|
do
|
||||||
name := url_decoded_string (a_name)
|
name := url_decoded_string (a_name)
|
||||||
string := url_decoded_string (a_string)
|
value := url_decoded_string (a_string)
|
||||||
|
|
||||||
url_encoded_name := a_name
|
url_encoded_name := a_name
|
||||||
url_encoded_string := a_string
|
url_encoded_value := a_string
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
name: READABLE_STRING_32
|
name: READABLE_STRING_32
|
||||||
|
-- <Precursor>
|
||||||
|
--| Note that the value might be html encoded as well
|
||||||
|
--| this is the application responsibility to html decode it
|
||||||
|
|
||||||
string: READABLE_STRING_32
|
value: READABLE_STRING_32
|
||||||
|
-- <Precursor>
|
||||||
|
--| Note that the value might be html encoded as well
|
||||||
|
--| this is the application responsibility to html decode it
|
||||||
|
|
||||||
url_encoded_name: READABLE_STRING_8
|
url_encoded_name: READABLE_STRING_8
|
||||||
|
-- URL encoded string of `name'.
|
||||||
|
|
||||||
url_encoded_string: READABLE_STRING_8
|
url_encoded_value: READABLE_STRING_8
|
||||||
|
-- URL encoded string of `value'.
|
||||||
|
|
||||||
|
frozen string: like value
|
||||||
|
obsolete
|
||||||
|
"Use value [2012-May-31]"
|
||||||
|
do
|
||||||
|
Result := value
|
||||||
|
end
|
||||||
|
|
||||||
|
frozen url_encoded_string: like url_encoded_value
|
||||||
|
obsolete
|
||||||
|
"Use url_encoded_value [2012-May-31]"
|
||||||
|
do
|
||||||
|
Result := url_encoded_value
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Conversion
|
||||||
|
|
||||||
|
integer_value: INTEGER
|
||||||
|
-- Integer value of `value'.
|
||||||
|
require
|
||||||
|
value_is_integer: is_integer
|
||||||
|
do
|
||||||
|
Result := value.to_integer
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
is_string: BOOLEAN = True
|
||||||
|
-- Is Current as a WSF_STRING representation?
|
||||||
|
|
||||||
|
is_empty: BOOLEAN
|
||||||
|
-- Is empty?
|
||||||
|
do
|
||||||
|
Result := value.is_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
is_integer: BOOLEAN
|
||||||
|
-- Is `value' an integer?
|
||||||
|
do
|
||||||
|
Result := value.is_integer
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Element change
|
feature -- Element change
|
||||||
|
|
||||||
@@ -51,31 +101,20 @@ feature -- Element change
|
|||||||
a_name.same_string (url_encoded_name)
|
a_name.same_string (url_encoded_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Status report
|
|
||||||
|
|
||||||
is_string: BOOLEAN = True
|
|
||||||
-- Is Current as a WSF_STRING representation?
|
|
||||||
|
|
||||||
is_empty: BOOLEAN
|
|
||||||
-- Is empty?
|
|
||||||
do
|
|
||||||
Result := string.is_empty
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Helper
|
feature -- Helper
|
||||||
|
|
||||||
same_string (a_other: READABLE_STRING_GENERAL): BOOLEAN
|
same_string (a_other: READABLE_STRING_GENERAL): BOOLEAN
|
||||||
-- Does `a_other' represent the same string as `Current'?
|
-- Does `a_other' represent the same string as `Current'?
|
||||||
do
|
do
|
||||||
Result := string.same_string_general (a_other)
|
Result := value.same_string_general (a_other)
|
||||||
end
|
end
|
||||||
|
|
||||||
is_case_insensitive_equal (a_other: READABLE_STRING_8): BOOLEAN
|
is_case_insensitive_equal (a_other: READABLE_STRING_8): BOOLEAN
|
||||||
-- Does `a_other' represent the same case insensitive string as `Current'?
|
-- Does `a_other' represent the same case insensitive string as `Current'?
|
||||||
local
|
local
|
||||||
v: like string
|
v: like value
|
||||||
do
|
do
|
||||||
v := string
|
v := value
|
||||||
if v = a_other then
|
if v = a_other then
|
||||||
Result := True
|
Result := True
|
||||||
elseif v.is_valid_as_string_8 then
|
elseif v.is_valid_as_string_8 then
|
||||||
@@ -87,26 +126,7 @@ feature -- Conversion
|
|||||||
|
|
||||||
string_representation: STRING_32
|
string_representation: STRING_32
|
||||||
do
|
do
|
||||||
create Result.make_from_string (string)
|
create Result.make_from_string (value)
|
||||||
end
|
|
||||||
|
|
||||||
html_encoded_name: READABLE_STRING_8
|
|
||||||
-- HTML encoded string `name'
|
|
||||||
do
|
|
||||||
Result := (create {HTML_ENCODER}).encoded_string (name)
|
|
||||||
end
|
|
||||||
|
|
||||||
html_encoded_string: READABLE_STRING_8
|
|
||||||
-- HTML encoded string `string'
|
|
||||||
do
|
|
||||||
Result := (create {HTML_ENCODER}).encoded_string (string)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Conversion
|
|
||||||
|
|
||||||
html_decoded_string (s: READABLE_STRING_GENERAL): READABLE_STRING_32
|
|
||||||
do
|
|
||||||
Result := (create {HTML_ENCODER}).general_decoded_string (s)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Visitor
|
feature -- Visitor
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ feature -- Access
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
first_key: detachable READABLE_STRING_32
|
first_name: detachable READABLE_STRING_32
|
||||||
do
|
do
|
||||||
across
|
across
|
||||||
values as c
|
values as c
|
||||||
@@ -70,6 +70,13 @@ feature -- Access
|
|||||||
Result := values.count
|
Result := values.count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
frozen first_key: like first_name
|
||||||
|
obsolete
|
||||||
|
"Use first_name [2012-May-31]"
|
||||||
|
do
|
||||||
|
Result := first_name
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Element change
|
feature -- Element change
|
||||||
|
|
||||||
change_name (a_name: like name)
|
change_name (a_name: like name)
|
||||||
@@ -122,7 +129,7 @@ feature -- Helper
|
|||||||
string_representation: STRING_32
|
string_representation: STRING_32
|
||||||
do
|
do
|
||||||
create Result.make_from_string ("{")
|
create Result.make_from_string ("{")
|
||||||
if values.count = 1 and then attached first_key as fk then
|
if values.count = 1 and then attached first_name as fk then
|
||||||
Result.append (fk + ": ")
|
Result.append (fk + ": ")
|
||||||
if attached value (fk) as fv then
|
if attached value (fk) as fv then
|
||||||
Result.append (fv.string_representation)
|
Result.append (fv.string_representation)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {WSF_UPLOADED_FILE}."
|
description: "[
|
||||||
author: ""
|
{WSF_UPLOADED_FILE} represents an uploaded file from form parameters.
|
||||||
|
]"
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
@@ -40,13 +41,11 @@ feature -- Element change
|
|||||||
a_name.same_string (url_encoded_name)
|
a_name.same_string (url_encoded_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
feature -- Status report
|
feature -- Status report
|
||||||
|
|
||||||
is_string: BOOLEAN = False
|
is_string: BOOLEAN = False
|
||||||
-- Is Current as a WSF_STRING representation?
|
-- Is Current as a WSF_STRING representation?
|
||||||
|
|
||||||
|
|
||||||
feature -- Conversion
|
feature -- Conversion
|
||||||
|
|
||||||
string_representation: STRING_32
|
string_representation: STRING_32
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ feature -- Access
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
|
frozen key: like name
|
||||||
|
do
|
||||||
|
Result := name
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Element change
|
feature -- Element change
|
||||||
|
|
||||||
change_name (a_name: like name)
|
change_name (a_name: like name)
|
||||||
@@ -78,7 +83,7 @@ feature -- Status report
|
|||||||
debug_output: STRING
|
debug_output: STRING
|
||||||
-- String that should be displayed in debugger to represent `Current'.
|
-- String that should be displayed in debugger to represent `Current'.
|
||||||
do
|
do
|
||||||
create Result.make_from_string (name.as_string_8 + "=" + string_representation.as_string_8)
|
create Result.make_from_string (url_encoder.encoded_string (name) + "=" + url_encoder.encoded_string (string_representation))
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ feature -- Element change
|
|||||||
answer_head_request_method := b
|
answer_head_request_method := b
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {WSF_SERVICE, WSF_RESPONSE} -- Basic operations
|
feature {WSF_RESPONSE} -- Output
|
||||||
|
|
||||||
send_to (res: WSF_RESPONSE)
|
send_to (res: WSF_RESPONSE)
|
||||||
do
|
do
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ feature -- Element change
|
|||||||
update_content_length
|
update_content_length
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {WSF_SERVICE, WSF_RESPONSE} -- Output
|
feature {WSF_RESPONSE} -- Output
|
||||||
|
|
||||||
send_to (res: WSF_RESPONSE)
|
send_to (res: WSF_RESPONSE)
|
||||||
local
|
local
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ feature -- Element change
|
|||||||
body := b
|
body := b
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {WSF_SERVICE, WSF_RESPONSE} -- Output
|
feature {WSF_RESPONSE} -- Output
|
||||||
|
|
||||||
send_to (res: WSF_RESPONSE)
|
send_to (res: WSF_RESPONSE)
|
||||||
local
|
local
|
||||||
@@ -147,8 +147,20 @@ feature {WSF_SERVICE, WSF_RESPONSE} -- Output
|
|||||||
res.put_string (s)
|
res.put_string (s)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- HTML facilities
|
||||||
|
|
||||||
|
html_encoded_string (s: READABLE_STRING_32): READABLE_STRING_8
|
||||||
|
do
|
||||||
|
Result := html_encoder.encoded_string (s)
|
||||||
|
end
|
||||||
|
|
||||||
feature {NONE} -- HTML Generation
|
feature {NONE} -- HTML Generation
|
||||||
|
|
||||||
|
html_encoder: HTML_ENCODER
|
||||||
|
once ("thread")
|
||||||
|
create Result
|
||||||
|
end
|
||||||
|
|
||||||
append_html_head_code (s: STRING_8)
|
append_html_head_code (s: STRING_8)
|
||||||
local
|
local
|
||||||
t: like title
|
t: like title
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ feature -- Element change
|
|||||||
url_location := a_url_location
|
url_location := a_url_location
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {WSF_SERVICE, WSF_RESPONSE} -- Output
|
feature {WSF_RESPONSE} -- Output
|
||||||
|
|
||||||
send_to (res: WSF_RESPONSE)
|
send_to (res: WSF_RESPONSE)
|
||||||
local
|
local
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ feature -- Element change
|
|||||||
l_body.append (a_string)
|
l_body.append (a_string)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {WSF_SERVICE, WSF_RESPONSE} -- Output
|
feature {WSF_RESPONSE} -- Output
|
||||||
|
|
||||||
send_to (res: WSF_RESPONSE)
|
send_to (res: WSF_RESPONSE)
|
||||||
local
|
local
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ feature -- Element change
|
|||||||
content_type := Void
|
content_type := Void
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {WSF_SERVICE, WSF_RESPONSE} -- Output
|
feature {WSF_RESPONSE} -- Output
|
||||||
|
|
||||||
send_to (res: WSF_RESPONSE)
|
send_to (res: WSF_RESPONSE)
|
||||||
local
|
local
|
||||||
|
|||||||
@@ -87,12 +87,12 @@ feature {NONE} -- Initialization
|
|||||||
end
|
end
|
||||||
|
|
||||||
--| PATH_INFO
|
--| PATH_INFO
|
||||||
path_info := url_encoder.decoded_string (wgi_request.path_info)
|
path_info := raw_url_encoder.decoded_string (wgi_request.path_info)
|
||||||
|
|
||||||
--| PATH_TRANSLATED
|
--| PATH_TRANSLATED
|
||||||
s8 := wgi_request.path_translated
|
s8 := wgi_request.path_translated
|
||||||
if s8 /= Void then
|
if s8 /= Void then
|
||||||
path_translated := url_encoder.decoded_string (s8)
|
path_translated := raw_url_encoder.decoded_string (s8)
|
||||||
end
|
end
|
||||||
|
|
||||||
--| Here one can set its own environment entries if needed
|
--| Here one can set its own environment entries if needed
|
||||||
@@ -253,7 +253,7 @@ feature -- Access: global variable
|
|||||||
string_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
string_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
do
|
do
|
||||||
if attached {WSF_STRING} item (a_name) as val then
|
if attached {WSF_STRING} item (a_name) as val then
|
||||||
Result := val.string
|
Result := val.value
|
||||||
else
|
else
|
||||||
check is_string_value: False end
|
check is_string_value: False end
|
||||||
end
|
end
|
||||||
@@ -303,7 +303,7 @@ feature -- Access: CGI Meta variables
|
|||||||
a_name_valid: a_name /= Void and then not a_name.is_empty
|
a_name_valid: a_name /= Void and then not a_name.is_empty
|
||||||
do
|
do
|
||||||
if attached meta_variable (a_name) as val then
|
if attached meta_variable (a_name) as val then
|
||||||
Result := val.string
|
Result := val.value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -317,7 +317,7 @@ feature -- Access: CGI Meta variables
|
|||||||
a_name_not_empty: a_name /= Void and then not a_name.is_empty
|
a_name_not_empty: a_name /= Void and then not a_name.is_empty
|
||||||
do
|
do
|
||||||
if attached meta_variable (a_name) as val then
|
if attached meta_variable (a_name) as val then
|
||||||
Result := val.string
|
Result := val.value
|
||||||
if use_default_when_empty and then Result.is_empty then
|
if use_default_when_empty and then Result.is_empty then
|
||||||
Result := a_default
|
Result := a_default
|
||||||
end
|
end
|
||||||
@@ -332,7 +332,7 @@ feature -- Access: CGI Meta variables
|
|||||||
do
|
do
|
||||||
meta_variables_table.force (new_string_value (a_name, a_value), a_name)
|
meta_variables_table.force (new_string_value (a_name, a_value), a_name)
|
||||||
ensure
|
ensure
|
||||||
param_set: attached {WSF_STRING} meta_variable (a_name) as val and then val.url_encoded_string.same_string (a_value)
|
param_set: attached {WSF_STRING} meta_variable (a_name) as val and then val.url_encoded_value.same_string (a_value)
|
||||||
end
|
end
|
||||||
|
|
||||||
unset_meta_variable (a_name: READABLE_STRING_GENERAL)
|
unset_meta_variable (a_name: READABLE_STRING_GENERAL)
|
||||||
@@ -825,9 +825,9 @@ feature -- Extra CGI environment variables
|
|||||||
do
|
do
|
||||||
if
|
if
|
||||||
attached {WSF_STRING} meta_variable ({WSF_META_NAMES}.request_time) as t and then
|
attached {WSF_STRING} meta_variable ({WSF_META_NAMES}.request_time) as t and then
|
||||||
t.string.is_integer_64
|
t.value.is_integer_64
|
||||||
then
|
then
|
||||||
Result := date_time_utilities.unix_time_stamp_to_date_time (t.string.to_integer_64)
|
Result := date_time_utilities.unix_time_stamp_to_date_time (t.value.to_integer_64)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -857,7 +857,7 @@ feature {NONE} -- Cookies
|
|||||||
l_cookies := internal_cookies_table
|
l_cookies := internal_cookies_table
|
||||||
if l_cookies = Void then
|
if l_cookies = Void then
|
||||||
if attached {WSF_STRING} meta_variable ({WSF_META_NAMES}.http_cookie) as val then
|
if attached {WSF_STRING} meta_variable ({WSF_META_NAMES}.http_cookie) as val then
|
||||||
s := val.string
|
s := val.value
|
||||||
create l_cookies.make_with_key_tester (5, string_equality_tester)
|
create l_cookies.make_with_key_tester (5, string_equality_tester)
|
||||||
l_cookies.compare_objects
|
l_cookies.compare_objects
|
||||||
from
|
from
|
||||||
@@ -1582,6 +1582,11 @@ feature {NONE} -- Implementation: utilities
|
|||||||
empty_string: READABLE_STRING_32
|
empty_string: READABLE_STRING_32
|
||||||
-- Reusable empty string
|
-- Reusable empty string
|
||||||
|
|
||||||
|
raw_url_encoder: URL_ENCODER
|
||||||
|
once
|
||||||
|
create {URL_ENCODER} Result
|
||||||
|
end
|
||||||
|
|
||||||
url_encoder: URL_ENCODER
|
url_encoder: URL_ENCODER
|
||||||
once
|
once
|
||||||
create {UTF8_URL_ENCODER} Result
|
create {UTF8_URL_ENCODER} Result
|
||||||
|
|||||||
@@ -1,17 +1,24 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {WSF_RESPONSE_MESSAGE}."
|
description: "[
|
||||||
author: ""
|
Object to represent a full message to be send to the client
|
||||||
|
via {WSF_RESPONSE}.send (obj)
|
||||||
|
|
||||||
|
The only requirement is to implement correctly the `send_to (WSF_RESPONSE)'
|
||||||
|
method.
|
||||||
|
]"
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
WSF_RESPONSE_MESSAGE
|
WSF_RESPONSE_MESSAGE
|
||||||
|
|
||||||
feature {WSF_SERVICE, WSF_RESPONSE} -- Output
|
feature {WSF_RESPONSE} -- Output
|
||||||
|
|
||||||
send_to (res: WSF_RESPONSE)
|
send_to (res: WSF_RESPONSE)
|
||||||
-- Send Current message to `res'
|
-- Send Current message to `res'
|
||||||
--| This should not be called by user's code directly
|
--
|
||||||
|
-- This feature should be called via `{WSF_RESPONSE}.send (obj)'
|
||||||
|
-- where `obj' is the current object
|
||||||
require
|
require
|
||||||
header_not_committed: not res.header_committed
|
header_not_committed: not res.header_committed
|
||||||
status_not_committed: not res.status_committed
|
status_not_committed: not res.status_committed
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ note
|
|||||||
Summary description for {HTML_ENCODER}.
|
Summary description for {HTML_ENCODER}.
|
||||||
|
|
||||||
see: http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
|
see: http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
|
||||||
|
see: http://en.wikipedia.org/wiki/Character_encodings_in_HTML
|
||||||
]"
|
]"
|
||||||
legal: "See notice at end of class."
|
legal: "See notice at end of class."
|
||||||
status: "See notice at end of class."
|
status: "See notice at end of class."
|
||||||
@@ -38,6 +39,7 @@ feature -- Encoder
|
|||||||
local
|
local
|
||||||
i, n: INTEGER
|
i, n: INTEGER
|
||||||
uc: CHARACTER_32
|
uc: CHARACTER_32
|
||||||
|
l_code: INTEGER
|
||||||
c: CHARACTER_8
|
c: CHARACTER_8
|
||||||
do
|
do
|
||||||
has_error := False
|
has_error := False
|
||||||
@@ -47,15 +49,32 @@ feature -- Encoder
|
|||||||
uc := s.item (i)
|
uc := s.item (i)
|
||||||
if uc.is_character_8 then
|
if uc.is_character_8 then
|
||||||
c := uc.to_character_8
|
c := uc.to_character_8
|
||||||
|
|
||||||
inspect c
|
inspect c
|
||||||
|
when '%T', '%N', '%R' then
|
||||||
|
Result.extend (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 ("'")
|
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
|
||||||
|
l_code := c.code
|
||||||
|
if
|
||||||
|
l_code <= 31 or -- Hexa 1F
|
||||||
|
l_code = 127 -- Hexa 7F
|
||||||
|
then
|
||||||
|
-- Ignore (forbidden in HTML, even by reference
|
||||||
|
|
||||||
|
elseif l_code >= 128 then
|
||||||
|
--| Tolerated
|
||||||
|
Result.append ("&#")
|
||||||
|
Result.append (l_code.out)
|
||||||
|
Result.extend (';')
|
||||||
else
|
else
|
||||||
Result.extend (c)
|
Result.extend (c)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
else
|
else
|
||||||
Result.append ("&#")
|
Result.append ("&#")
|
||||||
Result.append (uc.code.out)
|
Result.append (uc.code.out)
|
||||||
@@ -134,7 +153,7 @@ feature {NONE} -- Implementation: decoder
|
|||||||
do
|
do
|
||||||
sharp_code := ('#').natural_32_code
|
sharp_code := ('#').natural_32_code
|
||||||
x_code := ('x').natural_32_code
|
x_code := ('x').natural_32_code
|
||||||
x_code := (';').natural_32_code
|
semi_colon_code := (';').natural_32_code
|
||||||
|
|
||||||
i := cl_i.item
|
i := cl_i.item
|
||||||
create s.make_empty
|
create s.make_empty
|
||||||
|
|||||||
@@ -45,11 +45,8 @@ feature -- Encoder
|
|||||||
encoded_string (s: READABLE_STRING_32): STRING_8
|
encoded_string (s: READABLE_STRING_32): STRING_8
|
||||||
-- URL-encoded value of `s'.
|
-- URL-encoded value of `s'.
|
||||||
do
|
do
|
||||||
Result := Precursor (s)
|
Result := utf32_to_utf8 (s)
|
||||||
if not has_error then
|
Result := Precursor (Result)
|
||||||
Result := utf32_to_utf8 (Result)
|
|
||||||
has_error := not last_conversion_successful
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
partial_encoded_string (s: READABLE_STRING_32; a_ignore: ARRAY [CHARACTER]): READABLE_STRING_8
|
partial_encoded_string (s: READABLE_STRING_32; a_ignore: ARRAY [CHARACTER]): READABLE_STRING_8
|
||||||
@@ -58,7 +55,6 @@ feature -- Encoder
|
|||||||
Result := Precursor (s, a_ignore)
|
Result := Precursor (s, a_ignore)
|
||||||
if not has_error then
|
if not has_error then
|
||||||
Result := utf32_to_utf8 (Result)
|
Result := utf32_to_utf8 (Result)
|
||||||
has_error := not last_conversion_successful
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user