Migrated simple, simple_file and upload_image example.
Adapted EWF accordingly.
This commit is contained in:
@@ -10,16 +10,7 @@ class
|
|||||||
inherit
|
inherit
|
||||||
ANY
|
ANY
|
||||||
|
|
||||||
WSF_ROUTED_SKELETON_SERVICE
|
WSF_DEFAULT_SERVICE [IMAGE_UPLOADER_EXECUTION]
|
||||||
undefine
|
|
||||||
requires_proxy
|
|
||||||
end
|
|
||||||
|
|
||||||
WSF_URI_TEMPLATE_HELPER_FOR_ROUTED_SERVICE
|
|
||||||
|
|
||||||
WSF_NO_PROXY_POLICY
|
|
||||||
|
|
||||||
WSF_DEFAULT_SERVICE
|
|
||||||
|
|
||||||
SHARED_EXECUTION_ENVIRONMENT
|
SHARED_EXECUTION_ENVIRONMENT
|
||||||
|
|
||||||
@@ -31,224 +22,12 @@ feature {NONE} -- Initialization
|
|||||||
make
|
make
|
||||||
-- Initialize Current
|
-- Initialize Current
|
||||||
do
|
do
|
||||||
initialize_router
|
|
||||||
|
|
||||||
|
|
||||||
-- To use particular port number (as 9090) with Nino connector
|
-- To use particular port number (as 9090) with Nino connector
|
||||||
-- Uncomment the following line
|
-- Uncomment the following line
|
||||||
set_service_option ("port", 9090)
|
set_service_option ("port", 9090)
|
||||||
make_and_launch
|
make_and_launch
|
||||||
end
|
end
|
||||||
|
|
||||||
setup_router
|
|
||||||
-- Setup router
|
|
||||||
local
|
|
||||||
www: WSF_FILE_SYSTEM_HANDLER
|
|
||||||
do
|
|
||||||
map_uri_template_agent_with_request_methods ("/upload/{name}{?nb}", agent execute_upload_put, router.methods_put)
|
|
||||||
map_uri_template_agent ("/upload{?nb}", agent execute_upload)
|
|
||||||
|
|
||||||
create www.make_with_path (document_root)
|
|
||||||
www.set_directory_index (<<"index.html">>)
|
|
||||||
www.set_not_found_handler (agent execute_not_found)
|
|
||||||
router.handle_with_request_methods ("", www, router.methods_GET)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Configuration
|
|
||||||
|
|
||||||
document_root: PATH
|
|
||||||
-- Document root to look for files or directories
|
|
||||||
once
|
|
||||||
Result := execution_environment.current_working_path.extended ("htdocs")
|
|
||||||
ensure
|
|
||||||
not Result.name.ends_with (Operating_environment.directory_separator.out)
|
|
||||||
end
|
|
||||||
|
|
||||||
files_root: PATH
|
|
||||||
-- Uploaded files will be stored in `files_root' folder
|
|
||||||
once
|
|
||||||
Result := document_root.extended ("files")
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Execution
|
|
||||||
|
|
||||||
execute_not_found (uri: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE)
|
|
||||||
-- `uri' is not found, redirect to default page
|
|
||||||
do
|
|
||||||
res.redirect_now_with_content (req.script_url ("/"), uri + ": not found.%NRedirection to " + req.script_url ("/"), "text/html")
|
|
||||||
end
|
|
||||||
|
|
||||||
execute_upload (req: WSF_REQUEST; res: WSF_RESPONSE)
|
|
||||||
-- Upload page is requested, either GET or POST
|
|
||||||
-- On GET display the web form to upload file, by passing ?nb=5 you can upload 5 images
|
|
||||||
-- On POST display the uploaded files
|
|
||||||
local
|
|
||||||
l_body: STRING_8
|
|
||||||
l_safe_filename: STRING_8
|
|
||||||
fn: PATH
|
|
||||||
page: WSF_HTML_PAGE_RESPONSE
|
|
||||||
n: INTEGER
|
|
||||||
do
|
|
||||||
if req.is_request_method ("GET") or else not req.has_uploaded_file then
|
|
||||||
create page.make
|
|
||||||
page.set_title ("EWF: Upload file")
|
|
||||||
page.add_style (req.script_url ("style.css"), "all")
|
|
||||||
create l_body.make_empty
|
|
||||||
page.set_body (l_body)
|
|
||||||
l_body.append ("<h1>EWF: Upload image file</h1>%N")
|
|
||||||
l_body.append ("<form action=%""+ req.script_url ("/upload") +"%" method=%"POST%" enctype=%"multipart/form-data%">%N")
|
|
||||||
if attached {WSF_STRING} req.query_parameter ("nb") as p_nb and then p_nb.is_integer then
|
|
||||||
n := p_nb.integer_value
|
|
||||||
else
|
|
||||||
n := 1
|
|
||||||
end
|
|
||||||
if attached {WSF_STRING} req.query_parameter ("demo") as p_demo then
|
|
||||||
fn := document_root.extended (p_demo.value)
|
|
||||||
l_body.append ("File: <input type=%"file%" name=%"uploaded_file[]%" size=%"60%" value=%""+ html_encode (fn.name) +"%"></br>%N")
|
|
||||||
end
|
|
||||||
|
|
||||||
from
|
|
||||||
until
|
|
||||||
n = 0
|
|
||||||
loop
|
|
||||||
l_body.append ("File: <input type=%"file%" name=%"uploaded_file[]%" size=%"60%" accept=%"image/*%"></br>%N")
|
|
||||||
n := n - 1
|
|
||||||
end
|
|
||||||
l_body.append (" <input type=%"submit%" value=%"Upload%"/>%N</form>")
|
|
||||||
res.send (page)
|
|
||||||
else
|
|
||||||
create l_body.make (255)
|
|
||||||
l_body.append ("<h1>EWF: Uploaded files</h1>%N")
|
|
||||||
l_body.append ("<ul>")
|
|
||||||
n := 0
|
|
||||||
across
|
|
||||||
req.uploaded_files as c
|
|
||||||
loop
|
|
||||||
n := n + 1
|
|
||||||
l_body.append ("<li>")
|
|
||||||
l_body.append ("<div>" + c.item.name + "=" + html_encode (c.item.filename) + " size=" + c.item.size.out + " type=" + c.item.content_type + "</div>")
|
|
||||||
l_safe_filename := c.item.safe_filename
|
|
||||||
fn := files_root.extended (l_safe_filename)
|
|
||||||
if c.item.move_to (fn.name) then
|
|
||||||
if c.item.content_type.starts_with ("image") then
|
|
||||||
l_body.append ("%N<a href=%"../files/" + url_encode (l_safe_filename) + "%"><img src=%"../files/"+ l_safe_filename +"%" /></a>")
|
|
||||||
else
|
|
||||||
l_body.append ("File " + html_encode (c.item.filename) + " is not a supported image<br/>%N")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
l_body.append ("</li>")
|
|
||||||
end
|
|
||||||
|
|
||||||
l_body.append ("</ul>")
|
|
||||||
|
|
||||||
create page.make
|
|
||||||
page.set_title ("EWF: uploaded image")
|
|
||||||
page.add_style ("../style.css", "all")
|
|
||||||
page.set_body (l_body)
|
|
||||||
res.send (page)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
execute_upload_put (req: WSF_REQUEST; res: WSF_RESPONSE)
|
|
||||||
-- Upload page is requested, PUT
|
|
||||||
require
|
|
||||||
is_put_request_method: req.is_put_request_method
|
|
||||||
local
|
|
||||||
l_body: STRING_8
|
|
||||||
l_safe_filename: detachable READABLE_STRING_32
|
|
||||||
fn: PATH
|
|
||||||
page: WSF_HTML_PAGE_RESPONSE
|
|
||||||
n: INTEGER
|
|
||||||
do
|
|
||||||
create l_body.make (255)
|
|
||||||
l_body.append ("<h1>EWF: Uploaded files</h1>%N")
|
|
||||||
l_body.append ("<ul>")
|
|
||||||
n := 0
|
|
||||||
if attached {WSF_STRING} req.path_parameter ("name") as p_name then
|
|
||||||
l_safe_filename := p_name.value
|
|
||||||
end
|
|
||||||
if l_safe_filename = Void or else l_safe_filename.is_empty then
|
|
||||||
l_safe_filename := "input_data"
|
|
||||||
end
|
|
||||||
if n = 0 and req.content_length_value > 0 then
|
|
||||||
if attached new_temporary_output_file ("tmp-uploaded-file_" + n.out) as f then
|
|
||||||
req.read_input_data_into_file (f)
|
|
||||||
f.close
|
|
||||||
fn := files_root.extended (l_safe_filename)
|
|
||||||
f.rename_file (fn.name)
|
|
||||||
l_body.append ("<li>")
|
|
||||||
l_body.append ("<div>Input data : size=" + f.count.out + " (" + req.content_length_value.out + ")</div>")
|
|
||||||
l_body.append ("%N<a href=%"../files/" + url_encode (l_safe_filename) + "%">"+ html_encode (l_safe_filename) +"</a>")
|
|
||||||
l_body.append ("</li>")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
l_body.append ("</ul>")
|
|
||||||
|
|
||||||
create page.make
|
|
||||||
page.set_title ("EWF: uploaded image")
|
|
||||||
page.add_style ("../style.css", "all")
|
|
||||||
page.set_body (l_body)
|
|
||||||
res.send (page)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
feature {NONE} -- Encoder
|
|
||||||
|
|
||||||
new_temporary_output_file (n: detachable READABLE_STRING_8): detachable FILE
|
|
||||||
local
|
|
||||||
bp: detachable PATH
|
|
||||||
d: DIRECTORY
|
|
||||||
i: INTEGER
|
|
||||||
do
|
|
||||||
create bp.make_current
|
|
||||||
create d.make_with_path (bp)
|
|
||||||
if not d.exists then
|
|
||||||
d.recursive_create_dir
|
|
||||||
end
|
|
||||||
if n /= Void then
|
|
||||||
bp := bp.extended ("tmp-download-" + n)
|
|
||||||
else
|
|
||||||
bp := bp.extended ("tmp")
|
|
||||||
end
|
|
||||||
from
|
|
||||||
i := 0
|
|
||||||
until
|
|
||||||
Result /= Void or i > 100
|
|
||||||
loop
|
|
||||||
i := i + 1
|
|
||||||
create {RAW_FILE} Result.make_with_path (bp.appended ("__" + i.out))
|
|
||||||
if Result.exists then
|
|
||||||
Result := Void
|
|
||||||
else
|
|
||||||
Result.open_write
|
|
||||||
end
|
|
||||||
end
|
|
||||||
ensure
|
|
||||||
Result /= Void implies Result.is_open_write
|
|
||||||
end
|
|
||||||
|
|
||||||
url_encode (s: READABLE_STRING_32): STRING_8
|
|
||||||
-- URL Encode `s' as Result
|
|
||||||
do
|
|
||||||
Result := url_encoder.encoded_string (s)
|
|
||||||
end
|
|
||||||
|
|
||||||
url_encoder: URL_ENCODER
|
|
||||||
once
|
|
||||||
create Result
|
|
||||||
end
|
|
||||||
|
|
||||||
html_encode (s: READABLE_STRING_32): STRING_8
|
|
||||||
-- HTML Encode `s' as Result
|
|
||||||
do
|
|
||||||
Result := html_encoder.encoded_string (s)
|
|
||||||
end
|
|
||||||
|
|
||||||
html_encoder: HTML_ENCODER
|
|
||||||
once
|
|
||||||
create Result
|
|
||||||
end
|
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2012, Eiffel Software and others"
|
copyright: "2011-2012, 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)"
|
||||||
|
|||||||
261
examples/upload_image/src/image_uploader_execution.e
Normal file
261
examples/upload_image/src/image_uploader_execution.e
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {IMAGE_UPLOADER_EXECUTION}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
IMAGE_UPLOADER_EXECUTION
|
||||||
|
|
||||||
|
inherit
|
||||||
|
WSF_EXECUTION
|
||||||
|
redefine
|
||||||
|
initialize
|
||||||
|
end
|
||||||
|
|
||||||
|
WSF_ROUTED_SKELETON_EXECUTION
|
||||||
|
undefine
|
||||||
|
requires_proxy
|
||||||
|
end
|
||||||
|
|
||||||
|
WSF_NO_PROXY_POLICY
|
||||||
|
|
||||||
|
WSF_URI_TEMPLATE_HELPER_FOR_ROUTED_EXECUTION
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
initialize
|
||||||
|
do
|
||||||
|
Precursor
|
||||||
|
initialize_router
|
||||||
|
end
|
||||||
|
|
||||||
|
setup_router
|
||||||
|
-- Setup router
|
||||||
|
local
|
||||||
|
www: WSF_FILE_SYSTEM_HANDLER
|
||||||
|
do
|
||||||
|
map_uri_template_agent_with_request_methods ("/upload/{name}{?nb}", agent execute_upload_put, router.methods_put)
|
||||||
|
map_uri_template_agent ("/upload{?nb}", agent execute_upload)
|
||||||
|
|
||||||
|
create www.make (document_root)
|
||||||
|
www.set_directory_index (<<"index.html">>)
|
||||||
|
www.set_not_found_handler (agent execute_not_found)
|
||||||
|
router.handle_with_request_methods ("", www, router.methods_GET)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Configuration
|
||||||
|
|
||||||
|
document_root: READABLE_STRING_8
|
||||||
|
-- Document root to look for files or directories
|
||||||
|
local
|
||||||
|
e: EXECUTION_ENVIRONMENT
|
||||||
|
dn: DIRECTORY_NAME
|
||||||
|
once
|
||||||
|
create e
|
||||||
|
create dn.make_from_string (e.current_working_directory)
|
||||||
|
dn.extend ("htdocs")
|
||||||
|
Result := dn.string
|
||||||
|
if Result [Result.count] = Operating_environment.directory_separator then
|
||||||
|
Result := Result.substring (1, Result.count - 1)
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
not Result.ends_with (Operating_environment.directory_separator.out)
|
||||||
|
end
|
||||||
|
|
||||||
|
files_root: READABLE_STRING_8
|
||||||
|
-- Uploaded files will be stored in `files_root' folder
|
||||||
|
local
|
||||||
|
dn: DIRECTORY_NAME
|
||||||
|
once
|
||||||
|
create dn.make_from_string (document_root)
|
||||||
|
dn.extend ("files")
|
||||||
|
Result := dn.string
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Execution
|
||||||
|
|
||||||
|
execute_not_found (uri: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- `uri' is not found, redirect to default page
|
||||||
|
do
|
||||||
|
res.redirect_now_with_content (req.script_url ("/"), uri + ": not found.%NRedirection to " + req.script_url ("/"), "text/html")
|
||||||
|
end
|
||||||
|
|
||||||
|
execute_upload (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- Upload page is requested, either GET or POST
|
||||||
|
-- On GET display the web form to upload file, by passing ?nb=5 you can upload 5 images
|
||||||
|
-- On POST display the uploaded files
|
||||||
|
local
|
||||||
|
l_body: STRING_8
|
||||||
|
l_safe_filename: STRING_8
|
||||||
|
fn: PATH
|
||||||
|
page: WSF_HTML_PAGE_RESPONSE
|
||||||
|
n: INTEGER
|
||||||
|
do
|
||||||
|
if req.is_request_method ("GET") or else not req.has_uploaded_file then
|
||||||
|
create page.make
|
||||||
|
page.set_title ("EWF: Upload file")
|
||||||
|
page.add_style (req.script_url ("style.css"), "all")
|
||||||
|
create l_body.make_empty
|
||||||
|
page.set_body (l_body)
|
||||||
|
l_body.append ("<h1>EWF: Upload image file</h1>%N")
|
||||||
|
l_body.append ("<form action=%""+ req.script_url ("/upload") +"%" method=%"POST%" enctype=%"multipart/form-data%">%N")
|
||||||
|
if attached {WSF_STRING} req.query_parameter ("nb") as p_nb and then p_nb.is_integer then
|
||||||
|
n := p_nb.integer_value
|
||||||
|
else
|
||||||
|
n := 1
|
||||||
|
end
|
||||||
|
if attached {WSF_STRING} req.query_parameter ("demo") as p_demo then
|
||||||
|
create fn.make_from_string (document_root)
|
||||||
|
fn := fn.extended (p_demo.value)
|
||||||
|
l_body.append ("File: <input type=%"file%" name=%"uploaded_file[]%" size=%"60%" value=%""+ html_encode (fn.name) +"%"></br>%N")
|
||||||
|
end
|
||||||
|
|
||||||
|
from
|
||||||
|
until
|
||||||
|
n = 0
|
||||||
|
loop
|
||||||
|
l_body.append ("File: <input type=%"file%" name=%"uploaded_file[]%" size=%"60%" accept=%"image/*%"></br>%N")
|
||||||
|
n := n - 1
|
||||||
|
end
|
||||||
|
l_body.append (" <input type=%"submit%" value=%"Upload%"/>%N</form>")
|
||||||
|
res.send (page)
|
||||||
|
else
|
||||||
|
create l_body.make (255)
|
||||||
|
l_body.append ("<h1>EWF: Uploaded files</h1>%N")
|
||||||
|
l_body.append ("<ul>")
|
||||||
|
n := 0
|
||||||
|
across
|
||||||
|
req.uploaded_files as c
|
||||||
|
loop
|
||||||
|
n := n + 1
|
||||||
|
l_body.append ("<li>")
|
||||||
|
l_body.append ("<div>" + c.item.name + "=" + html_encode (c.item.filename) + " size=" + c.item.size.out + " type=" + c.item.content_type + "</div>")
|
||||||
|
create fn.make_from_string (files_root)
|
||||||
|
l_safe_filename := c.item.safe_filename
|
||||||
|
fn := fn.extended (l_safe_filename)
|
||||||
|
if c.item.move_to (fn.name) then
|
||||||
|
if c.item.content_type.starts_with ("image") then
|
||||||
|
l_body.append ("%N<a href=%"../files/" + url_encode (l_safe_filename) + "%"><img src=%"../files/"+ l_safe_filename +"%" /></a>")
|
||||||
|
else
|
||||||
|
l_body.append ("File " + html_encode (c.item.filename) + " is not a supported image<br/>%N")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
l_body.append ("</li>")
|
||||||
|
end
|
||||||
|
|
||||||
|
l_body.append ("</ul>")
|
||||||
|
|
||||||
|
create page.make
|
||||||
|
page.set_title ("EWF: uploaded image")
|
||||||
|
page.add_style ("../style.css", "all")
|
||||||
|
page.set_body (l_body)
|
||||||
|
res.send (page)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
execute_upload_put (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- Upload page is requested, PUT
|
||||||
|
require
|
||||||
|
is_put_request_method: req.is_put_request_method
|
||||||
|
local
|
||||||
|
l_body: STRING_8
|
||||||
|
l_safe_filename: detachable READABLE_STRING_32
|
||||||
|
fn: PATH
|
||||||
|
page: WSF_HTML_PAGE_RESPONSE
|
||||||
|
n: INTEGER
|
||||||
|
do
|
||||||
|
create l_body.make (255)
|
||||||
|
l_body.append ("<h1>EWF: Uploaded files</h1>%N")
|
||||||
|
l_body.append ("<ul>")
|
||||||
|
n := 0
|
||||||
|
if attached {WSF_STRING} req.path_parameter ("name") as p_name then
|
||||||
|
l_safe_filename := p_name.value
|
||||||
|
end
|
||||||
|
if l_safe_filename = Void or else l_safe_filename.is_empty then
|
||||||
|
l_safe_filename := "input_data"
|
||||||
|
end
|
||||||
|
if n = 0 and req.content_length_value > 0 then
|
||||||
|
if attached new_temporary_output_file ("tmp-uploaded-file_" + n.out) as f then
|
||||||
|
req.read_input_data_into_file (f)
|
||||||
|
f.close
|
||||||
|
create fn.make_from_string (files_root)
|
||||||
|
fn := fn.extended (l_safe_filename)
|
||||||
|
f.rename_file (fn.name)
|
||||||
|
l_body.append ("<li>")
|
||||||
|
l_body.append ("<div>Input data : size=" + f.count.out + " (" + req.content_length_value.out + ")</div>")
|
||||||
|
l_body.append ("%N<a href=%"../files/" + url_encode (l_safe_filename) + "%">"+ html_encode (l_safe_filename) +"</a>")
|
||||||
|
l_body.append ("</li>")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
l_body.append ("</ul>")
|
||||||
|
|
||||||
|
create page.make
|
||||||
|
page.set_title ("EWF: uploaded image")
|
||||||
|
page.add_style ("../style.css", "all")
|
||||||
|
page.set_body (l_body)
|
||||||
|
res.send (page)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
feature {NONE} -- Encoder
|
||||||
|
|
||||||
|
new_temporary_output_file (n: detachable READABLE_STRING_8): detachable FILE
|
||||||
|
local
|
||||||
|
bp: detachable PATH
|
||||||
|
d: DIRECTORY
|
||||||
|
i: INTEGER
|
||||||
|
do
|
||||||
|
create bp.make_current
|
||||||
|
create d.make_with_path (bp)
|
||||||
|
if not d.exists then
|
||||||
|
d.recursive_create_dir
|
||||||
|
end
|
||||||
|
if n /= Void then
|
||||||
|
bp := bp.extended ("tmp-download-" + n)
|
||||||
|
else
|
||||||
|
bp := bp.extended ("tmp")
|
||||||
|
end
|
||||||
|
from
|
||||||
|
i := 0
|
||||||
|
until
|
||||||
|
Result /= Void or i > 100
|
||||||
|
loop
|
||||||
|
i := i + 1
|
||||||
|
create {RAW_FILE} Result.make_with_path (bp.appended ("__" + i.out))
|
||||||
|
if Result.exists then
|
||||||
|
Result := Void
|
||||||
|
else
|
||||||
|
Result.open_write
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
Result /= Void implies Result.is_open_write
|
||||||
|
end
|
||||||
|
|
||||||
|
url_encode (s: READABLE_STRING_32): STRING_8
|
||||||
|
-- URL Encode `s' as Result
|
||||||
|
do
|
||||||
|
Result := url_encoder.encoded_string (s)
|
||||||
|
end
|
||||||
|
|
||||||
|
url_encoder: URL_ENCODER
|
||||||
|
once
|
||||||
|
create Result
|
||||||
|
end
|
||||||
|
|
||||||
|
html_encode (s: READABLE_STRING_32): STRING_8
|
||||||
|
-- HTML Encode `s' as Result
|
||||||
|
do
|
||||||
|
Result := html_encoder.encoded_string (s)
|
||||||
|
end
|
||||||
|
|
||||||
|
html_encoder: HTML_ENCODER
|
||||||
|
once
|
||||||
|
create Result
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -4,50 +4,48 @@ note
|
|||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
class
|
class
|
||||||
NINO_SERVICE
|
NINO_SERVICE [G -> WGI_EXECUTION create make end]
|
||||||
|
|
||||||
create
|
create
|
||||||
make,
|
make,
|
||||||
make_custom,
|
make_custom
|
||||||
make_with_callback,
|
|
||||||
make_custom_with_callback
|
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
make (a_service: WGI_SERVICE)
|
make
|
||||||
-- Initialize `Current'.
|
-- Initialize `Current'.
|
||||||
do
|
do
|
||||||
make_custom (a_service, Void)
|
make_custom (Void)
|
||||||
end
|
end
|
||||||
|
|
||||||
make_custom (a_service: WGI_SERVICE; a_base_url: detachable STRING)
|
make_custom (a_base_url: detachable STRING)
|
||||||
-- Initialize `Current'.
|
-- Initialize `Current'.
|
||||||
require
|
require
|
||||||
base_url_starts_with_slash: (a_base_url /= Void and then not a_base_url.is_empty) implies a_base_url.starts_with ("/")
|
base_url_starts_with_slash: (a_base_url /= Void and then not a_base_url.is_empty) implies a_base_url.starts_with ("/")
|
||||||
do
|
do
|
||||||
create connector.make_with_base (a_service, a_base_url)
|
create connector.make_with_base (a_base_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
make_with_callback (a_callback: PROCEDURE [ANY, TUPLE [req: WGI_REQUEST; res: WGI_RESPONSE]])
|
-- make_with_callback (a_callback: PROCEDURE [ANY, TUPLE [req: WGI_REQUEST; res: WGI_RESPONSE]])
|
||||||
-- Initialize `Current'.
|
-- -- Initialize `Current'.
|
||||||
do
|
-- do
|
||||||
make_custom_with_callback (a_callback, Void)
|
-- make_custom_with_callback (a_callback, Void)
|
||||||
end
|
-- end
|
||||||
|
|
||||||
make_custom_with_callback (a_callback: PROCEDURE [ANY, TUPLE [req: WGI_REQUEST; res: WGI_RESPONSE]]; a_base_url: detachable STRING)
|
-- make_custom_with_callback (a_callback: PROCEDURE [ANY, TUPLE [req: WGI_REQUEST; res: WGI_RESPONSE]]; a_base_url: detachable STRING)
|
||||||
-- Initialize `Current'.
|
-- -- Initialize `Current'.
|
||||||
require
|
-- require
|
||||||
base_url_starts_with_slash: (a_base_url /= Void and then not a_base_url.is_empty) implies a_base_url.starts_with ("/")
|
-- base_url_starts_with_slash: (a_base_url /= Void and then not a_base_url.is_empty) implies a_base_url.starts_with ("/")
|
||||||
local
|
-- local
|
||||||
app: WGI_AGENT_SERVICE
|
-- app: WGI_AGENT_SERVICE
|
||||||
do
|
-- do
|
||||||
create app.make (a_callback)
|
-- create app.make (a_callback)
|
||||||
make_custom (app, a_base_url)
|
-- make_custom (app, a_base_url)
|
||||||
end
|
-- end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
connector: WGI_NINO_CONNECTOR
|
connector: WGI_NINO_CONNECTOR [G]
|
||||||
-- Web server connector
|
-- Web server connector
|
||||||
|
|
||||||
feature -- Status report
|
feature -- Status report
|
||||||
@@ -104,7 +102,7 @@ feature -- Server
|
|||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
copyright: "2011-2015, 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: "[
|
||||||
Eiffel Software
|
Eiffel Software
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ create
|
|||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
make (a_service: like service)
|
make --(a_service: like service)
|
||||||
local
|
local
|
||||||
cfg: HTTP_SERVER_CONFIGURATION
|
cfg: HTTP_SERVER_CONFIGURATION
|
||||||
do
|
do
|
||||||
service := a_service
|
-- service := a_service
|
||||||
|
|
||||||
create cfg.make
|
create cfg.make
|
||||||
create server.make (cfg)
|
create server.make (cfg)
|
||||||
@@ -29,11 +29,11 @@ feature {NONE} -- Initialization
|
|||||||
create on_stopped_actions
|
create on_stopped_actions
|
||||||
end
|
end
|
||||||
|
|
||||||
make_with_base (a_service: like service; a_base: like base)
|
make_with_base (a_base: like base)
|
||||||
require
|
require
|
||||||
a_base_starts_with_slash: (a_base /= Void and then not a_base.is_empty) implies a_base.starts_with ("/")
|
a_base_starts_with_slash: (a_base /= Void and then not a_base.is_empty) implies a_base.starts_with ("/")
|
||||||
do
|
do
|
||||||
make (a_service)
|
make -- (a_service)
|
||||||
set_base (a_base)
|
set_base (a_base)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -45,10 +45,10 @@ feature -- Access
|
|||||||
version: STRING_8 = "0.1"
|
version: STRING_8 = "0.1"
|
||||||
-- Version of Current connector
|
-- Version of Current connector
|
||||||
|
|
||||||
feature {NONE} -- Access
|
--feature {NONE} -- Access
|
||||||
|
|
||||||
service: WGI_SERVICE
|
-- service: WGI_SERVICE
|
||||||
-- Gateway Service
|
-- -- Gateway Service
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ feature -- Server
|
|||||||
create req.make (env, create {WGI_NINO_INPUT_STREAM}.make (a_socket), Current)
|
create req.make (env, create {WGI_NINO_INPUT_STREAM}.make (a_socket), Current)
|
||||||
create res.make (create {WGI_NINO_OUTPUT_STREAM}.make (a_socket), create {WGI_NINO_ERROR_STREAM}.make_stderr (a_socket.descriptor.out))
|
create res.make (create {WGI_NINO_OUTPUT_STREAM}.make (a_socket), create {WGI_NINO_ERROR_STREAM}.make_stderr (a_socket.descriptor.out))
|
||||||
req.set_meta_string_variable ("RAW_HEADER_DATA", a_headers_text)
|
req.set_meta_string_variable ("RAW_HEADER_DATA", a_headers_text)
|
||||||
|
|
||||||
create {G} exec.make (req, res)
|
create {G} exec.make (req, res)
|
||||||
exec.execute
|
exec.execute
|
||||||
res.flush
|
res.flush
|
||||||
@@ -161,7 +161,7 @@ feature -- Server
|
|||||||
end
|
end
|
||||||
if exec /= Void then
|
if exec /= Void then
|
||||||
exec.clean
|
exec.clean
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
if not retried then
|
if not retried then
|
||||||
@@ -171,7 +171,7 @@ feature -- Server
|
|||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
copyright: "2011-2015, 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: "[
|
||||||
Eiffel Software
|
Eiffel Software
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ feature {NONE} -- Initialization
|
|||||||
verbose := l_verbose_str.as_lower.same_string ("true")
|
verbose := l_verbose_str.as_lower.same_string ("true")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
create conn.make (Current)
|
create conn.make --(Current)
|
||||||
connector := conn
|
connector := conn
|
||||||
|
|
||||||
conn.on_launched_actions.extend (agent on_launched)
|
conn.on_launched_actions.extend (agent on_launched)
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ note
|
|||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
WSF_DEFAULT_RESPONSE_SERVICE
|
WSF_DEFAULT_RESPONSE_SERVICE [G -> WSF_EXECUTION create make end]
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
WSF_DEFAULT_SERVICE
|
WSF_DEFAULT_SERVICE [G]
|
||||||
|
|
||||||
WSF_RESPONSE_SERVICE
|
WSF_RESPONSE_SERVICE [G]
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
copyright: "2011-2015, 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: "[
|
||||||
Eiffel Software
|
Eiffel Software
|
||||||
|
|||||||
@@ -0,0 +1,291 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {WSF_ROUTED_SKELETON_EXECUTION}."
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
WSF_ROUTED_SKELETON_EXECUTION
|
||||||
|
|
||||||
|
inherit
|
||||||
|
WSF_ROUTED_EXECUTION
|
||||||
|
redefine
|
||||||
|
execute
|
||||||
|
end
|
||||||
|
|
||||||
|
WSF_SYSTEM_OPTIONS_ACCESS_POLICY
|
||||||
|
|
||||||
|
WSF_PROXY_USE_POLICY
|
||||||
|
|
||||||
|
feature -- Execution
|
||||||
|
|
||||||
|
execute
|
||||||
|
-- If the service is available, and request URI is not too long, dispatch the request
|
||||||
|
-- and if handler is not found, execute the default procedure `execute_default'.
|
||||||
|
local
|
||||||
|
l_sess: WSF_ROUTER_SESSION
|
||||||
|
req: WSF_REQUEST; res: WSF_RESPONSE
|
||||||
|
do
|
||||||
|
req := request
|
||||||
|
res := response
|
||||||
|
|
||||||
|
--| When we reach here, the request has already passed check for 400 (Bad request),
|
||||||
|
--| which is implemented in WSF_REQUEST.make_from_wgi (when it calls `analyze').
|
||||||
|
if unavailable then
|
||||||
|
handle_unavailable (res)
|
||||||
|
elseif requires_proxy (req) then
|
||||||
|
handle_use_proxy (req, res)
|
||||||
|
elseif
|
||||||
|
maximum_uri_length > 0 and then
|
||||||
|
req.request_uri.count.to_natural_32 > maximum_uri_length
|
||||||
|
then
|
||||||
|
handle_request_uri_too_long (res)
|
||||||
|
elseif
|
||||||
|
req.is_request_method ({HTTP_REQUEST_METHODS}.method_options) and then
|
||||||
|
req.request_uri.same_string ("*")
|
||||||
|
then
|
||||||
|
handle_server_options (req, res)
|
||||||
|
else
|
||||||
|
create l_sess
|
||||||
|
router.dispatch (req, res, l_sess)
|
||||||
|
if not l_sess.dispatched then
|
||||||
|
execute_default
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Measurement
|
||||||
|
|
||||||
|
maximum_uri_length: NATURAL
|
||||||
|
-- Maximum length in characters (or zero for no limit) permitted
|
||||||
|
-- for {WSF_REQUEST}.request_uri
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
unavailable: BOOLEAN
|
||||||
|
-- Is service currently unavailable?
|
||||||
|
|
||||||
|
unavailablity_message: detachable READABLE_STRING_8
|
||||||
|
-- Message to be included as text of response body for {HTTP_STATUS_CODE}.service_unavailable
|
||||||
|
|
||||||
|
unavailability_duration: NATURAL
|
||||||
|
-- Delta seconds for service unavailability (0 if not known)
|
||||||
|
|
||||||
|
unavailable_until: detachable DATE_TIME
|
||||||
|
-- Time at which service becomes available again (if known)
|
||||||
|
|
||||||
|
feature -- Status setting
|
||||||
|
|
||||||
|
set_available
|
||||||
|
-- Set `unavailable' to `False'.
|
||||||
|
do
|
||||||
|
unavailable := False
|
||||||
|
unavailablity_message := Void
|
||||||
|
unavailable_until := Void
|
||||||
|
ensure
|
||||||
|
available: unavailable = False
|
||||||
|
unavailablity_message_detached: unavailablity_message = Void
|
||||||
|
unavailable_until_detached: unavailable_until = Void
|
||||||
|
end
|
||||||
|
|
||||||
|
set_unavailable (a_message: READABLE_STRING_8; a_duration: NATURAL; a_until: detachable DATE_TIME)
|
||||||
|
-- Set `unavailable' to `True'.
|
||||||
|
require
|
||||||
|
a_message_attached: a_message /= Void
|
||||||
|
a_duration_xor_a_until: a_duration > 0 implies a_until = Void
|
||||||
|
do
|
||||||
|
unavailable := True
|
||||||
|
unavailablity_message := a_message
|
||||||
|
unavailability_duration := a_duration
|
||||||
|
ensure
|
||||||
|
unavailable: unavailable = True
|
||||||
|
unavailablity_message_aliased: unavailablity_message = a_message
|
||||||
|
unavailability_duration_set: unavailability_duration = a_duration
|
||||||
|
unavailable_until_aliased: unavailable_until = a_until
|
||||||
|
end
|
||||||
|
|
||||||
|
set_maximum_uri_length (a_len: NATURAL)
|
||||||
|
-- Set `maximum_uri_length' to `a_len'.
|
||||||
|
-- Can pass zero to mean no restrictions.
|
||||||
|
do
|
||||||
|
maximum_uri_length := a_len
|
||||||
|
ensure
|
||||||
|
maximum_uri_length_set: maximum_uri_length = a_len
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
handle_unavailable (res: WSF_RESPONSE)
|
||||||
|
-- Write "Service unavailable" response to `res'.
|
||||||
|
require
|
||||||
|
unavailable: unavailable
|
||||||
|
res_attached: res /= Void
|
||||||
|
local
|
||||||
|
h: HTTP_HEADER
|
||||||
|
do
|
||||||
|
create h.make
|
||||||
|
h.put_content_type_text_plain
|
||||||
|
check attached unavailablity_message as m then
|
||||||
|
-- invariant `unavailability_message_attached' plus precondition `unavailable'
|
||||||
|
h.put_content_length (m.count)
|
||||||
|
h.put_current_date
|
||||||
|
res.set_status_code ({HTTP_STATUS_CODE}.service_unavailable)
|
||||||
|
if unavailability_duration > 0 then
|
||||||
|
h.put_header_key_value ({HTTP_HEADER_NAMES}.header_retry_after, unavailability_duration.out)
|
||||||
|
elseif attached unavailable_until as u then
|
||||||
|
h.put_header_key_value ({HTTP_HEADER_NAMES}.header_retry_after,
|
||||||
|
h.date_to_rfc1123_http_date_format (u))
|
||||||
|
end
|
||||||
|
res.put_header_text (h.string)
|
||||||
|
res.put_string (m)
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
response_status_is_set: res.status_is_set
|
||||||
|
status_is_service_unavailable: res.status_code = {HTTP_STATUS_CODE}.service_unavailable
|
||||||
|
body_sent: res.message_committed and then res.transfered_content_length > 0
|
||||||
|
body_content_was_unavailablity_message: True -- doesn't seem to be any way to check
|
||||||
|
end
|
||||||
|
|
||||||
|
handle_request_uri_too_long (res: WSF_RESPONSE)
|
||||||
|
-- Write "Request URI too long" response into `res'.
|
||||||
|
require
|
||||||
|
res_attached: res /= Void
|
||||||
|
local
|
||||||
|
h: HTTP_HEADER
|
||||||
|
m: READABLE_STRING_8
|
||||||
|
do
|
||||||
|
create h.make
|
||||||
|
h.put_content_type_text_plain
|
||||||
|
h.put_current_date
|
||||||
|
m := "Maximum permitted length for request URI is " + maximum_uri_length.out + " characters"
|
||||||
|
h.put_content_length (m.count)
|
||||||
|
res.set_status_code ({HTTP_STATUS_CODE}.request_uri_too_long)
|
||||||
|
res.put_header_text (h.string)
|
||||||
|
res.put_string (m)
|
||||||
|
ensure
|
||||||
|
response_status_is_set: res.status_is_set
|
||||||
|
status_is_request_uri_too_long: res.status_code = {HTTP_STATUS_CODE}.request_uri_too_long
|
||||||
|
body_sent: res.message_committed and then res.transfered_content_length > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
frozen handle_server_options (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- Write response to OPTIONS * into `res'.
|
||||||
|
require
|
||||||
|
req_attached: req /= Void
|
||||||
|
res_attached: res /= Void
|
||||||
|
method_is_options: req.is_request_method ({HTTP_REQUEST_METHODS}.method_options)
|
||||||
|
server_options_requested: req.request_uri.same_string ("*")
|
||||||
|
do
|
||||||
|
--| First check if forbidden.
|
||||||
|
--| (N.B. authentication requires an absoluteURI (RFC3617 page 3), and so cannot be used for OPTIONS *.
|
||||||
|
--| Otherwise construct an Allow response automatically from the router.
|
||||||
|
if is_system_options_forbidden (req) then
|
||||||
|
handle_system_options_forbidden (req, res)
|
||||||
|
else
|
||||||
|
handle_system_options (req, res)
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
response_status_is_set: res.status_is_set
|
||||||
|
valid_response_code: res.status_code = {HTTP_STATUS_CODE}.forbidden or
|
||||||
|
res.status_code = {HTTP_STATUS_CODE}.not_found or res.status_code = {HTTP_STATUS_CODE}.ok
|
||||||
|
header_sent: res.header_committed and res.message_committed
|
||||||
|
end
|
||||||
|
|
||||||
|
frozen handle_system_options_forbidden (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- Write a 403 Forbidden or a 404 Not found response into `res'.
|
||||||
|
require
|
||||||
|
req_attached: req /= Void
|
||||||
|
res_attached: res /= Void
|
||||||
|
method_is_options: req.is_request_method ({HTTP_REQUEST_METHODS}.method_options)
|
||||||
|
server_options_requested: req.request_uri.same_string ("*")
|
||||||
|
local
|
||||||
|
m: detachable READABLE_STRING_8
|
||||||
|
h: HTTP_HEADER
|
||||||
|
do
|
||||||
|
m := system_options_forbidden_text (req)
|
||||||
|
if attached {READABLE_STRING_8} m as l_msg then
|
||||||
|
create h.make
|
||||||
|
h.put_content_type_text_plain
|
||||||
|
h.put_current_date
|
||||||
|
h.put_content_length (l_msg.count)
|
||||||
|
res.set_status_code ({HTTP_STATUS_CODE}.forbidden)
|
||||||
|
res.put_header_text (h.string)
|
||||||
|
res.put_string (l_msg)
|
||||||
|
else
|
||||||
|
create h.make
|
||||||
|
h.put_content_type_text_plain
|
||||||
|
h.put_current_date
|
||||||
|
h.put_content_length (0)
|
||||||
|
res.set_status_code ({HTTP_STATUS_CODE}.not_found)
|
||||||
|
res.put_header_text (h.string)
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
response_status_is_set: res.status_is_set
|
||||||
|
valid_response_code: res.status_code = {HTTP_STATUS_CODE}.forbidden or
|
||||||
|
res.status_code = {HTTP_STATUS_CODE}.not_found
|
||||||
|
header_sent: res.header_committed
|
||||||
|
message_sent: res.message_committed
|
||||||
|
end
|
||||||
|
|
||||||
|
handle_system_options (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- Write response to OPTIONS * into `res'.
|
||||||
|
-- This may be redefined by the user, but normally this will not be necessary.
|
||||||
|
require
|
||||||
|
req_attached: req /= Void
|
||||||
|
res_attached: res /= Void
|
||||||
|
method_is_options: req.is_request_method ({HTTP_REQUEST_METHODS}.method_options)
|
||||||
|
server_options_requested: req.request_uri.same_string ("*")
|
||||||
|
local
|
||||||
|
h: HTTP_HEADER
|
||||||
|
do
|
||||||
|
create h.make
|
||||||
|
h.put_content_type_text_plain
|
||||||
|
h.put_current_date
|
||||||
|
h.put_allow (router.all_allowed_methods)
|
||||||
|
h.put_content_length (0)
|
||||||
|
res.set_status_code ({HTTP_STATUS_CODE}.ok)
|
||||||
|
res.put_header_text (h.string)
|
||||||
|
ensure
|
||||||
|
response_status_is_set: res.status_is_set
|
||||||
|
response_code_ok: res.status_code = {HTTP_STATUS_CODE}.ok
|
||||||
|
header_sent: res.header_committed and res.message_committed
|
||||||
|
empty_body: res.transfered_content_length = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
frozen handle_use_proxy (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- Write Use Proxy response `res'.
|
||||||
|
require
|
||||||
|
res_attached: res /= Void
|
||||||
|
req_attached: req /= Void
|
||||||
|
proxy_required: requires_proxy (req)
|
||||||
|
local
|
||||||
|
h: HTTP_HEADER
|
||||||
|
do
|
||||||
|
create h.make
|
||||||
|
h.put_content_type_text_plain
|
||||||
|
h.put_current_date
|
||||||
|
h.put_location (proxy_server (req).string)
|
||||||
|
h.put_content_length (0)
|
||||||
|
res.put_header_lines (h)
|
||||||
|
res.set_status_code ({HTTP_STATUS_CODE}.use_proxy)
|
||||||
|
ensure
|
||||||
|
response_status_is_set: res.status_is_set
|
||||||
|
response_code_use_proxy: res.status_code = {HTTP_STATUS_CODE}.use_proxy
|
||||||
|
end
|
||||||
|
|
||||||
|
invariant
|
||||||
|
|
||||||
|
unavailability_message_attached: unavailable implies attached unavailablity_message as m and then
|
||||||
|
m.count > 0
|
||||||
|
unavailability_duration_xor_unavailable_until: unavailability_duration > 0 implies unavailable_until = Void
|
||||||
|
|
||||||
|
;note
|
||||||
|
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
source: "[
|
||||||
|
Eiffel Software
|
||||||
|
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||||
|
Telephone 805-685-1006, Fax 805-685-6869
|
||||||
|
Website http://www.eiffel.com
|
||||||
|
Customer support http://support.eiffel.com
|
||||||
|
]"
|
||||||
|
end
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
note
|
||||||
|
description: "Facilities inheritance to add URI base routing to a routed execution"
|
||||||
|
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class WSF_URI_HELPER_FOR_ROUTED_EXECUTION
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
router: WSF_ROUTER
|
||||||
|
-- Router used to dispatch the request according to the WSF_REQUEST object
|
||||||
|
-- and associated request methods;
|
||||||
|
-- This should not be implemented by descendants. Instead, you gain an effective
|
||||||
|
-- version by also inheriting from WSF_ROUTED_EXECUTION, or one of it's descendants.
|
||||||
|
deferred
|
||||||
|
ensure
|
||||||
|
router_not_void: Result /= Void
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Mapping helper: uri
|
||||||
|
|
||||||
|
map_uri (a_uri: READABLE_STRING_8; h: WSF_URI_HANDLER)
|
||||||
|
-- Map `h' as handler for `a_uri'
|
||||||
|
do
|
||||||
|
map_uri_with_request_methods (a_uri, h, Void)
|
||||||
|
end
|
||||||
|
|
||||||
|
map_uri_with_request_methods (a_uri: READABLE_STRING_8; h: WSF_URI_HANDLER; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||||
|
-- Map `h' as handler for `a_uri' for request methods `rqst_methods'.
|
||||||
|
do
|
||||||
|
router.map_with_request_methods (create {WSF_URI_MAPPING}.make (a_uri, h), rqst_methods)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Mapping helper: uri agent
|
||||||
|
|
||||||
|
map_uri_agent (a_uri: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]])
|
||||||
|
-- Map `proc' as handler for `a_uri'
|
||||||
|
do
|
||||||
|
map_uri_agent_with_request_methods (a_uri, proc, Void)
|
||||||
|
end
|
||||||
|
|
||||||
|
map_uri_agent_with_request_methods (a_uri: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||||
|
-- Map `proc' as handler for `a_uri' for request methods `rqst_methods'.
|
||||||
|
do
|
||||||
|
map_uri_with_request_methods (a_uri, create {WSF_URI_AGENT_HANDLER}.make (proc), rqst_methods)
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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,73 @@
|
|||||||
|
note
|
||||||
|
description: "Facilities inheritance to add URI template-base routing to a routed execution"
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
WSF_URI_TEMPLATE_HELPER_FOR_ROUTED_EXECUTION
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
router: WSF_ROUTER
|
||||||
|
-- Router used to dispatch the request according to the WSF_REQUEST object
|
||||||
|
-- and associated request methods;
|
||||||
|
-- This should not be implemented by descendants. Instead, you gain an effective
|
||||||
|
-- version by also inheriting from WSF_ROUTED_SERVICE, or one of it's descendants.
|
||||||
|
deferred
|
||||||
|
ensure
|
||||||
|
router_not_void: Result /= Void
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Mapping helper: uri template
|
||||||
|
|
||||||
|
map_uri_template (a_tpl: STRING; h: WSF_URI_TEMPLATE_HANDLER)
|
||||||
|
-- Map `h' as handler for `a_tpl'
|
||||||
|
require
|
||||||
|
a_tpl_attached: a_tpl /= Void
|
||||||
|
h_attached: h /= Void
|
||||||
|
do
|
||||||
|
map_uri_template_with_request_methods (a_tpl, h, Void)
|
||||||
|
end
|
||||||
|
|
||||||
|
map_uri_template_with_request_methods (a_tpl: READABLE_STRING_8; h: WSF_URI_TEMPLATE_HANDLER; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||||
|
-- Map `h' as handler for `a_tpl' for request methods `rqst_methods'.
|
||||||
|
require
|
||||||
|
a_tpl_attached: a_tpl /= Void
|
||||||
|
h_attached: h /= Void
|
||||||
|
do
|
||||||
|
router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make (a_tpl, h), rqst_methods)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Mapping helper: uri template agent
|
||||||
|
|
||||||
|
map_uri_template_agent (a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]])
|
||||||
|
-- Map `proc' as handler for `a_tpl'
|
||||||
|
require
|
||||||
|
a_tpl_attached: a_tpl /= Void
|
||||||
|
proc_attached: proc /= Void
|
||||||
|
do
|
||||||
|
map_uri_template_agent_with_request_methods (a_tpl, proc, Void)
|
||||||
|
end
|
||||||
|
|
||||||
|
map_uri_template_agent_with_request_methods (a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_REQUEST_METHODS)
|
||||||
|
-- Map `proc' as handler for `a_tpl' for request methods `rqst_methods'.
|
||||||
|
require
|
||||||
|
a_tpl_attached: a_tpl /= Void
|
||||||
|
proc_attached: proc /= Void
|
||||||
|
do
|
||||||
|
map_uri_template_with_request_methods (a_tpl, create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (proc), rqst_methods)
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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
|
||||||
76
library/server/wsf/router/wsf_routed_execution.e
Normal file
76
library/server/wsf/router/wsf_routed_execution.e
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {WSF_ROUTED_EXECUTION}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
WSF_ROUTED_EXECUTION
|
||||||
|
|
||||||
|
feature -- Router
|
||||||
|
|
||||||
|
initialize_router
|
||||||
|
-- Initialize router
|
||||||
|
do
|
||||||
|
create_router
|
||||||
|
setup_router
|
||||||
|
end
|
||||||
|
|
||||||
|
create_router
|
||||||
|
-- Create `router'
|
||||||
|
--| could be redefine to initialize with proper capacity
|
||||||
|
do
|
||||||
|
create router.make (10)
|
||||||
|
ensure
|
||||||
|
router_created: router /= Void
|
||||||
|
end
|
||||||
|
|
||||||
|
setup_router
|
||||||
|
-- Setup `router'
|
||||||
|
require
|
||||||
|
router_created: router /= Void
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
request: WSF_REQUEST
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
response: WSF_RESPONSE
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
router: WSF_ROUTER
|
||||||
|
-- Router used to dispatch the request according to the WSF_REQUEST object
|
||||||
|
-- and associated request methods
|
||||||
|
|
||||||
|
feature -- Execution
|
||||||
|
|
||||||
|
execute
|
||||||
|
-- Dispatch the request
|
||||||
|
-- and if handler is not found, execute the default procedure `execute_default'.
|
||||||
|
local
|
||||||
|
sess: WSF_ROUTER_SESSION
|
||||||
|
do
|
||||||
|
create sess
|
||||||
|
router.dispatch (request, response, sess)
|
||||||
|
if not sess.dispatched then
|
||||||
|
execute_default
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
response_status_is_set: response.status_is_set
|
||||||
|
end
|
||||||
|
|
||||||
|
execute_default
|
||||||
|
-- Dispatch requests without a matching handler.
|
||||||
|
local
|
||||||
|
msg: WSF_DEFAULT_ROUTER_RESPONSE
|
||||||
|
do
|
||||||
|
create msg.make_with_router (request, router)
|
||||||
|
msg.set_documentation_included (True)
|
||||||
|
response.send (msg)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -28,6 +28,14 @@ feature {NONE} -- Initialization
|
|||||||
Precursor (req, res)
|
Precursor (req, res)
|
||||||
create request.make_from_wgi (wgi_request)
|
create request.make_from_wgi (wgi_request)
|
||||||
create response.make_from_wgi (wgi_response)
|
create response.make_from_wgi (wgi_response)
|
||||||
|
initialize
|
||||||
|
end
|
||||||
|
|
||||||
|
initialize
|
||||||
|
-- Initialize Current object.
|
||||||
|
--| To be redefined if needed.
|
||||||
|
do
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Access
|
feature {NONE} -- Access
|
||||||
|
|||||||
Reference in New Issue
Block a user