Merge branch 'master' of github.com:Eiffel-World/Eiffel-Web-Framework

This commit is contained in:
Jocelyn Fiat
2011-10-27 14:43:32 +02:00
140 changed files with 5598 additions and 2843 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
EIFGENs EIFGENs
tests/temp/ tests/temp/
.svn/

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="hello_routed_world" uuid="7C9887BD-4AE4-47F2-A0AA-4BBB6736D433"> <system xmlns="http://www.eiffel.com/developers/xml/configuration-1-9-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-9-0 http://www.eiffel.com/developers/xml/configuration-1-9-0.xsd" name="hello_routed_world" uuid="7C9887BD-4AE4-47F2-A0AA-4BBB6736D433">
<target name="hello_routed_world"> <target name="hello_routed_world">
<root class="HELLO_ROUTED_WORLD" feature="make"/> <root class="HELLO_ROUTED_WORLD" feature="make"/>
<file_rule> <file_rule>
@@ -8,14 +8,14 @@
<exclude>/\.svn$</exclude> <exclude>/\.svn$</exclude>
</file_rule> </file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional"> <option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
<assertions precondition="true" postcondition="true" invariant="true" supplier_precondition="true"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" supplier_precondition="true"/>
</option> </option>
<setting name="concurrency" value="thread"/> <setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="connector_nino" location="..\..\library\server\ewsgi\connectors\nino\nino-safe.ecf" readonly="false"/> <library name="connector_nino" location="..\..\library\server\ewsgi\connectors\nino\nino-safe.ecf" readonly="false"/>
<library name="default_nino" location="..\..\library\server\ewsgi\default\ewsgi_nino-safe.ecf" readonly="false"/> <library name="default_nino" location="..\..\library\server\wsf\default\nino-safe.ecf" readonly="false"/>
<library name="encoder" location="..\..\library\text\encoder\encoder-safe.ecf" readonly="false"/> <library name="encoder" location="..\..\library\text\encoder\encoder-safe.ecf" readonly="false"/>
<library name="ewsgi" location="..\..\library\server\ewsgi\ewsgi-safe.ecf" readonly="false"/> <library name="wsf" location="..\..\library\server\wsf\wsf-safe.ecf" readonly="false"/>
<library name="http" location="..\..\library\protocol\http\http-safe.ecf" readonly="false"/> <library name="http" location="..\..\library\protocol\http\http-safe.ecf" readonly="false"/>
<library name="router" location="..\..\library\server\request\router\router-safe.ecf" readonly="false"/> <library name="router" location="..\..\library\server\request\router\router-safe.ecf" readonly="false"/>
<library name="uri_template" location="..\..\library\protocol\uri_template\uri_template-safe.ecf" readonly="false"/> <library name="uri_template" location="..\..\library\protocol\uri_template\uri_template-safe.ecf" readonly="false"/>

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>Hello Eiffel::default</title>
<link rel="stylesheet" href="../style.css" type="text/css" media="all" />
</head>
<body>
<h1>Hello Eiffel Default World</h1>
</body>
</html>

View File

@@ -0,0 +1,9 @@
<html>
<head>
<title>Hello Eiffel</title>
<link rel="stylesheet" href="style.css" type="text/css" media="all" />
</head>
<body>
<h1>Hello Eiffel World :D</h1>
</body>
</html>

Binary file not shown.

View File

@@ -0,0 +1 @@
h1 { border: solid 1px #00f; margin: 5px; padding: 5px; }

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,7 @@ inherit
ROUTED_APPLICATION_HELPER ROUTED_APPLICATION_HELPER
DEFAULT_WGI_APPLICATION DEFAULT_APPLICATION
create create
make make
@@ -30,7 +30,6 @@ feature {NONE} -- Initialization
create_router create_router
do do
check False end
create router.make (5) create router.make (5)
end end
@@ -38,8 +37,13 @@ feature {NONE} -- Initialization
local local
ra: REQUEST_AGENT_HANDLER [REQUEST_URI_TEMPLATE_HANDLER_CONTEXT] ra: REQUEST_AGENT_HANDLER [REQUEST_URI_TEMPLATE_HANDLER_CONTEXT]
hello: REQUEST_URI_TEMPLATE_ROUTING_HANDLER hello: REQUEST_URI_TEMPLATE_ROUTING_HANDLER
www: REQUEST_FILE_SYSTEM_HANDLER [REQUEST_URI_TEMPLATE_HANDLER_CONTEXT]
do do
router.map_agent ("/home", agent execute_home) router.map_agent ("/home", agent execute_home)
create www.make (document_root)
www.set_directory_index (<<"index.html">>)
router.map ("/www{/path}{?query}", www)
--| Map all "/hello*" using a ROUTING_HANDLER --| Map all "/hello*" using a ROUTING_HANDLER
create hello.make (3) create hello.make (3)
@@ -61,55 +65,86 @@ feature {NONE} -- Initialization
router.map_agent_with_request_methods ("/method/custom", agent handle_method_post, <<"POST">>) router.map_agent_with_request_methods ("/method/custom", agent handle_method_post, <<"POST">>)
end end
document_root: READABLE_STRING_8
local
e: EXECUTION_ENVIRONMENT
dn: DIRECTORY_NAME
once
create e
create dn.make_from_string (e.current_working_directory)
dn.extend ("htdocs")
Result := dn.string
if Result[Result.count] = Operating_environment.directory_separator then
Result := Result.substring (1, Result.count - 1)
end
end
feature -- Execution feature -- Execution
execute_default (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_default (req: WSF_REQUEST; res: WSF_RESPONSE)
local local
h: EWF_HEADER h: WSF_HEADER
l_url: STRING l_url: STRING
e: EXECUTION_ENVIRONMENT e: EXECUTION_ENVIRONMENT
n: INTEGER n: INTEGER
i: INTEGER i: INTEGER
s: STRING_8
do do
l_url := req.script_url ("/home") l_url := req.script_url ("/home")
n := 3 n := 3
create h.make create h.make
h.put_refresh (l_url, 5) h.put_refresh (l_url, 5)
h.put_content_type_text_plain
h.put_transfer_encoding_chunked
-- h.put_content_length (0)
res.set_status_code ({HTTP_STATUS_CODE}.moved_permanently) res.set_status_code ({HTTP_STATUS_CODE}.moved_permanently)
res.write_headers_string (h.string) res.write_headers_string (h.string)
from from
create e create e
create s.make (255)
until until
n = 0 n = 0
loop loop
if n > 1 then if n > 1 then
res.write_string ("Redirected to " + l_url + " in " + n.out + " seconds :%N") s.append ("%NRedirected to " + l_url + " in " + n.out + " seconds :%N")
else else
res.write_string ("Redirected to " + l_url + " in 1 second :%N") s.append ("%NRedirected to " + l_url + " in 1 second :%N")
end end
res.flush write_chunk (s, res); s.wipe_out
from from
i := 1 i := 1
until until
i = 1001 i = 1001
loop loop
res.write_string (".") s.append_character ('.')
if i \\ 100 = 0 then if i \\ 100 = 0 then
res.write_string ("%N") s.append_character ('%N')
end end
res.flush write_chunk (s, res); s.wipe_out
e.sleep (1_000_000) e.sleep (1_000_000)
i := i + 1 i := i + 1
end end
res.write_string ("%N")
n := n - 1 n := n - 1
end end
res.write_string ("You are now being redirected...%N") s.append ("%NYou are now being redirected...%N")
write_chunk (s, res); s.wipe_out
write_chunk (Void, res)
end
write_chunk (s: detachable READABLE_STRING_8; res: WSF_RESPONSE)
do
if s /= Void then
res.write_string (s.count.to_hex_string + {HTTP_CONSTANTS}.crlf)
res.write_string (s)
else
res.write_string ("0" + {HTTP_CONSTANTS}.crlf)
end
res.flush res.flush
end end
execute_home (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_home (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
local local
l_body: STRING_8 l_body: STRING_8
do do
@@ -133,10 +168,10 @@ feature -- Execution
res.write_string (l_body) res.write_string (l_body)
end end
execute_hello (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_name: detachable READABLE_STRING_32; ctx: REQUEST_HANDLER_CONTEXT) execute_hello (req: WSF_REQUEST; res: WSF_RESPONSE; a_name: detachable READABLE_STRING_32; ctx: REQUEST_HANDLER_CONTEXT)
local local
l_response_content_type: detachable STRING l_response_content_type: detachable STRING
h: EWF_HEADER h: WSF_HEADER
content_type_supported: ARRAY [STRING] content_type_supported: ARRAY [STRING]
l_body: STRING_8 l_body: STRING_8
do do
@@ -172,33 +207,33 @@ feature -- Execution
end end
end end
handle_hello (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) handle_hello (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
execute_hello (req, res, Void, ctx) execute_hello (req, res, Void, ctx)
end end
handle_anonymous_hello (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) handle_anonymous_hello (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
execute_hello (req, res, ctx.string_parameter ("name"), ctx) execute_hello (req, res, ctx.string_parameter ("name"), ctx)
end end
handle_method_any (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) handle_method_any (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
execute_hello (req, res, req.request_method, ctx) execute_hello (req, res, req.request_method, ctx)
end end
handle_method_get (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) handle_method_get (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
execute_hello (req, res, "GET", ctx) execute_hello (req, res, "GET", ctx)
end end
handle_method_post (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) handle_method_post (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
execute_hello (req, res, "POST", ctx) execute_hello (req, res, "POST", ctx)
end end
handle_method_get_or_post (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) handle_method_get_or_post (ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
execute_hello (req, res, "GET or POST", ctx) execute_hello (req, res, "GET or POST", ctx)
end end

View File

@@ -0,0 +1,11 @@
Make sure to have the Clib generated in the related cURL library
- if you use EiffelStudio >= 7.0
check %ISE_LIBRARY%\library\cURL\spec\%ISE_C_COMPILER%\$ISE_PLATFORM
or $ISE_LIBRARY/library/cURL/spec/$ISE_PLATFORM
- otherwise if you use earlier version
check under ext/ise_library/curl/spec/...
And on Windows, be sure to get the libcurl.dll from %ISE_LIBRARY%\studio\spec\%ISE_PLATFORM%\bin\libcurl.dll

View File

@@ -13,9 +13,9 @@
<setting name="concurrency" value="thread"/> <setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="connector_nino" location="..\..\library\server\ewsgi\connectors\nino\nino-safe.ecf" readonly="false"/> <library name="connector_nino" location="..\..\library\server\ewsgi\connectors\nino\nino-safe.ecf" readonly="false"/>
<library name="default_nino" location="..\..\library\server\ewsgi\default\ewsgi_nino-safe.ecf" readonly="false"/> <library name="default_nino" location="..\..\library\server\wsf\default\nino-safe.ecf" readonly="false"/>
<library name="encoder" location="..\..\library\text\encoder\encoder-safe.ecf" readonly="false"/> <library name="encoder" location="..\..\library\text\encoder\encoder-safe.ecf" readonly="false"/>
<library name="ewsgi" location="..\..\library\server\ewsgi\ewsgi-safe.ecf" readonly="false"/> <library name="wsf" location="..\..\library\server\wsf\wsf-safe.ecf" readonly="false"/>
<library name="json" location="..\..\ext\text\json\library\json-safe.ecf" readonly="false"/> <library name="json" location="..\..\ext\text\json\library\json-safe.ecf" readonly="false"/>
<library name="http" location="..\..\library\protocol\http\http-safe.ecf" readonly="false"/> <library name="http" location="..\..\library\protocol\http\http-safe.ecf" readonly="false"/>
<library name="router" location="..\..\library\server\request\router\router-safe.ecf" readonly="false"/> <library name="router" location="..\..\library\server\request\router\router-safe.ecf" readonly="false"/>

View File

@@ -22,7 +22,7 @@ inherit
feature -- execute feature -- execute
execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler -- Execute request handler
do do
execute_methods (ctx, req, res) execute_methods (ctx, req, res)
@@ -34,7 +34,7 @@ feature -- API DOC
feature -- HTTP Methods feature -- HTTP Methods
do_get (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) do_get (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
-- Using GET to retrieve resource information. -- Using GET to retrieve resource information.
-- If the GET request is SUCCESS, we response with -- If the GET request is SUCCESS, we response with
-- 200 OK, and a representation of the order -- 200 OK, and a representation of the order
@@ -53,9 +53,9 @@ feature -- HTTP Methods
end end
end end
compute_response_get (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; l_order : ORDER) compute_response_get (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE; l_order : ORDER)
local local
h: EWF_HEADER h: WSF_HEADER
l_msg : STRING l_msg : STRING
do do
create h.make create h.make
@@ -73,12 +73,12 @@ feature -- HTTP Methods
end end
end end
do_put (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) do_put (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
local local
l_post: STRING l_post: STRING
l_location : STRING l_location : STRING
l_order : detachable ORDER l_order : detachable ORDER
h : EWF_HEADER h : WSF_HEADER
do do
fixme ("TODO handle an Internal Server Error") fixme ("TODO handle an Internal Server Error")
fixme ("Refactor the code, create new abstractions") fixme ("Refactor the code, create new abstractions")
@@ -111,10 +111,10 @@ feature -- HTTP Methods
end end
end end
do_delete (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) do_delete (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
local local
id: STRING id: STRING
h : EWF_HEADER h : WSF_HEADER
do do
fixme ("TODO handle an Internal Server Error") fixme ("TODO handle an Internal Server Error")
fixme ("Refactor the code, create new abstractions") fixme ("Refactor the code, create new abstractions")
@@ -136,7 +136,7 @@ feature -- HTTP Methods
end end
end end
do_post (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) do_post (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
-- Here the convention is the following. -- Here the convention is the following.
-- POST is used for creation and the server determines the URI -- POST is used for creation and the server determines the URI
-- of the created resource. -- of the created resource.
@@ -158,9 +158,9 @@ feature -- HTTP Methods
end end
end end
compute_response_post (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; l_order : ORDER) compute_response_post (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE; l_order : ORDER)
local local
h: EWF_HEADER h: WSF_HEADER
l_msg : STRING l_msg : STRING
l_location : STRING l_location : STRING
joc : JSON_ORDER_CONVERTER joc : JSON_ORDER_CONVERTER

View File

@@ -14,7 +14,7 @@ inherit
ROUTED_APPLICATION_HELPER ROUTED_APPLICATION_HELPER
DEFAULT_WGI_APPLICATION DEFAULT_APPLICATION
create create
make make
@@ -43,12 +43,12 @@ feature {NONE} -- Initialization
feature -- Execution feature -- Execution
execute_default (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_default (req: WSF_REQUEST; res: WSF_RESPONSE)
-- I'm using this method to handle the method not allowed response -- I'm using this method to handle the method not allowed response
-- in the case that the given uri does not have a corresponding http method -- in the case that the given uri does not have a corresponding http method
-- to handle it. -- to handle it.
local local
h : EWF_HEADER h : WSF_HEADER
l_description : STRING l_description : STRING
l_api_doc : STRING l_api_doc : STRING
do do

View File

@@ -7,7 +7,7 @@
<exclude>/EIFGENs$</exclude> <exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude> <exclude>/.svn$</exclude>
</file_rule> </file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all"> <option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
<assertions precondition="true"/> <assertions precondition="true"/>
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>

View File

@@ -7,7 +7,7 @@
<exclude>/EIFGENs$</exclude> <exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude> <exclude>/.svn$</exclude>
</file_rule> </file_rule>
<option warning="true" full_class_checking="true"> <option warning="true" full_class_checking="true" syntax="provisional">
<assertions precondition="true"/> <assertions precondition="true"/>
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>

View File

@@ -31,6 +31,8 @@ feature -- Server, header
feature -- Misc feature -- Misc
crlf: STRING = "%R%N"
default_bufsize: INTEGER = 16384 --| 16K default_bufsize: INTEGER = 16384 --| 16K
note note

View File

@@ -0,0 +1,238 @@
note
description: "[
Various common MIME types for file extensions
See also for longer list and description
http://www.webmaster-toolkit.com/mime-types.shtml
Please suggest missing entries
]"
date: "$Date$"
revision: "$Revision$"
class
HTTP_FILE_EXTENSION_MIME_MAPPING
inherit
ANY
HTTP_MIME_TYPES
export
{NONE} all
end
create
make_empty,
make_default,
make_from_string,
make_from_file
feature {NONE} -- Initialization
make_empty (n: INTEGER)
-- Create with no mapping
-- but one can use `map' to add new mapping
do
create mapping.make (n)
mapping.compare_objects
end
make_default
-- Create with default limited mapping
-- One can use `map' to add new mapping
local
m: like mapping
do
create m.make (40)
mapping := m
m.compare_objects
m.force (text_css, "css")
m.force (text_html, "html")
m.force (text_xml, "xml")
m.force (application_json, "json")
m.force (application_javascript, "js")
m.force (application_rss_xml, "rss")
m.force (application_atom_xml, "atom")
m.force (image_x_ico, "ico")
m.force (image_gif, "gif")
m.force (image_jpeg, "jpeg")
m.force (image_jpg, "jpg")
m.force (image_png, "png")
m.force (application_zip, "zip")
m.force (application_x_bzip, "bz")
m.force (application_x_bzip2, "bz2")
m.force (application_x_gzip, "gz")
m.force (application_x_gzip, "gzip")
m.force (application_x_tar, "tar")
m.force (application_x_compressed, "tgz")
m.force (application_postscript, "ps")
m.force (application_pdf, "pdf")
m.force (application_x_shockwave_flash, "swf")
m.force (text_plain, "conf")
m.force (text_plain, "log")
m.force (text_plain, "text")
m.force (text_plain, "txt")
end
make_from_file (fn: READABLE_STRING_8)
-- Create with mime.types file
-- One can use `map' to add new mapping
local
f: RAW_FILE
do
create f.make (fn)
if f.exists and then f.is_readable then
make_empty (50)
f.open_read
from
f.read_line
until
f.exhausted or f.end_of_file
loop
add_mapping_line (f.last_string)
f.read_line
end
f.close
else
make_empty (0)
end
end
make_from_string (t: READABLE_STRING_8)
-- Set mapping from multiline string `t'
-- line should be formatted as in http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
--| # is a comment
--| mime-type space(s) extensions
local
i,j,n: INTEGER
do
make_empty (10)
n := t.count
if n > 0 then
from
i := 1
until
i = 0 or i > n
loop
j := t.index_of ('%N', i)
if j > 0 then
add_mapping_line (t.substring (i, j - 1))
i := j + 1
else
add_mapping_line (t.substring (i, n))
i := 0
end
end
end
end
feature -- Access
mime_type (ext: READABLE_STRING_8): detachable READABLE_STRING_8
-- Mime type for extension `ext'
do
Result := mapping.item (ext.as_lower)
end
feature -- Element change
map (e: READABLE_STRING_8; t: READABLE_STRING_8)
-- Add mapping extension `e' to mime type `t'
do
mapping.force (t, e.as_lower)
end
feature {NONE} -- Implementation
add_mapping_line (t: READABLE_STRING_8)
local
i,j,n: INTEGER
l_type, l_ext: READABLE_STRING_8
do
n := t.count
if n > 0 then
-- ignore blanks
i := next_non_blank_position (t, i)
if i > 0 then
if t[i] = '#' then
--| ignore
else
j := next_blank_position (t, i)
if j > i then
l_type := t.substring (i, j - 1)
from
until
i = 0
loop
i := next_non_blank_position (t, j)
if i > 0 then
j := next_blank_position (t, i)
if j = 0 then
l_ext := t.substring (i, n)
i := 0
else
l_ext := t.substring (i, j - 1)
i := j
end
map (l_ext, l_type)
end
end
end
end
end
end
end
next_blank_position (s: READABLE_STRING_8; p: INTEGER): INTEGER
local
i, n: INTEGER
do
n := s.count
from
i := p + 1
until
i > n or s[i].is_space
loop
i := i + 1
end
if i <= n then
Result := i
end
end
next_non_blank_position (s: READABLE_STRING_8; p: INTEGER): INTEGER
local
i, n: INTEGER
do
n := s.count
from
i := p + 1
until
i > n or not s[i].is_space
loop
i := i + 1
end
if i <= n then
Result := i
end
end
feature {NONE} -- Extension MIME mapping
mapping: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
invariant
mapping_keys_are_lowercase: across mapping as c all c.key.same_string (c.key.as_lower) end
note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -19,11 +19,7 @@ feature -- Content type : application
application_atom_xml: STRING = "application/atom+xml" application_atom_xml: STRING = "application/atom+xml"
-- atom application content-type header -- atom application content-type header
application_x_www_form_encoded: STRING = "application/x-www-form-urlencoded" application_force_download: STRING = "application/force-download"
-- Starting chars of form url-encoded data content-type header
application_octet_stream: STRING = "application/octet-stream"
-- Octet stream content-type header
application_javascript: STRING = "application/javascript" application_javascript: STRING = "application/javascript"
-- JavaScript application content-type header -- JavaScript application content-type header
@@ -31,25 +27,54 @@ feature -- Content type : application
application_json: STRING = "application/json" application_json: STRING = "application/json"
-- JSON application content-type header -- JSON application content-type header
application_octet_stream: STRING = "application/octet-stream"
-- Octet stream content-type header
application_pdf: STRING = "application/pdf" application_pdf: STRING = "application/pdf"
-- pdf application content-type header -- pdf application content-type header
application_postscript: STRING = "application/postscript"
-- postscript application content-type header
application_rss_xml: STRING = "application/rss+xml" application_rss_xml: STRING = "application/rss+xml"
-- rss application content-type header -- rss application content-type header
application_rtf: STRING = "application/rtf"
-- RTF application content-type header
application_xml: STRING = "application/xml" application_xml: STRING = "application/xml"
-- xml application content-type header -- xml application content-type header
application_x_shockwave_flash: STRING = "application/x-shockwave-flash"
application_x_compressed: STRING = "application/x-compressed" application_x_compressed: STRING = "application/x-compressed"
-- x-compressed application content-type header
application_x_gzip: STRING = "application/x-gzip"
application_zip: STRING = "application/zip" application_zip: STRING = "application/zip"
-- ZIP application content-type header
application_x_bzip: STRING = "application/x-bzip"
application_x_bzip2: STRING = "application/x-bzip2"
application_x_tar: STRING = "application/x-tar"
application_x_www_form_encoded: STRING = "application/x-www-form-urlencoded"
-- Starting chars of form url-encoded data content-type header
feature -- Content type : audio feature -- Content type : audio
audio_mpeg3: STRING = "audio/mpeg3"
audio_mpeg: STRING = "audio/mpeg"
audio_wav: STRING = "audio/wav"
feature -- Content type : image feature -- Content type : image
image_bmp: STRING = "image/bmp"
-- BMP image content-type header
image_gif: STRING = "image/gif" image_gif: STRING = "image/gif"
-- GIF image content-type header -- GIF image content-type header
@@ -65,6 +90,12 @@ feature -- Content type : image
image_svg_xml: STRING = "image/svg+xml" image_svg_xml: STRING = "image/svg+xml"
-- SVG+XML image content-type header -- SVG+XML image content-type header
image_tiff: STRING = "image/tiff"
-- TIFF image content-type header
image_x_ico: STRING = "image/x-ico"
-- ICO image content-type header
feature -- Content type : message feature -- Content type : message
message_http: STRING = "message/http" message_http: STRING = "message/http"
@@ -81,6 +112,8 @@ feature -- Content type : message
feature -- Content type : model feature -- Content type : model
model_vrml: STRING = "model/vrml"
feature -- Content type : multipart feature -- Content type : multipart
multipart_mixed: STRING = "multipart/mixed" multipart_mixed: STRING = "multipart/mixed"
@@ -95,6 +128,8 @@ feature -- Content type : multipart
multipart_encrypted: STRING = "multipart/encrypted" multipart_encrypted: STRING = "multipart/encrypted"
multipart_x_gzip: STRING = "multipart/x-gzip"
feature -- Content type : text feature -- Content type : text
text_css: STRING = "text/css" text_css: STRING = "text/css"
@@ -119,13 +154,23 @@ feature -- Content type : text
text_rtf: STRING = "text/rtf" text_rtf: STRING = "text/rtf"
-- rtf content-type header -- rtf content-type header
text_tab_separated_values: STRING = "text/tab-separated-values"
-- TSV text content-type header
text_xml: STRING = "text/xml" text_xml: STRING = "text/xml"
-- XML text content-type header -- XML text content-type header
text_vcard: STRING = "text/vcard" text_vcard: STRING = "text/vcard"
-- vcard text content-type header -- vcard text content-type header
feature -- Content type : video feature -- Content type : video
video_avi: STRING = "video/avi"
video_quicktime: STRING = "video/quicktime"
video_x_motion_jpeg: STRING = "video/x-motion-jpeg"
note note
copyright: "2011-2011, Eiffel Software and others" copyright: "2011-2011, Eiffel Software and others"

View File

@@ -51,7 +51,7 @@ feature -- Methods intented for actions
method_delete: STRING = "DELETE" method_delete: STRING = "DELETE"
-- Deletes the specified resource. -- Deletes the specified resource.
feature -- Other Methods feature -- Other Methods
method_connect: STRING = "CONNECT" method_connect: STRING = "CONNECT"

View File

@@ -189,7 +189,7 @@ feature -- Match
exp: URI_TEMPLATE_EXPRESSION exp: URI_TEMPLATE_EXPRESSION
vn, s,t: STRING vn, s,t: STRING
vv, path_vv: STRING vv, path_vv: STRING
l_vars, l_path_vars, l_query_vars: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL] l_vars, l_path_vars, l_query_vars: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
l_uri_count: INTEGER l_uri_count: INTEGER
tpl_count: INTEGER tpl_count: INTEGER
l_next_literal_separator: detachable STRING l_next_literal_separator: detachable STRING
@@ -274,7 +274,7 @@ feature -- Match
vv := "/" vv := "/"
nb := 0 nb := 0
until until
vv.is_empty or q + l_offset > a_uri.count vv.is_empty or q + l_offset + 1 > a_uri.count
loop loop
vv := next_path_variable_value (a_uri, q + l_offset + 1, l_next_literal_separator) vv := next_path_variable_value (a_uri, q + l_offset + 1, l_next_literal_separator)
l_offset := l_offset + vv.count + 1 l_offset := l_offset + vv.count + 1
@@ -414,7 +414,7 @@ feature {NONE} -- Implementation
end end
end end
import_path_style_parameters_into (a_content: STRING; res: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]) import_path_style_parameters_into (a_content: STRING; res: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8])
require require
a_content_attached: a_content /= Void a_content_attached: a_content /= Void
res_attached: res /= Void res_attached: res /= Void
@@ -422,7 +422,7 @@ feature {NONE} -- Implementation
import_custom_style_parameters_into (a_content, ';', res) import_custom_style_parameters_into (a_content, ';', res)
end end
import_form_style_parameters_into (a_content: STRING; res: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]) import_form_style_parameters_into (a_content: STRING; res: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8])
require require
a_content_attached: a_content /= Void a_content_attached: a_content /= Void
res_attached: res /= Void res_attached: res /= Void
@@ -430,14 +430,14 @@ feature {NONE} -- Implementation
import_custom_style_parameters_into (a_content, '&', res) import_custom_style_parameters_into (a_content, '&', res)
end end
import_custom_style_parameters_into (a_content: STRING; a_separator: CHARACTER; res: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]) import_custom_style_parameters_into (a_content: STRING; a_separator: CHARACTER; res: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8])
require require
a_content_attached: a_content /= Void a_content_attached: a_content /= Void
res_attached: res /= Void res_attached: res /= Void
local local
n, p, i, j: INTEGER n, p, i, j: INTEGER
s: STRING s: READABLE_STRING_8
l_name,l_value: STRING l_name, l_value: READABLE_STRING_8
do do
n := a_content.count n := a_content.count
if n > 0 then if n > 0 then

View File

@@ -24,30 +24,29 @@ feature {NONE} -- Initialization
make (create {like path_variables}.make (0), create {like query_variables}.make (0)) make (create {like path_variables}.make (0), create {like query_variables}.make (0))
end end
feature -- Access feature -- Access
path_variables: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL] path_variables: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
-- Variables being part of the path segments -- Variables being part of the path segments
query_variables: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL] query_variables: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
-- Variables being part of the query segments (i.e: after the ?) -- Variables being part of the query segments (i.e: after the ?)
feature -- Query feature -- Query
path_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 path_variable (n: READABLE_STRING_8): detachable READABLE_STRING_8
-- Value related to query variable name `n' -- Value related to query variable name `n'
do do
Result := path_variables.item (n) Result := path_variables.item (n)
end end
query_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 query_variable (n: READABLE_STRING_8): detachable READABLE_STRING_8
-- Value related to path variable name `n' -- Value related to path variable name `n'
do do
Result := query_variables.item (n) Result := query_variables.item (n)
end end
variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 variable (n: READABLE_STRING_8): detachable READABLE_STRING_8
-- Value related to variable name `n' -- Value related to variable name `n'
do do
Result := query_variable (n) Result := query_variable (n)
@@ -58,7 +57,7 @@ feature -- Query
feature -- Query: url-decoded feature -- Query: url-decoded
url_decoded_query_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 url_decoded_query_variable (n: READABLE_STRING_8): detachable READABLE_STRING_32
-- Unencoded value related to variable name `n' -- Unencoded value related to variable name `n'
do do
if attached query_variable (n) as v then if attached query_variable (n) as v then
@@ -66,7 +65,7 @@ feature -- Query: url-decoded
end end
end end
url_decoded_path_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 url_decoded_path_variable (n: READABLE_STRING_8): detachable READABLE_STRING_32
-- Unencoded value related to variable name `n' -- Unencoded value related to variable name `n'
do do
if attached path_variable (n) as v then if attached path_variable (n) as v then
@@ -74,7 +73,7 @@ feature -- Query: url-decoded
end end
end end
url_decoded_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 url_decoded_variable (n: READABLE_STRING_8): detachable READABLE_STRING_32
-- Unencoded value related to variable name `n' -- Unencoded value related to variable name `n'
do do
if attached variable (n) as v then if attached variable (n) as v then
@@ -84,7 +83,7 @@ feature -- Query: url-decoded
feature {NONE} -- Implementation feature {NONE} -- Implementation
url_decoded_string (s: READABLE_STRING_GENERAL): READABLE_STRING_32 url_decoded_string (s: READABLE_STRING_8): READABLE_STRING_32
do do
Result := url_encoder.decoded_string (s.as_string_8) Result := url_encoder.decoded_string (s.as_string_8)
end end

View File

@@ -10,6 +10,7 @@
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all"> <option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all">
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="connector" location="..\connector-safe.ecf" readonly="false"/>
<library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/> <library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/>
<library name="http" location="..\..\..\..\protocol\http\http-safe.ecf"/> <library name="http" location="..\..\..\..\protocol\http\http-safe.ecf"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>

View File

@@ -10,6 +10,7 @@
<option warning="true" full_class_checking="true"> <option warning="true" full_class_checking="true">
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="connector" location="..\connector.ecf" readonly="false"/>
<library name="ewsgi" location="..\..\ewsgi.ecf" readonly="false"/> <library name="ewsgi" location="..\..\ewsgi.ecf" readonly="false"/>
<library name="http" location="..\..\..\..\protocol\http\http.ecf"/> <library name="http" location="..\..\..\..\protocol\http\http.ecf"/>
<cluster name="src" location=".\src\" recursive="true"/> <cluster name="src" location=".\src\" recursive="true"/>

View File

@@ -1,38 +0,0 @@
note
description: "Summary description for {EWF_CGI_CONNECTOR}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
EWF_CGI_CONNECTOR
inherit
WGI_CONNECTOR
create
make
feature -- Execution
launch
local
req: WGI_REQUEST_FROM_TABLE
res: WGI_RESPONSE_STREAM_BUFFER
do
create req.make ((create {EXECUTION_ENVIRONMENT}).starting_environment_variables, create {EWF_CGI_INPUT_STREAM}.make)
create res.make (create {EWF_CGI_OUTPUT_STREAM}.make)
application.process (req, res)
end
note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -0,0 +1,55 @@
note
description: "Summary description for {WGI_CGI_CONNECTOR}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
WGI_CGI_CONNECTOR
inherit
WGI_CONNECTOR
create
make
feature -- Execution
launch
local
req: WGI_REQUEST_FROM_TABLE
res: detachable WGI_RESPONSE_STREAM_BUFFER
rescued: BOOLEAN
do
if not rescued then
create req.make ((create {EXECUTION_ENVIRONMENT}).starting_environment_variables, create {WGI_CGI_INPUT_STREAM}.make)
create res.make (create {WGI_CGI_OUTPUT_STREAM}.make)
application.execute (req, res)
else
if attached (create {EXCEPTION_MANAGER}).last_exception as e and then attached e.exception_trace as l_trace then
if res /= Void then
if not res.status_is_set then
res.write_header ({HTTP_STATUS_CODE}.internal_server_error, Void)
end
if res.message_writable then
res.write_string ("<pre>" + l_trace + "</pre>")
end
end
end
end
rescue
rescued := True
retry
end
note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,12 +1,12 @@
note note
description: "Summary description for EWF_CGI_INPUT_STREAM." description: "Summary description for WGI_CGI_INPUT_STREAM."
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."
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
class class
EWF_CGI_INPUT_STREAM WGI_CGI_INPUT_STREAM
inherit inherit
WGI_INPUT_STREAM WGI_INPUT_STREAM

View File

@@ -1,12 +1,12 @@
note note
description: "Summary description for EWF_CGI_OUTPUT_STREAM." description: "Summary description for WGI_CGI_OUTPUT_STREAM."
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."
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
class class
EWF_CGI_OUTPUT_STREAM WGI_CGI_OUTPUT_STREAM
inherit inherit
WGI_OUTPUT_STREAM WGI_OUTPUT_STREAM

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="connector" uuid="61FBBC8E-558A-4079-920E-204946E54EFB" library_target="connector">
<target name="connector">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard">
</option>
<library name="base" location="$ISE_LIBRARY/library/base/base-safe.ecf"/>
<library name="ewsgi" location="../ewsgi-safe.ecf"/>
<cluster name="common" location="./common" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="connector" uuid="61FBBC8E-558A-4079-920E-204946E54EFB" library_target="connector">
<target name="connector">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" void_safety="none" syntax="standard">
</option>
<library name="base" location="$ISE_LIBRARY/library/base/base.ecf"/>
<library name="ewsgi" location="../ewsgi.ecf"/>
<cluster name="common" location="./common" recursive="true"/>
</target>
</system>

View File

@@ -10,6 +10,7 @@
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all"> <option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all">
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="connector" location="..\connector-safe.ecf" readonly="false"/>
<library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/> <library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/>
<library name="libfcgi" location="..\..\..\libfcgi\libfcgi-safe.ecf" /> <library name="libfcgi" location="..\..\..\libfcgi\libfcgi-safe.ecf" />
<library name="http" location="..\..\..\..\protocol\http\http-safe.ecf"/> <library name="http" location="..\..\..\..\protocol\http\http-safe.ecf"/>

View File

@@ -10,6 +10,7 @@
<option warning="true" full_class_checking="true"> <option warning="true" full_class_checking="true">
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="connector" location="..\connector.ecf" readonly="false"/>
<library name="ewsgi" location="..\..\ewsgi.ecf" readonly="false"/> <library name="ewsgi" location="..\..\ewsgi.ecf" readonly="false"/>
<library name="libfcgi" location="..\..\..\libfcgi\libfcgi.ecf" /> <library name="libfcgi" location="..\..\..\libfcgi\libfcgi.ecf" />
<library name="http" location="..\..\..\..\protocol\http\http.ecf"/> <library name="http" location="..\..\..\..\protocol\http\http.ecf"/>

View File

@@ -1,12 +1,12 @@
note note
description: "Summary description for {EWF_LIBFCGI_CONNECTOR}." description: "Summary description for {WGI_LIBFCGI_CONNECTOR}."
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."
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
class class
EWF_LIBFCGI_CONNECTOR WGI_LIBFCGI_CONNECTOR
inherit inherit
WGI_CONNECTOR WGI_CONNECTOR
@@ -22,8 +22,8 @@ feature {NONE} -- Initialization
initialize initialize
do do
create fcgi.make create fcgi.make
create {EWF_LIBFCGI_INPUT_STREAM} input.make (fcgi) create {WGI_LIBFCGI_INPUT_STREAM} input.make (fcgi)
create {EWF_LIBFCGI_OUTPUT_STREAM} output.make (fcgi) create {WGI_LIBFCGI_OUTPUT_STREAM} output.make (fcgi)
end end
feature -- Server feature -- Server
@@ -47,11 +47,28 @@ feature -- Execution
process_fcgi_request (vars: HASH_TABLE [STRING, STRING]; a_input: like input; a_output: like output) process_fcgi_request (vars: HASH_TABLE [STRING, STRING]; a_input: like input; a_output: like output)
local local
req: WGI_REQUEST_FROM_TABLE req: WGI_REQUEST_FROM_TABLE
res: WGI_RESPONSE_STREAM_BUFFER res: detachable WGI_RESPONSE_STREAM_BUFFER
rescued: BOOLEAN
do do
create req.make (vars, a_input) if not rescued then
create res.make (a_output) create req.make (vars, a_input)
application.process (req, res) create res.make (a_output)
application.execute (req, res)
else
if attached (create {EXCEPTION_MANAGER}).last_exception as e and then attached e.exception_trace as l_trace then
if res /= Void then
if not res.status_is_set then
res.write_header ({HTTP_STATUS_CODE}.internal_server_error, Void)
end
if res.message_writable then
res.write_string ("<pre>" + l_trace + "</pre>")
end
end
end
end
rescue
rescued := True
retry
end end
feature -- Input/Output feature -- Input/Output

View File

@@ -1,12 +1,12 @@
note note
description: "Summary description for EWF_LIBFCGI_INPUT_STREAM." description: "Summary description for WGI_LIBFCGI_INPUT_STREAM."
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."
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
class class
EWF_LIBFCGI_INPUT_STREAM WGI_LIBFCGI_INPUT_STREAM
inherit inherit
WGI_INPUT_STREAM WGI_INPUT_STREAM

View File

@@ -1,12 +1,12 @@
note note
description: "Summary description for {EWF_LIBFCGI_OUTPUT_STREAM}." description: "Summary description for {WGI_LIBFCGI_OUTPUT_STREAM}."
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."
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
class class
EWF_LIBFCGI_OUTPUT_STREAM WGI_LIBFCGI_OUTPUT_STREAM
inherit inherit
WGI_OUTPUT_STREAM WGI_OUTPUT_STREAM

View File

@@ -10,6 +10,7 @@
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all"> <option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all">
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="connector" location="..\connector-safe.ecf" readonly="false"/>
<library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/> <library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/>
<library name="http" location="..\..\..\..\protocol\http\http-safe.ecf"/> <library name="http" location="..\..\..\..\protocol\http\http-safe.ecf"/>
<library name="nino" location="..\..\..\..\..\ext\server\nino\nino-safe.ecf" readonly="false"> <library name="nino" location="..\..\..\..\..\ext\server\nino\nino-safe.ecf" readonly="false">

View File

@@ -10,6 +10,7 @@
<option warning="true" full_class_checking="true"> <option warning="true" full_class_checking="true">
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="connector" location="..\connector.ecf" readonly="false"/>
<library name="ewsgi" location="..\..\ewsgi.ecf" readonly="false"/> <library name="ewsgi" location="..\..\ewsgi.ecf" readonly="false"/>
<library name="http" location="..\..\..\..\protocol\http\http.ecf"/> <library name="http" location="..\..\..\..\protocol\http\http.ecf"/>
<library name="nino" location="..\..\..\..\..\ext\server\nino\nino.ecf" readonly="false"> <library name="nino" location="..\..\..\..\..\ext\server\nino\nino.ecf" readonly="false">

View File

@@ -29,7 +29,7 @@ feature {NONE} -- Implementation
create connector.make_with_base (app, a_base_url) create connector.make_with_base (app, a_base_url)
end end
connector: EWF_NINO_CONNECTOR connector: WGI_NINO_CONNECTOR
-- Web server connector -- Web server connector
feature -- Status settings feature -- Status settings

View File

@@ -1,11 +1,11 @@
note note
description: "Summary description for {EWF_NINO_CONNECTOR}." description: "Summary description for {WGI_NINO_CONNECTOR}."
author: "" author: ""
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
class class
EWF_NINO_CONNECTOR WGI_NINO_CONNECTOR
inherit inherit
WGI_CONNECTOR WGI_CONNECTOR
@@ -68,7 +68,7 @@ feature -- Server
local local
l_http_handler : HTTP_HANDLER l_http_handler : HTTP_HANDLER
do do
create {EWF_NINO_HANDLER} l_http_handler.make_with_callback (server, "NINO_HANDLER", Current) create {WGI_NINO_HANDLER} l_http_handler.make_with_callback (server, "NINO_HANDLER", Current)
debug ("nino") debug ("nino")
if attached base as l_base then if attached base as l_base then
print ("Base=" + l_base + "%N") print ("Base=" + l_base + "%N")
@@ -80,12 +80,29 @@ feature -- Server
process_request (env: HASH_TABLE [STRING, STRING]; a_headers_text: STRING; a_input: HTTP_INPUT_STREAM; a_output: HTTP_OUTPUT_STREAM) process_request (env: HASH_TABLE [STRING, STRING]; a_headers_text: STRING; a_input: HTTP_INPUT_STREAM; a_output: HTTP_OUTPUT_STREAM)
local local
req: WGI_REQUEST_FROM_TABLE req: WGI_REQUEST_FROM_TABLE
res: WGI_RESPONSE_STREAM_BUFFER res: detachable WGI_RESPONSE_STREAM_BUFFER
rescued: BOOLEAN
do do
create req.make (env, create {EWF_NINO_INPUT_STREAM}.make (a_input)) if not rescued then
create res.make (create {EWF_NINO_OUTPUT_STREAM}.make (a_output)) create req.make (env, create {WGI_NINO_INPUT_STREAM}.make (a_input))
req.set_meta_string_variable ("RAW_HEADER_DATA", a_headers_text) create res.make (create {WGI_NINO_OUTPUT_STREAM}.make (a_output))
application.execute (req, res) req.set_meta_string_variable ("RAW_HEADER_DATA", a_headers_text)
application.execute (req, res)
else
if attached (create {EXCEPTION_MANAGER}).last_exception as e and then attached e.exception_trace as l_trace then
if res /= Void then
if not res.status_is_set then
res.write_header ({HTTP_STATUS_CODE}.internal_server_error, Void)
end
if res.message_writable then
res.write_string ("<pre>" + l_trace + "</pre>")
end
end
end
end
rescue
rescued := True
retry
end end
note note

View File

@@ -5,7 +5,7 @@ note
revision : "$Revision$" revision : "$Revision$"
class class
EWF_NINO_HANDLER WGI_NINO_HANDLER
inherit inherit
HTTP_CONNECTION_HANDLER HTTP_CONNECTION_HANDLER
@@ -23,7 +23,7 @@ feature {NONE} -- Initialization
callback := a_callback callback := a_callback
end end
callback: EWF_NINO_CONNECTOR callback: WGI_NINO_CONNECTOR
feature -- Access feature -- Access

View File

@@ -1,12 +1,12 @@
note note
description: "Summary description for {EWF_NINO_INPUT_STREAM}." description: "Summary description for {WGI_NINO_INPUT_STREAM}."
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."
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
class class
EWF_NINO_INPUT_STREAM WGI_NINO_INPUT_STREAM
inherit inherit
WGI_INPUT_STREAM WGI_INPUT_STREAM
@@ -22,7 +22,7 @@ feature {NONE} -- Initialization
set_nino_input (a_nino_input) set_nino_input (a_nino_input)
end end
feature {EWF_NINO_CONNECTOR, WGI_APPLICATION} -- Nino feature {WGI_NINO_CONNECTOR, WGI_APPLICATION} -- Nino
set_nino_input (i: like nino_input) set_nino_input (i: like nino_input)
do do

View File

@@ -1,12 +1,12 @@
note note
description: "Summary description for {EWF_NINO_OUTPUT_STREAM}." description: "Summary description for {WGI_NINO_OUTPUT_STREAM}."
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."
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
class class
EWF_NINO_OUTPUT_STREAM WGI_NINO_OUTPUT_STREAM
inherit inherit
WGI_OUTPUT_STREAM WGI_OUTPUT_STREAM
@@ -26,7 +26,7 @@ feature {NONE} -- Initialization
set_nino_output (a_nino_output) set_nino_output (a_nino_output)
end end
feature {EWF_NINO_CONNECTOR, WGI_APPLICATION} -- Nino feature {WGI_NINO_CONNECTOR, WGI_APPLICATION} -- Nino
set_nino_output (o: like nino_output) set_nino_output (o: like nino_output)
do do

Binary file not shown.

View File

@@ -11,7 +11,6 @@
</option> </option>
<setting name="concurrency" value="thread"/> <setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="default_nino" location="..\..\default\ewsgi_nino-safe.ecf" readonly="false"/>
<library name="connector_nino" location="..\..\connectors\nino\nino-safe.ecf" readonly="false"/> <library name="connector_nino" location="..\..\connectors\nino\nino-safe.ecf" readonly="false"/>
<library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/> <library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/>
<cluster name="src" location="src\" recursive="true"/> <cluster name="src" location="src\" recursive="true"/>

View File

@@ -11,7 +11,6 @@
</option> </option>
<setting name="concurrency" value="thread"/> <setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="default_nino" location="..\..\default\ewsgi_nino.ecf" readonly="false"/>
<library name="connector_nino" location="..\..\connectors\nino\nino.ecf" readonly="false"/> <library name="connector_nino" location="..\..\connectors\nino\nino.ecf" readonly="false"/>
<library name="ewsgi" location="..\..\ewsgi.ecf" readonly="false"/> <library name="ewsgi" location="..\..\ewsgi.ecf" readonly="false"/>
<cluster name="src" location="src\" recursive="true"/> <cluster name="src" location="src\" recursive="true"/>

View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="hello_world" uuid="09AE4913-629B-4D3C-B15D-BB615D9A7B7F">
<target name="hello_world">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/\.git$</exclude>
<exclude>/\.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
<assertions precondition="true" postcondition="true" invariant="true" supplier_precondition="true"/>
</option>
<setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/>
</target>
<target name="hello_nino_world" extends="hello_world">
<root class="HELLO_WORLD" feature="make_and_launch"/>
<library name="connector_nino" location="..\..\connectors\nino\nino-safe.ecf" readonly="false"/>
<library name="default_nino" location="..\..\default\ewsgi_nino-safe.ecf" readonly="false"/>
<cluster name="src" location="src\" recursive="true"/>
</target>
<target name="hello_cgi_world" extends="hello_world">
<root class="HELLO_WORLD" feature="make_and_launch"/>
<library name="connector_cgi" location="..\..\connectors\cgi\cgi-safe.ecf" readonly="false"/>
<library name="default_cgi" location="..\..\default\ewsgi_cgi-safe.ecf" readonly="false"/>
<cluster name="src" location="src\" recursive="true"/>
</target>
</system>

View File

@@ -1,10 +0,0 @@
${NOTE_KEYWORD}
copyright: "2011-${YEAR}, 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
]"

View File

@@ -1,48 +0,0 @@
note
description : "Objects that ..."
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
class
HELLO_WORLD
inherit
WGI_RESPONSE_APPLICATION
DEFAULT_WGI_APPLICATION
create
make_and_launch
feature -- Response
response (request: WGI_REQUEST): WGI_RESPONSE
do
if request.path_info.starts_with ("/streaming/") then
Result := streaming_response (request)
else
create Result.make
Result.set_status (200)
Result.set_header ("Content-Type", "text/html; charset=utf-8")
Result.set_message_body ("<html><body>Hello World</body></html>")
end
end
streaming_response (request: WGI_REQUEST): WGI_RESPONSE
do
create {HELLO_WORLD_RESPONSE} Result.make
Result.set_status (200)
Result.set_header ("Content-Type", "text/html; charset=utf-8")
end
note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,70 +0,0 @@
note
description: "A streaming (non-buffered) Hello World example."
author: "Paul Cohen <paul.cohen@seibostudio.se>"
status: "Draft"
class HELLO_WORLD_RESPONSE
inherit
WGI_RESPONSE
redefine
make,
read_block
end
create
make
feature {NONE} -- Initialization
make
do
precursor
set_ready_to_transmit
current_hello := 0
end
feature {NONE} -- Entity body
read_block
-- Reads a block of 100000 lines of "Hello World".
local
i: INTEGER
do
if current_hello >= 10000 then
end_of_blocks := True
else
if current_hello = 0 then
current_block := "<html><style>div#status {position: absolute; top: 30%%; left: 40%%; border: red solid 1px; padding: 10px; background-color: #ffcccc;}</style><body>%N"
current_block.append ("<a name=%"top%">Welcome</a><br/><div id=%"status%">In progress</div>")
end
from
i := 0
until
i = 1000
loop
current_block.append ("Hello World ("+ current_hello.out +","+ i.out +")<br/>%N")
i := i + 1
end
current_hello := current_hello + i
current_block.append ("<div id=%"status%">In progress - "+ (100 * current_hello // 10000).out +"%%</div>")
if current_hello = 10000 then
current_block.append ("<a name=%"bottom%">Bye bye..</a><br/><div id=%"status%">Completed - GO TO <a href=%"#bottom%">BOTTOM</a></div></body></html>")
end_of_blocks := True
end
end
end
current_hello: INTEGER
;note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,76 +0,0 @@
note
description: "[
Contains all information of a rfc2109 cookie that was read from the request header
]"
legal: "See notice at end of class."
status: "See notice at end of class."
date: "$Date$"
revision: "$Revision$"
class
WGI_COOKIE
create
make
convert
value: {READABLE_STRING_8, STRING_8, READABLE_STRING_GENERAL, STRING_GENERAL}
feature {NONE} -- Initialization
make (a_name: STRING; a_value: STRING)
-- Creates current.
require
a_name_not_empty: a_name /= Void and then not a_name.is_empty
a_value_not_empty: a_value /= Void and then not a_value.is_empty
do
name := a_name
value := a_value
ensure
a_name_set: name = a_name
a_value_set: value = a_value
end
feature -- Access
name: STRING
-- Required. The name of the state information ("cookie") is NAME,
-- and its value is VALUE. NAMEs that begin with $ are reserved for
-- other uses and must not be used by applications.
value: STRING
-- The VALUE is opaque to the user agent and may be anything the
-- origin server chooses to send, possibly in a server-selected
-- printable ASCII encoding. "Opaque" implies that the content is of
-- interest and relevance only to the origin server. The content
-- may, in fact, be readable by anyone that examines the Set-Cookie
-- header.
feature -- Query
variables: detachable HASH_TABLE [STRING, STRING]
-- Potential variable contained in the encoded cookie's value.
feature -- Status report
value_is_string (s: READABLE_STRING_GENERAL): BOOLEAN
-- Is `value' same string as `s'
do
Result := s.same_string (value)
end
invariant
name_attached: name /= Void
value_attached: value /= Void
note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,80 +0,0 @@
note
description : "[
Interface to access the variable stored in a container
]"
legal: "See notice at end of class."
status: "See notice at end of class."
date: "$Date$"
revision: "$Revision$"
deferred class
WGI_VARIABLES [G -> STRING_GENERAL]
inherit
ITERABLE [G]
feature -- Status report
has_variable (a_name: STRING): BOOLEAN
-- Has variable associated with `a_name'
require
a_name_not_empty: a_name /= Void and then not a_name.is_empty
deferred
end
feature -- Access
variable (a_name: STRING): detachable G
-- Value for variable associated with `a_name'
-- If not found, return Void
require
a_name_not_empty: a_name /= Void and then not a_name.is_empty
deferred
end
variable_or_default (a_name: STRING; a_default: G; use_default_when_empty: BOOLEAN): G
-- Value for variable `a_name'
-- If not found, return `a_default'
require
a_name_not_empty: a_name /= Void and then not a_name.is_empty
do
if attached variable (a_name) as s then
if use_default_when_empty and then s.is_empty then
Result := a_default
else
Result := s
end
else
Result := a_default
end
end
feature {WGI_REQUEST, WGI_APPLICATION, WGI_CONNECTOR} -- Element change
set_variable (a_name: STRING; a_value: G)
require
a_name_not_empty: a_name /= Void and then not a_name.is_empty
deferred
ensure
variable_set: has_variable (a_name) and then variable (a_name) ~ a_value
end
unset_variable (a_name: STRING)
require
a_name_not_empty: a_name /= Void and then not a_name.is_empty
deferred
ensure
variable_unset: not has_variable (a_name)
end
note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -80,23 +80,16 @@ feature -- Access: Input
deferred deferred
end end
feature -- Access: extra values
request_time: detachable DATE_TIME
-- Request time (UTC)
deferred
end
feature -- Access: CGI meta variables feature -- Access: CGI meta variables
meta_variable (a_name: READABLE_STRING_GENERAL): detachable WGI_STRING_VALUE meta_variable (a_name: READABLE_STRING_8): detachable READABLE_STRING_8
-- Environment variable related to `a_name' -- Environment variable related to `a_name'
require require
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
deferred deferred
end end
meta_string_variable (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 meta_string_variable (a_name: READABLE_STRING_8): detachable READABLE_STRING_8
-- Environment variable related to `a_name' -- Environment variable related to `a_name'
require require
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
@@ -106,7 +99,7 @@ feature -- Access: CGI meta variables
end end
end end
meta_variables: ITERABLE [WGI_STRING_VALUE] meta_variables: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
-- These variables are specific to requests made with HTTP. -- These variables are specific to requests made with HTTP.
-- Interpretation of these variables may depend on the value of -- Interpretation of these variables may depend on the value of
-- SERVER_PROTOCOL. -- SERVER_PROTOCOL.
@@ -138,7 +131,7 @@ feature -- Access: CGI meta variables
feature -- Common Gateway Interface - 1.1 8 January 1996 feature -- Common Gateway Interface - 1.1 8 January 1996
auth_type: detachable READABLE_STRING_32 auth_type: detachable READABLE_STRING_8
-- This variable is specific to requests made via the "http" -- This variable is specific to requests made via the "http"
-- scheme. -- scheme.
-- --
@@ -160,7 +153,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
deferred deferred
end end
content_length: detachable READABLE_STRING_32 content_length: detachable READABLE_STRING_8
-- This metavariable is set to the size of the message-body -- This metavariable is set to the size of the message-body
-- entity attached to the request, if any, in decimal number of -- entity attached to the request, if any, in decimal number of
-- octets. If no data are attached, then this metavariable is -- octets. If no data are attached, then this metavariable is
@@ -175,12 +168,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
deferred deferred
end end
content_length_value: NATURAL_64 content_type: detachable READABLE_STRING_8
-- Integer value related to `content_length"
deferred
end
content_type: detachable READABLE_STRING_32
-- If the request includes a message-body, CONTENT_TYPE is set to -- If the request includes a message-body, CONTENT_TYPE is set to
-- the Internet Media Type [9] of the attached entity if the type -- the Internet Media Type [9] of the attached entity if the type
-- was provided via a "Content-type" field in the request header, -- was provided via a "Content-type" field in the request header,
@@ -223,7 +211,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
deferred deferred
end end
gateway_interface: READABLE_STRING_32 gateway_interface: READABLE_STRING_8
-- This metavariable is set to the dialect of CGI being used by -- This metavariable is set to the dialect of CGI being used by
-- the server to communicate with the script. Syntax: -- the server to communicate with the script. Syntax:
-- --
@@ -256,7 +244,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
deferred deferred
end end
path_info: READABLE_STRING_32 path_info: READABLE_STRING_8
-- The PATH_INFO metavariable specifies a path to be interpreted -- The PATH_INFO metavariable specifies a path to be interpreted
-- by the CGI script. It identifies the resource or sub-resource -- by the CGI script. It identifies the resource or sub-resource
-- to be returned by the CGI script, and it is derived from the -- to be returned by the CGI script, and it is derived from the
@@ -287,7 +275,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
deferred deferred
end end
path_translated: detachable READABLE_STRING_32 path_translated: detachable READABLE_STRING_8
-- PATH_TRANSLATED is derived by taking any path-info component -- PATH_TRANSLATED is derived by taking any path-info component
-- of the request URI (see section 6.1.6), decoding it (see -- of the request URI (see section 6.1.6), decoding it (see
-- section 3.1), parsing it as a URI in its own right, and -- section 3.1), parsing it as a URI in its own right, and
@@ -333,7 +321,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
deferred deferred
end end
query_string: READABLE_STRING_32 query_string: READABLE_STRING_8
-- A URL-encoded string; the <query> part of the Script-URI. (See -- A URL-encoded string; the <query> part of the Script-URI. (See
-- section 3.2.) -- section 3.2.)
-- --
@@ -350,7 +338,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
deferred deferred
end end
remote_addr: READABLE_STRING_32 remote_addr: READABLE_STRING_8
-- The IP address of the client sending the request to the -- The IP address of the client sending the request to the
-- server. This is not necessarily that of the user agent (such -- server. This is not necessarily that of the user agent (such
-- as if the request came through a proxy). -- as if the request came through a proxy).
@@ -365,7 +353,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
deferred deferred
end end
remote_host: detachable READABLE_STRING_32 remote_host: detachable READABLE_STRING_8
-- The fully qualified domain name of the client sending the -- The fully qualified domain name of the client sending the
-- request to the server, if available, otherwise NULL. (See -- request to the server, if available, otherwise NULL. (See
-- section 6.1.9.) Fully qualified domain names take the form as -- section 6.1.9.) Fully qualified domain names take the form as
@@ -376,7 +364,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
deferred deferred
end end
remote_ident: detachable READABLE_STRING_32 remote_ident: detachable READABLE_STRING_8
-- The identity information reported about the connection by a -- The identity information reported about the connection by a
-- RFC 1413 [11] request to the remote agent, if available. -- RFC 1413 [11] request to the remote agent, if available.
-- Servers MAY choose not to support this feature, or not to -- Servers MAY choose not to support this feature, or not to
@@ -392,7 +380,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
deferred deferred
end end
remote_user: detachable READABLE_STRING_32 remote_user: detachable READABLE_STRING_8
-- If the request required authentication using the "Basic" -- If the request required authentication using the "Basic"
-- mechanism (i.e., the AUTH_TYPE metavariable is set to -- mechanism (i.e., the AUTH_TYPE metavariable is set to
-- "Basic"), then the value of the REMOTE_USER metavariable is -- "Basic"), then the value of the REMOTE_USER metavariable is
@@ -408,7 +396,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
deferred deferred
end end
request_method: READABLE_STRING_32 request_method: READABLE_STRING_8
-- The REQUEST_METHOD metavariable is set to the method with -- The REQUEST_METHOD metavariable is set to the method with
-- which the request was made, as described in section 5.1.1 of -- which the request was made, as described in section 5.1.1 of
-- the HTTP/1.0 specification [3] and section 5.1.1 of the -- the HTTP/1.0 specification [3] and section 5.1.1 of the
@@ -429,7 +417,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
deferred deferred
end end
script_name: READABLE_STRING_32 script_name: READABLE_STRING_8
-- The SCRIPT_NAME metavariable is set to a URL path that could -- The SCRIPT_NAME metavariable is set to a URL path that could
-- identify the CGI script (rather than the script's output). The -- identify the CGI script (rather than the script's output). The
-- syntax and semantics are identical to a decoded HTTP URL -- syntax and semantics are identical to a decoded HTTP URL
@@ -447,7 +435,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
deferred deferred
end end
server_name: READABLE_STRING_32 server_name: READABLE_STRING_8
-- The SERVER_NAME metavariable is set to the name of the server, -- The SERVER_NAME metavariable is set to the name of the server,
-- as derived from the <host> part of the Script-URI (see section -- as derived from the <host> part of the Script-URI (see section
-- 3.2). -- 3.2).
@@ -473,7 +461,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
deferred deferred
end end
server_protocol: READABLE_STRING_32 server_protocol: READABLE_STRING_8
-- The SERVER_PROTOCOL metavariable is set to the name and -- The SERVER_PROTOCOL metavariable is set to the name and
-- revision of the information protocol with which the request -- revision of the information protocol with which the request
-- arrived. This is not necessarily the same as the protocol -- arrived. This is not necessarily the same as the protocol
@@ -501,7 +489,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
deferred deferred
end end
server_software: READABLE_STRING_32 server_software: READABLE_STRING_8
-- The SERVER_SOFTWARE metavariable is set to the name and -- The SERVER_SOFTWARE metavariable is set to the name and
-- version of the information server software answering the -- version of the information server software answering the
-- request (and running the gateway). -- request (and running the gateway).
@@ -516,42 +504,42 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
feature -- HTTP_* feature -- HTTP_*
http_accept: detachable READABLE_STRING_32 http_accept: detachable READABLE_STRING_8
-- Contents of the Accept: header from the current request, if there is one. -- Contents of the Accept: header from the current request, if there is one.
-- Example: 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -- Example: 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
deferred deferred
end end
http_accept_charset: detachable READABLE_STRING_32 http_accept_charset: detachable READABLE_STRING_8
-- Contents of the Accept-Charset: header from the current request, if there is one. -- Contents of the Accept-Charset: header from the current request, if there is one.
-- Example: 'iso-8859-1,*,utf-8'. -- Example: 'iso-8859-1,*,utf-8'.
deferred deferred
end end
http_accept_encoding: detachable READABLE_STRING_32 http_accept_encoding: detachable READABLE_STRING_8
-- Contents of the Accept-Encoding: header from the current request, if there is one. -- Contents of the Accept-Encoding: header from the current request, if there is one.
-- Example: 'gzip'. -- Example: 'gzip'.
deferred deferred
end end
http_accept_language: detachable READABLE_STRING_32 http_accept_language: detachable READABLE_STRING_8
-- Contents of the Accept-Language: header from the current request, if there is one. -- Contents of the Accept-Language: header from the current request, if there is one.
-- Example: 'en'. -- Example: 'en'.
deferred deferred
end end
http_connection: detachable READABLE_STRING_32 http_connection: detachable READABLE_STRING_8
-- Contents of the Connection: header from the current request, if there is one. -- Contents of the Connection: header from the current request, if there is one.
-- Example: 'Keep-Alive'. -- Example: 'Keep-Alive'.
deferred deferred
end end
http_host: detachable READABLE_STRING_32 http_host: detachable READABLE_STRING_8
-- Contents of the Host: header from the current request, if there is one. -- Contents of the Host: header from the current request, if there is one.
deferred deferred
end end
http_referer: detachable READABLE_STRING_32 http_referer: detachable READABLE_STRING_8
-- The address of the page (if any) which referred the user agent to the current page. -- The address of the page (if any) which referred the user agent to the current page.
-- This is set by the user agent. -- This is set by the user agent.
-- Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. -- Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature.
@@ -559,7 +547,7 @@ feature -- HTTP_*
deferred deferred
end end
http_user_agent: detachable READABLE_STRING_32 http_user_agent: detachable READABLE_STRING_8
-- Contents of the User-Agent: header from the current request, if there is one. -- Contents of the User-Agent: header from the current request, if there is one.
-- This is a string denoting the user agent being which is accessing the page. -- This is a string denoting the user agent being which is accessing the page.
-- A typical example is: Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586). -- A typical example is: Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586).
@@ -568,127 +556,23 @@ feature -- HTTP_*
deferred deferred
end end
http_authorization: detachable READABLE_STRING_32 http_authorization: detachable READABLE_STRING_8
-- Contents of the Authorization: header from the current request, if there is one. -- Contents of the Authorization: header from the current request, if there is one.
deferred deferred
end end
feature -- Extra CGI environment variables feature -- Extra CGI environment variables
request_uri: READABLE_STRING_32 request_uri: READABLE_STRING_8
-- The URI which was given in order to access this page; for instance, '/index.html'. -- The URI which was given in order to access this page; for instance, '/index.html'.
deferred deferred
end end
orig_path_info: detachable READABLE_STRING_32 orig_path_info: detachable READABLE_STRING_8
-- Original version of `path_info' before processed by Current environment -- Original version of `path_info' before processed by Current environment
deferred deferred
end end
feature -- Query string Parameters
query_parameters: ITERABLE [WGI_VALUE]
-- Variables extracted from QUERY_STRING
deferred
end
query_parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE
-- Parameter for name `n'.
require
a_name_valid: a_name /= Void and then not a_name.is_empty
deferred
end
feature -- Form fields and related
form_data_parameters: ITERABLE [WGI_VALUE]
-- Variables sent by POST request
deferred
end
form_data_parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE
-- Field for name `a_name'.
require
a_name_valid: a_name /= Void and then not a_name.is_empty
deferred
end
uploaded_files: HASH_TABLE [WGI_UPLOADED_FILE_DATA, READABLE_STRING_GENERAL]
-- Table of uploaded files information
--| name: original path from the user
--| type: content type
--| tmp_name: path to temp file that resides on server
--| tmp_base_name: basename of `tmp_name'
--| error: if /= 0 , there was an error : TODO ...
--| size: size of the file given by the http request
deferred
end
feature -- Cookies
cookies: ITERABLE [WGI_VALUE]
-- Expanded cookies variable
deferred
end
cookie (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE
-- Field for name `a_name'.
require
a_name_valid: a_name /= Void and then not a_name.is_empty
deferred
end
feature -- Access: all variables
parameters: like items
obsolete "use items"
do
Result := items
end
parameter (a_name: READABLE_STRING_GENERAL): like item
obsolete "use item"
do
Result := item (a_name)
end
items: ITERABLE [WGI_VALUE]
-- Table containing all the various variables
-- Warning: this is computed each time, if you change the content of other containers
-- this won't update this Result's content, unless you query it again
deferred
end
item (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE
-- Variable named `a_name' from any of the variables container
-- and following a specific order
-- execution, environment, get, post, cookies
require
a_name_valid: a_name /= Void and then not a_name.is_empty
deferred
end
feature -- Uploaded File Handling
is_uploaded_file (a_filename: READABLE_STRING_GENERAL): BOOLEAN
-- Is `a_filename' a file uploaded via HTTP POST
deferred
end
feature -- URL Utility
absolute_script_url (a_path: STRING): STRING
-- Absolute Url for the script if any, extended by `a_path'
deferred
end
script_url (a_path: STRING): STRING
-- Url relative to script name if any, extended by `a_path'
require
a_path_attached: a_path /= Void
deferred
end
invariant invariant
server_name_not_empty: not server_name.is_empty server_name_not_empty: not server_name.is_empty
server_port_set: server_port /= 0 server_port_set: server_port /= 0

View File

@@ -1,186 +0,0 @@
note
description: "Summary description for {EWF_BUFFERED_RESPONSE}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
EWF_BUFFERED_RESPONSE
inherit
WGI_RESPONSE_BUFFER
create {WGI_APPLICATION}
make
feature {NONE} -- Initialization
make (a_res: like response_buffer; a_buffer_size: INTEGER)
do
response_buffer := a_res
buffer_capacity := a_buffer_size
create buffer.make (a_buffer_size)
end
response_buffer: WGI_RESPONSE_BUFFER
buffer: STRING_8
buffer_capacity: INTEGER
buffer_count: INTEGER
feature {NONE} -- Core output operation
write (s: STRING)
-- Send the content of `s'
local
buf: like buffer
len_b, len_s: INTEGER
do
buf := buffer
len_s := s.count
len_b := buffer_count
if len_b + len_s >= buffer_capacity then
flush_buffer
if len_s >= buffer_capacity then
-- replace buffer by `s'
buffer := s
buffer_count := len_s
flush_buffer
-- restore buffer with `buf'
buffer := buf
else
buf.append (s)
buffer_count := len_s
end
else
buf.append (s)
buffer_count := len_b + len_s
end
end
feature -- Output operation
flush
do
flush_buffer
end
feature {NONE} -- Implementation
flush_buffer
require
buffer_count_match_buffer: buffer_count = buffer.count
do
response_buffer.write (buffer)
buffer_count := 0
ensure
buffer_flushed: buffer_count = 0 and buffer.count = 0
end
feature {WGI_APPLICATION} -- Commit
commit
do
flush_buffer
end
feature -- Status report
header_committed: BOOLEAN
-- Header committed?
message_committed: BOOLEAN
-- Message committed?
message_writable: BOOLEAN
-- Can message be written?
do
Result := status_is_set and header_committed
end
feature -- Status setting
status_is_set: BOOLEAN
-- Is status set?
do
Result := status_code /= 0
end
set_status_code (a_code: INTEGER)
-- Set response status code
-- Should be done before sending any data back to the client
do
status_code := a_code
response_buffer.set_status_code (a_code)
end
status_code: INTEGER
-- Response status
feature -- Header output operation
write_headers_string (a_headers: STRING)
do
write (a_headers)
header_committed := True
end
write_header (a_status_code: INTEGER; a_headers: detachable ARRAY [TUPLE [key: STRING; value: STRING]])
-- Send headers with status `a_status', and headers from `a_headers'
local
h: EWF_HEADER
i,n: INTEGER
do
set_status_code (a_status_code)
create h.make
h.put_status (a_status_code)
if a_headers /= Void then
from
i := a_headers.lower
n := a_headers.upper
until
i > n
loop
h.put_header_key_value (a_headers[i].key, a_headers[i].value)
i := i + 1
end
end
write_headers_string (h.string)
end
feature -- Output operation
write_string (s: STRING)
-- Send the string `s'
do
write (s)
end
write_substring (s: STRING; start_index, end_index: INTEGER)
-- Send the substring `start_index:end_index]'
--| Could be optimized according to the target output
do
flush_buffer
response_buffer.write_substring (s, start_index, end_index)
end
write_file_content (fn: STRING)
-- Send the content of file `fn'
do
flush_buffer
response_buffer.write_file_content (fn)
end
;note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,151 +0,0 @@
note
description: "Summary description for {EWF_IN_MEMORY_RESPONSE}."
date: "$Date$"
revision: "$Revision$"
class
EWF_IN_MEMORY_RESPONSE
inherit
WGI_RESPONSE_BUFFER
create {WGI_APPLICATION}
make
feature {NONE} -- Initialization
make (res: WGI_RESPONSE_BUFFER)
do
response_buffer := res
create header.make
create body.make (100)
end
response_buffer: WGI_RESPONSE_BUFFER
header: EWF_HEADER
body: STRING_8
feature {WGI_APPLICATION} -- Commit
commit
local
r: like response_buffer
do
r := response_buffer
r.set_status_code (status_code)
r.write_headers_string (header.string)
header_committed := True
r.write_string (body)
r.flush
end
feature -- Status report
header_committed: BOOLEAN
-- Header committed?
message_committed: BOOLEAN
-- Message committed?
message_writable: BOOLEAN
-- Can message be written?
do
Result := status_is_set and header_committed
end
feature -- Status setting
status_is_set: BOOLEAN
-- Is status set?
do
Result := status_code /= 0
end
set_status_code (a_code: INTEGER)
-- Set response status code
-- Should be done before sending any data back to the client
do
status_code := a_code
end
status_code: INTEGER
-- Response status
feature {NONE} -- Status output
write (s: STRING)
-- Send the content of `s'
do
body.append (s)
end
feature -- Header output operation
write_headers_string (a_headers: STRING)
do
write (a_headers)
header_committed := True
end
write_header (a_status_code: INTEGER; a_headers: detachable ARRAY [TUPLE [key: STRING; value: STRING]])
-- Send headers with status `a_status', and headers from `a_headers'
local
h: EWF_HEADER
i,n: INTEGER
do
set_status_code (a_status_code)
create h.make
if a_headers /= Void then
from
i := a_headers.lower
n := a_headers.upper
until
i > n
loop
h.put_header_key_value (a_headers[i].key, a_headers[i].value)
i := i + 1
end
end
header := h
end
feature -- Output operation
write_string (s: STRING)
-- Send the string `s'
do
write (s)
end
write_substring (s: STRING; start_index, end_index: INTEGER)
-- Send the substring `start_index:end_index]'
--| Could be optimized according to the target output
do
write_string (s.substring (start_index, end_index))
end
write_file_content (fn: STRING)
-- Send the content of file `fn'
do
response_buffer.write_file_content (fn)
end
flush
do
--| Do nothing ... this is in_memory response
end
;note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,59 +0,0 @@
note
description: "Summary description for {EWF_IN_MEMORY_RESPONSE_APPLICATION}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
EWF_IN_MEMORY_RESPONSE_APPLICATION
inherit
WGI_APPLICATION
rename
execute as app_execute
end
feature -- Execution
app_execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
-- Execute the request
-- See `req.input' for input stream
-- `req.environment' for the Gateway environment
-- and `res' for output buffer
do
execute (req, new_response (req, res))
end
feature -- Execute
execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
-- Execute the request
-- See `req.input' for input stream
-- `req.environment' for the Gateway environment
-- and `res' for output buffer
require
res_status_unset: not res.status_is_set
deferred
ensure
res_status_set: res.status_is_set
end
feature {NONE} -- Implementation
new_response (req: WGI_REQUEST; a_res: WGI_RESPONSE_BUFFER): EWF_IN_MEMORY_RESPONSE
do
create {EWF_IN_MEMORY_RESPONSE} Result.make (a_res)
end
note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,226 +0,0 @@
note
description: "[
An EWSGI response. This may be used as is or specialized (subclassed)
if a developer wishes to reimplement their own version of the feature
'read_message_body_block' for supporting a block-based message body
response.
]"
author: "Paul Cohen <paul.cohen@seibostudio.se>"
status: "Draft"
class WGI_RESPONSE
create
make
feature {NONE} -- Initialization
make
-- Create new response object
do
is_buffered := False
ready_to_transmit := False
end_of_blocks := False
max_block_size := default_max_block_size
current_block := ""
create headers_table.make (10)
end
feature {WGI_RESPONSE_APPLICATION} -- Response status
transmit_to (res: WGI_RESPONSE_BUFFER)
do
res.set_status_code (status)
res.write_headers_string (headers)
from
read_block
res.write_string (last_block)
-- res.flush
until
end_of_blocks
loop
read_block
res.write_string (last_block)
-- res.flush
end
end
ready_to_transmit: BOOLEAN
-- Is this response ready to be transmitted?
set_ready_to_transmit
-- Set response to ready to transmit.
do
if is_buffered then
set_header ("Content-Length", current_block.count.out)
-- elseif tmp_file /= Void then
-- if tmp_file.is_open_write then
-- tmp_file.close
-- set_header ("Content-Length", tmp_file.count.out)
-- end
end
ready_to_transmit := True
ensure
ready_to_transmit
end
feature {WGI_RESPONSE_APPLICATION} -- Message start line and status
status: INTEGER
-- HTTP status code
set_status (s: INTEGER)
-- Set 'status_code'.
do
status := s
set_header ("Status", s.out)
ensure
status = s
end
start_line: STRING
-- HTTP message start-line
do
if attached status as st then
Result := "HTTP/1.1 " + st.out + " " + status_text (st) + crlf
else
Result := "HTTP/1.1 200 " + status_text (200) + crlf
end
end
feature {WGI_RESPONSE_APPLICATION} -- Message headers
headers: STRING
-- HTTP message headers including trailing empty line.
local
t: HASH_TABLE [STRING, STRING]
do
Result := ""
t := headers_table
from
t.start
until
t.after
loop
Result.append (t.key_for_iteration + ": " + t.item_for_iteration + crlf)
t.forth
end
Result.append (crlf)
end
headers_table: HASH_TABLE [STRING, STRING]
-- Hash table of HTTP headers
set_header (key, value: STRING)
-- Set the HTTP header with the given 'key' to the given 'value'.
do
headers_table.put (value, key)
ensure
headers_table.has (key) and headers_table @ key = value
end
feature {WGI_RESPONSE_APPLICATION} -- Message body
read_block
-- Read a message body block.
do
if is_buffered then
end_of_blocks := True
-- else
-- -- File based block-based output
-- -- TBD!
end
ensure
--Commented, since it is far from obvious to ensure that:
-- not is_buffered implies last_block.count <= max_block_size
end
last_block: STRING
-- Last message body block that has been read.
do
Result := current_block
end
is_buffered: BOOLEAN
-- Is the entire entity body buffered in memory (STRING)?
end_of_blocks: BOOLEAN
-- Has the last of the entity body blocks been read?
set_message_body (s: STRING)
-- Set the message body to 's'. Use this for when you want a memory
-- buffered response.
do
current_block := s
is_buffered := True
set_ready_to_transmit
ensure
is_buffered
ready_to_transmit
last_block.is_equal (s)
end
max_block_size: INTEGER
-- Maximum block size returned by message body if not buffered
set_max_block_size (block_size: INTEGER)
-- Set 'max_block_size'.
do
max_block_size := block_size
ensure
max_block_size = block_size
end
-- write_message_block (s: STRING)
-- -- Write message body block 's' to a temporary file. Us this when
-- -- you want a non-buffered response.
-- require
-- not is_buffered
-- do
-- -- TBD!
-- ensure
-- not is_buffered
-- not ready_to_transmit
-- end
feature {NONE} -- Implementation
-- tmp_file_name: STRING
-- tmp_file: detachable FILE
-- -- Created with mktmp
-- position: INTEGER
-- -- Current read position in tmp_file
current_block: STRING
-- Current message body block
default_max_block_size: INTEGER = 65536
-- Default value of 'max_block_size'
crlf: STRING = "%/13/%/10/"
status_text (code: INTEGER): STRING
do
inspect code
when 500 then
Result := "Internal Server Error"
when 200 then
Result := "OK"
else
Result := "Code " + code.out
end
end
note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -1,56 +0,0 @@
note
description: "Summary description for {WGI_RESPONSE_APPLICATION} "
legal: "See notice at end of class."
status: "See notice at end of class."
date: "$Date$"
revision: "$Revision$"
deferred class
WGI_RESPONSE_APPLICATION
feature -- Execution
execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
-- Execute the request
-- See `req.input' for input stream
-- `req.environment' for the Gateway environment
-- and `res.output' for output stream
local
rs: WGI_RESPONSE
do
rs := response (req)
if rs.ready_to_transmit then
rs.transmit_to (res)
else
-- Report internal server error.
-- Response not ready to transmit!
-- Implementor of WGI_APPLICATION has not done his job!
create rs.make
rs.set_status (500)
rs.set_header ("Content-Type", "text/plain")
rs.set_message_body ("Incomplete server implementation: Response not ready to transmit.%NTell the programmer to finish his/her job!")
rs.transmit_to (res)
end
end
feature -- Response
response (request: WGI_REQUEST): WGI_RESPONSE
-- HTTP response for given 'request'.
deferred
ensure
ready_to_transmit: Result.ready_to_transmit
end
;note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -0,0 +1,412 @@
note
description: "[
Request instanciated from a hash_table of meta variables
]"
specification: "EWSGI specification https://github.com/Eiffel-World/Eiffel-Web-Framework/wiki/EWSGI-specification"
legal: "See notice at end of class."
status: "See notice at end of class."
date: "$Date$"
revision: "$Revision$"
class
WGI_REQUEST_FROM_TABLE
inherit
WGI_REQUEST
create
make
feature {NONE} -- Initialization
make (a_vars: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]; a_input: like input)
require
vars_attached: a_vars /= Void
do
input := a_input
set_meta_variables (a_vars)
update_path_info
end
feature -- Access: Input
input: WGI_INPUT_STREAM
-- Server input channel
feature -- Access: CGI meta parameters
meta_variables: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
-- CGI Environment parameters
meta_variable (a_name: READABLE_STRING_8): detachable READABLE_STRING_8
-- CGI meta variable related to `a_name'
do
Result := meta_variables.item (a_name)
end
meta_string_variable_or_default (a_name: READABLE_STRING_8; a_default: READABLE_STRING_8; use_default_when_empty: BOOLEAN): READABLE_STRING_8
-- Value for meta parameter `a_name'
-- If not found, return `a_default'
require
a_name_not_empty: a_name /= Void and then not a_name.is_empty
do
if attached meta_variable (a_name) as val then
Result := val.string
if use_default_when_empty and then Result.is_empty then
Result := a_default
end
else
Result := a_default
end
end
set_meta_string_variable (a_name: READABLE_STRING_8; a_value: READABLE_STRING_8)
do
meta_variables.force (a_value, a_name)
ensure
param_set: attached meta_variable (a_name) as val and then val ~ a_value
end
unset_meta_variable (a_name: READABLE_STRING_8)
do
meta_variables.remove (a_name)
ensure
param_unset: meta_variable (a_name) = Void
end
feature -- Access: CGI meta parameters - 1.1
auth_type: detachable READABLE_STRING_8
content_length: detachable READABLE_STRING_8
content_type: detachable READABLE_STRING_8
gateway_interface: READABLE_STRING_8
do
Result := meta_string_variable_or_default ({WGI_META_NAMES}.gateway_interface, "", False)
end
path_info: READABLE_STRING_8
-- <Precursor/>
--
--| For instance, if the current script was accessed via the URL
--| http://www.example.com/eiffel/path_info.exe/some/stuff?foo=bar, then $_SERVER['PATH_INFO'] would contain /some/stuff.
--|
--| Note that is the PATH_INFO variable does not exists, the `path_info' value will be empty
path_translated: detachable READABLE_STRING_8
do
Result := meta_string_variable ({WGI_META_NAMES}.path_translated)
end
query_string: READABLE_STRING_8
remote_addr: READABLE_STRING_8
remote_host: READABLE_STRING_8
remote_ident: detachable READABLE_STRING_8
do
Result := meta_string_variable ({WGI_META_NAMES}.remote_ident)
end
remote_user: detachable READABLE_STRING_8
do
Result := meta_string_variable ({WGI_META_NAMES}.remote_user)
end
request_method: READABLE_STRING_8
script_name: READABLE_STRING_8
server_name: READABLE_STRING_8
server_port: INTEGER
server_protocol: READABLE_STRING_8
do
Result := meta_string_variable_or_default ({WGI_META_NAMES}.server_protocol, "HTTP/1.0", True)
end
server_software: READABLE_STRING_8
do
Result := meta_string_variable_or_default ({WGI_META_NAMES}.server_software, "Unknown Server", True)
end
feature -- Access: HTTP_* CGI meta parameters - 1.1
http_accept: detachable READABLE_STRING_8
-- Contents of the Accept: header from the current request, if there is one.
do
Result := meta_string_variable ({WGI_META_NAMES}.http_accept)
end
http_accept_charset: detachable READABLE_STRING_8
-- Contents of the Accept-Charset: header from the current request, if there is one.
-- Example: 'iso-8859-1,*,utf-8'.
do
Result := meta_string_variable ({WGI_META_NAMES}.http_accept_charset)
end
http_accept_encoding: detachable READABLE_STRING_8
-- Contents of the Accept-Encoding: header from the current request, if there is one.
-- Example: 'gzip'.
do
Result := meta_string_variable ({WGI_META_NAMES}.http_accept_encoding)
end
http_accept_language: detachable READABLE_STRING_8
-- Contents of the Accept-Language: header from the current request, if there is one.
-- Example: 'en'.
do
Result := meta_string_variable ({WGI_META_NAMES}.http_accept_language)
end
http_connection: detachable READABLE_STRING_8
-- Contents of the Connection: header from the current request, if there is one.
-- Example: 'Keep-Alive'.
do
Result := meta_string_variable ({WGI_META_NAMES}.http_connection)
end
http_host: detachable READABLE_STRING_8
-- Contents of the Host: header from the current request, if there is one.
do
Result := meta_string_variable ({WGI_META_NAMES}.http_host)
end
http_referer: detachable READABLE_STRING_8
-- The address of the page (if any) which referred the user agent to the current page.
-- This is set by the user agent.
-- Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature.
-- In short, it cannot really be trusted.
do
Result := meta_string_variable ({WGI_META_NAMES}.http_referer)
end
http_user_agent: detachable READABLE_STRING_8
-- Contents of the User-Agent: header from the current request, if there is one.
-- This is a string denoting the user agent being which is accessing the page.
-- A typical example is: Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586).
-- Among other things, you can use this value to tailor your page's
-- output to the capabilities of the user agent.
do
Result := meta_string_variable ({WGI_META_NAMES}.http_user_agent)
end
http_authorization: detachable READABLE_STRING_8
-- Contents of the Authorization: header from the current request, if there is one.
do
Result := meta_string_variable ({WGI_META_NAMES}.http_authorization)
end
feature -- Access: Extension to CGI meta parameters - 1.1
request_uri: READABLE_STRING_8
-- The URI which was given in order to access this page; for instance, '/index.html'.
orig_path_info: detachable READABLE_STRING_8
-- Original version of `path_info' before processed by Current environment
feature {NONE} -- Element change: CGI meta parameter related to PATH_INFO
set_meta_variables (a_vars: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8])
-- Fill with variable from `a_vars'
local
s: like meta_string_variable
table: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
l_query_string: like query_string
l_request_uri: detachable STRING_32
do
create {STRING_8} empty_string.make_empty
create table.make (a_vars.count)
table.compare_objects
meta_variables := table
from
a_vars.start
until
a_vars.after
loop
table.force (a_vars.item_for_iteration, a_vars.key_for_iteration)
a_vars.forth
end
--| QUERY_STRING
l_query_string := meta_string_variable_or_default ({WGI_META_NAMES}.query_string, empty_string, False)
query_string := l_query_string
--| REQUEST_METHOD
request_method := meta_string_variable_or_default ({WGI_META_NAMES}.request_method, empty_string, False)
--| CONTENT_TYPE
s := meta_string_variable ({WGI_META_NAMES}.content_type)
if s /= Void and then not s.is_empty then
content_type := s
else
content_type := Void
end
--| CONTENT_LENGTH
content_length := meta_string_variable ({WGI_META_NAMES}.content_length)
--| PATH_INFO
path_info := meta_string_variable_or_default ({WGI_META_NAMES}.path_info, empty_string, False)
--| SERVER_NAME
server_name := meta_string_variable_or_default ({WGI_META_NAMES}.server_name, empty_string, False)
--| SERVER_PORT
s := meta_string_variable ({WGI_META_NAMES}.server_port)
if s /= Void and then s.is_integer then
server_port := s.to_integer
else
server_port := 80
end
--| SCRIPT_NAME
script_name := meta_string_variable_or_default ({WGI_META_NAMES}.script_name, empty_string, False)
--| REMOTE_ADDR
remote_addr := meta_string_variable_or_default ({WGI_META_NAMES}.remote_addr, empty_string, False)
--| REMOTE_HOST
remote_host := meta_string_variable_or_default ({WGI_META_NAMES}.remote_host, empty_string, False)
--| REQUEST_URI
s := meta_string_variable ({WGI_META_NAMES}.request_uri)
if s /= Void then
l_request_uri := s
else
--| It might occur that REQUEST_URI is not available, so let's compute it from SCRIPT_NAME
create l_request_uri.make_from_string (script_name)
if not l_query_string.is_empty then
l_request_uri.append_character ('?')
l_request_uri.append (l_query_string)
end
end
request_uri := single_slash_starting_string (l_request_uri)
end
set_orig_path_info (s: READABLE_STRING_8)
-- Set ORIG_PATH_INFO to `s'
require
s_attached: s /= Void
do
orig_path_info := s
set_meta_string_variable ({WGI_META_NAMES}.orig_path_info, s)
end
unset_orig_path_info
-- Unset ORIG_PATH_INFO
do
orig_path_info := Void
unset_meta_variable ({WGI_META_NAMES}.orig_path_info)
ensure
unset: attached meta_variable ({WGI_META_NAMES}.orig_path_info)
end
update_path_info
-- Fix and update PATH_INFO value if needed
local
l_path_info: STRING
do
l_path_info := path_info
--| Warning
--| on IIS: we might have PATH_INFO = /sample.exe/foo/bar
--| on apache: PATH_INFO = /foo/bar
--| So, we might need to check with SCRIPT_NAME and remove it on IIS
--| store original PATH_INFO in ORIG_PATH_INFO
if l_path_info.is_empty then
unset_orig_path_info
else
set_orig_path_info (l_path_info)
if attached script_name as l_script_name then
if l_path_info.starts_with (l_script_name) then
path_info := l_path_info.substring (l_script_name.count + 1 , l_path_info.count)
end
end
end
end
feature {NONE} -- I/O: implementation
read_input (nb: INTEGER)
-- Read `nb' bytes from `input'
do
input.read_stream (nb)
end
last_input_string: STRING
-- Last string read from `input'
do
Result := input.last_string
end
feature {NONE} -- Implementation: utilities
single_slash_starting_string (s: READABLE_STRING_8): STRING_8
-- Return the string `s' (or twin) with one and only one starting slash
local
i, n: INTEGER
do
n := s.count
if n > 1 then
if s[1] /= '/' then
create Result.make (1 + n)
Result.append_character ('/')
Result.append (s)
elseif s[2] = '/' then
--| We need to remove all starting slash, except one
from
i := 3
until
i > n
loop
if s[i] /= '/' then
n := 0 --| exit loop
else
i := i + 1
end
end
n := s.count
check i >= 2 and i <= n end
Result := s.substring (i - 1, s.count)
else
--| starts with one '/' and only one
Result := s
end
elseif n = 1 then
if s[1] = '/' then
Result := s
else
create Result.make (2)
Result.append_character ('/')
Result.append (s)
end
else --| n = 0
create Result.make_filled ('/', 1)
end
ensure
one_starting_slash: Result[1] = '/' and (Result.count = 1 or else Result[2] /= '/')
end
empty_string: READABLE_STRING_8
-- Reusable empty string
invariant
empty_string_unchanged: empty_string.is_empty
note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -144,6 +144,17 @@ feature -- Content related header
add_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t) add_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t)
end end
put_content_type_with_charset (t: READABLE_STRING_8; c: READABLE_STRING_8)
do
put_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t + "; charset=" + c + "")
end
add_content_type_with_charset (t: READABLE_STRING_8; c: READABLE_STRING_8)
-- same as `put_content_type_with_charset', but allow multiple definition of "Content-Type"
do
add_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t + "; charset=" + c + "")
end
put_content_type_with_name (t: READABLE_STRING_8; n: READABLE_STRING_8) put_content_type_with_name (t: READABLE_STRING_8; n: READABLE_STRING_8)
do do
put_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t + "; name=%"" + n + "%"") put_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t + "; name=%"" + n + "%"")

View File

@@ -25,43 +25,7 @@ feature -- Execution
res_status_set: res.status_is_set res_status_set: res.status_is_set
end end
feature -- Process request note
frozen process (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
-- Process request with environment `env', and i/o streams `a_input' and `a_output'
local
rescued: BOOLEAN
do
if not rescued then
request_count := request_count + 1
execute (req, res)
else
rescue_execute (req, res, (create {EXCEPTION_MANAGER}).last_exception)
end
if res /= Void then
res.commit
end
end
feature -- Access
request_count: INTEGER
-- Request count
feature {NONE} -- Execution
rescue_execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_exception: detachable EXCEPTION)
-- Operation processed on rescue of `execute'
do
if
a_exception /= Void and then attached a_exception.exception_trace as l_trace
then
res.write_header ({HTTP_STATUS_CODE}.internal_server_error, Void)
res.write_string ("<pre>" + l_trace + "</pre>")
end
end
;note
copyright: "2011-2011, Eiffel Software and others" copyright: "2011-2011, 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: "[

File diff suppressed because it is too large Load Diff

View File

@@ -7,12 +7,13 @@
<exclude>/\.git$</exclude> <exclude>/\.git$</exclude>
<exclude>/\.svn$</exclude> <exclude>/\.svn$</exclude>
</file_rule> </file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all"/> <option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all">
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf"/> <library name="wsf" location="..\..\wsf\wsf-safe.ecf" readonly="false"/>
<library name="http" location="..\..\..\protocol\http\http-safe.ecf"/> <library name="http" location="..\..\..\protocol\http\http-safe.ecf"/>
<library name="router" location="..\..\request\router\router-safe.ecf" readonly="false"/> <library name="router" location="..\..\request\router\router-safe.ecf" readonly="false"/>
<library name="uri_template" location="..\..\..\protocol\uri_template\uri_template-safe.ecf"/> <library name="uri_template" location="..\..\..\protocol\uri_template\uri_template-safe.ecf" readonly="false"/>
<cluster name="contrib" location=".\src\contrib\" recursive="true"> <cluster name="contrib" location=".\src\contrib\" recursive="true">
<file_rule> <file_rule>
<exclude>/html$</exclude> <exclude>/html$</exclude>

View File

@@ -9,7 +9,7 @@
</file_rule> </file_rule>
<option warning="true" full_class_checking="true"/> <option warning="true" full_class_checking="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="ewsgi" location="..\..\ewsgi\ewsgi.ecf"/> <library name="wsf" location="..\..\wsf\wsf.ecf"/>
<library name="http" location="..\..\..\protocol\http\http.ecf"/> <library name="http" location="..\..\..\protocol\http\http.ecf"/>
<library name="router" location="..\..\request\router\router.ecf" readonly="false"/> <library name="router" location="..\..\request\router\router.ecf" readonly="false"/>
<library name="uri_template" location="..\..\..\protocol\uri_template\uri_template.ecf"/> <library name="uri_template" location="..\..\..\protocol\uri_template\uri_template.ecf"/>

View File

@@ -31,7 +31,7 @@ feature {NONE} -- Initialization
feature -- Access feature -- Access
headers: EWF_HEADER headers: WSF_HEADER
feature -- Recycle feature -- Recycle
@@ -155,7 +155,7 @@ feature -- Output
Result := o Result := o
end end
send (buf: WGI_RESPONSE_BUFFER) send (buf: WSF_RESPONSE)
do do
buf.set_status_code (200) buf.set_status_code (200)
buf.write_headers_string (header_string) buf.write_headers_string (header_string)

View File

@@ -30,13 +30,13 @@ feature {NONE} -- Access: Implementation
feature -- Access feature -- Access
authentication_required (req: WGI_REQUEST): BOOLEAN authentication_required (req: WSF_REQUEST): BOOLEAN
do do
end end
feature -- Execution feature -- Execution
execute_application (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
local local
rep: like new_html_page rep: like new_html_page
s: STRING s: STRING
@@ -50,7 +50,7 @@ feature -- Execution
create s.make_empty create s.make_empty
if if
attached {WGI_STRING_VALUE} ctx.path_parameter ("resource") as l_resource_value and then attached {WSF_STRING_VALUE} ctx.path_parameter ("resource") as l_resource_value and then
attached l_resource_value.string as l_resource attached l_resource_value.string as l_resource
then then
from from
@@ -114,7 +114,7 @@ feature -- Execution
rep.recycle rep.recycle
end end
process_request_handler_doc (rq: REST_REQUEST_HANDLER [C]; a_resource: STRING; buf: STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_dft_format: detachable STRING) process_request_handler_doc (rq: REST_REQUEST_HANDLER [C]; a_resource: STRING; buf: STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE; a_dft_format: detachable STRING)
local local
l_dft_format_name: detachable STRING l_dft_format_name: detachable STRING
s: STRING s: STRING

View File

@@ -32,7 +32,7 @@ feature -- Recycle
feature -- Access feature -- Access
headers: EWF_HEADER headers: WSF_HEADER
api: STRING api: STRING
-- Associated api query string. -- Associated api query string.
@@ -129,7 +129,7 @@ feature -- Output
Result := o Result := o
end end
send (res: WGI_RESPONSE_BUFFER) send (res: WSF_RESPONSE)
do do
compute compute
res.set_status_code (200) res.set_status_code (200)

View File

@@ -23,7 +23,7 @@ create
feature -- status feature -- status
authentication_required (req: WGI_REQUEST): BOOLEAN authentication_required (req: WSF_REQUEST): BOOLEAN
do do
Result := internal_authentication_required Result := internal_authentication_required
end end

View File

@@ -15,7 +15,7 @@ inherit
feature -- Access feature -- Access
authentication_required (req: WGI_REQUEST): BOOLEAN authentication_required (req: WSF_REQUEST): BOOLEAN
-- Is authentication required -- Is authentication required
-- might depend on the request environment -- might depend on the request environment
-- or the associated resources -- or the associated resources
@@ -35,7 +35,7 @@ feature -- Element change
feature -- Execution feature -- Execution
execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler -- Execute request handler
local local
rescued: BOOLEAN rescued: BOOLEAN
@@ -60,24 +60,24 @@ feature -- Execution
retry retry
end end
execute_application (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
deferred deferred
end end
pre_execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) pre_execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
end end
post_execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) post_execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
end end
rescue_execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) rescue_execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
post_execute (ctx, req, res) post_execute (ctx, req, res)
end end
execute_unauthorized (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_unauthorized (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
res.set_status_code ({HTTP_STATUS_CODE}.unauthorized) res.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
res.write_header ({HTTP_STATUS_CODE}.unauthorized, Void) res.write_header ({HTTP_STATUS_CODE}.unauthorized, Void)
@@ -233,45 +233,45 @@ feature -- Status report
do do
create {LINKED_LIST [STRING]} Result.make create {LINKED_LIST [STRING]} Result.make
if method_get_supported then if method_get_supported then
Result.extend (request_method_constants.method_get_name) Result.extend (request_method_constants.method_get)
end end
if method_post_supported then if method_post_supported then
Result.extend (request_method_constants.method_post_name) Result.extend (request_method_constants.method_post)
end end
if method_put_supported then if method_put_supported then
Result.extend (request_method_constants.method_put_name) Result.extend (request_method_constants.method_put)
end end
if method_delete_supported then if method_delete_supported then
Result.extend (request_method_constants.method_delete_name) Result.extend (request_method_constants.method_delete)
end end
if method_head_supported then if method_head_supported then
Result.extend (request_method_constants.method_head_name) Result.extend (request_method_constants.method_head)
end end
end end
method_get_supported: BOOLEAN method_get_supported: BOOLEAN
do do
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.method_get) Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.get)
end end
method_post_supported: BOOLEAN method_post_supported: BOOLEAN
do do
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.method_post) Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.post)
end end
method_put_supported: BOOLEAN method_put_supported: BOOLEAN
do do
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.method_put) Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.put)
end end
method_delete_supported: BOOLEAN method_delete_supported: BOOLEAN
do do
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.method_delete) Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.delete)
end end
method_head_supported: BOOLEAN method_head_supported: BOOLEAN
do do
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.method_head) Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.head)
end end
feature -- Element change: request methods feature -- Element change: request methods
@@ -283,27 +283,27 @@ feature -- Element change: request methods
enable_request_method_get enable_request_method_get
do do
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.method_get) enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.get)
end end
enable_request_method_post enable_request_method_post
do do
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.method_post) enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.post)
end end
enable_request_method_put enable_request_method_put
do do
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.method_put) enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.put)
end end
enable_request_method_delete enable_request_method_delete
do do
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.method_delete) enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.delete)
end end
enable_request_method_head enable_request_method_head
do do
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.method_head) enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.head)
end end
enable_request_method (m: INTEGER) enable_request_method (m: INTEGER)

View File

@@ -18,7 +18,7 @@ create
feature -- Mapping feature -- Mapping
map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REST_REQUEST_URI_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]]; map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REST_REQUEST_URI_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]];
rqst_methods: detachable ARRAY [READABLE_STRING_8]) rqst_methods: detachable ARRAY [READABLE_STRING_8])
local local
h: REST_REQUEST_AGENT_HANDLER [REST_REQUEST_URI_HANDLER_CONTEXT] h: REST_REQUEST_AGENT_HANDLER [REST_REQUEST_URI_HANDLER_CONTEXT]

View File

@@ -25,7 +25,7 @@ create
feature -- Status report feature -- Status report
authentication_required (req: WGI_REQUEST): BOOLEAN authentication_required (req: WSF_REQUEST): BOOLEAN
do do
Result := internal_authentication_required Result := internal_authentication_required
end end
@@ -36,12 +36,12 @@ feature {NONE} -- Implementation
feature -- Execution feature -- Execution
execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
Precursor {REQUEST_URI_ROUTING_HANDLER_I} (ctx, req, res) Precursor {REQUEST_URI_ROUTING_HANDLER_I} (ctx, req, res)
end end
execute_application (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
check should_not_occur: False end check should_not_occur: False end
end end

View File

@@ -18,7 +18,7 @@ create
feature -- Mapping feature -- Mapping
map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]]; map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]];
rqst_methods: detachable ARRAY [READABLE_STRING_8]) rqst_methods: detachable ARRAY [READABLE_STRING_8])
local local
h: REST_REQUEST_AGENT_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT] h: REST_REQUEST_AGENT_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT]

View File

@@ -25,7 +25,7 @@ create
feature -- Status report feature -- Status report
authentication_required (req: WGI_REQUEST): BOOLEAN authentication_required (req: WSF_REQUEST): BOOLEAN
do do
Result := internal_authentication_required Result := internal_authentication_required
end end
@@ -36,14 +36,14 @@ feature {NONE} -- Implementation
feature -- Execution feature -- Execution
execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
pre_execute (ctx, req, res) pre_execute (ctx, req, res)
Precursor {REQUEST_URI_TEMPLATE_ROUTING_HANDLER_I} (ctx, req, res) Precursor {REQUEST_URI_TEMPLATE_ROUTING_HANDLER_I} (ctx, req, res)
post_execute (ctx, req, res) post_execute (ctx, req, res)
end end
execute_application (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
check should_not_occur: False end check should_not_occur: False end
end end

View File

@@ -12,7 +12,7 @@
<setting name="concurrency" value="thread"/> <setting name="concurrency" value="thread"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="rest" location="..\rest-safe.ecf" readonly="false"/> <library name="rest" location="..\rest-safe.ecf" readonly="false"/>
<library name="ewsgi" location="..\..\..\ewsgi\ewsgi-safe.ecf" readonly="false"/> <library name="wsf" location="..\..\..\wsf\wsf-safe.ecf" readonly="false"/>
<library name="http" location="..\..\..\..\protocol\http\http-safe.ecf" readonly="false"/> <library name="http" location="..\..\..\..\protocol\http\http-safe.ecf" readonly="false"/>
</target> </target>
<target name="sample_fcgi" extends="common"> <target name="sample_fcgi" extends="common">
@@ -42,7 +42,7 @@
<root class="APP_SERVER" feature="make"/> <root class="APP_SERVER" feature="make"/>
<setting name="executable_name" value="sample"/> <setting name="executable_name" value="sample"/>
<library name="ewsgi_nino" location="..\..\..\ewsgi/connectors\nino\nino-safe.ecf" readonly="false"/> <library name="ewsgi_nino" location="..\..\..\ewsgi/connectors\nino\nino-safe.ecf" readonly="false"/>
<library name="ewsgi_default_nino" location="..\..\..\ewsgi/default\ewsgi_nino-safe.ecf" readonly="false"/> <library name="default_nino" location="..\..\..\wsf\default\nino-safe.ecf" readonly="false"/>
<cluster name="src" location=".\src\" recursive="true"> <cluster name="src" location=".\src\" recursive="true">

View File

@@ -35,14 +35,14 @@ feature {NONE} -- Initialization
feature -- Access feature -- Access
authentication_required (req: WGI_REQUEST): BOOLEAN authentication_required (req: WSF_REQUEST): BOOLEAN
do do
Result := True Result := True
end end
feature -- Execution feature -- Execution
execute_unauthorized (a_hdl_context: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_unauthorized (a_hdl_context: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
local local
s: STRING s: STRING
lst: LIST [STRING] lst: LIST [STRING]
@@ -52,16 +52,16 @@ feature -- Execution
res.write_string ("Unauthorized") res.write_string ("Unauthorized")
end end
execute_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
local local
l_full: BOOLEAN l_full: BOOLEAN
h: EWF_HEADER h: WSF_HEADER
l_login: STRING_8 l_login: STRING_8
s: STRING s: STRING
content_type_supported: ARRAY [STRING] content_type_supported: ARRAY [STRING]
l_format_id: INTEGER l_format_id: INTEGER
do do
content_type_supported := <<{HTTP_CONSTANTS}.json_app, {HTTP_CONSTANTS}.xml_text, {HTTP_CONSTANTS}.plain_text>> content_type_supported := <<{HTTP_CONSTANTS}.application_json, {HTTP_CONSTANTS}.text_xml, {HTTP_CONSTANTS}.text_plain>>
l_format_id := ctx.request_format_id ("format", content_type_supported) l_format_id := ctx.request_format_id ("format", content_type_supported)
if authenticated (ctx) then if authenticated (ctx) then
l_full := attached ctx.query_parameter ("details") as v and then v.is_case_insensitive_equal ("true") l_full := attached ctx.query_parameter ("details") as v and then v.is_case_insensitive_equal ("true")

View File

@@ -32,17 +32,17 @@ feature {NONE} -- Initialization
feature -- Access feature -- Access
authentication_required (req: WGI_REQUEST): BOOLEAN authentication_required (req: WSF_REQUEST): BOOLEAN
do do
end end
feature -- Execution feature -- Execution
execute_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler -- Execute request handler
local local
s: STRING s: STRING
h: EWF_HEADER h: WSF_HEADER
do do
create h.make create h.make
h.put_content_type_text_plain h.put_content_type_text_plain

View File

@@ -68,17 +68,17 @@ feature {NONE} -- Handlers
feature -- Execution feature -- Execution
execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute (req: WSF_REQUEST; res: WSF_RESPONSE)
do do
request_count := request_count + 1 request_count := request_count + 1
Precursor (req, res) Precursor (req, res)
end end
execute_default (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_default (req: WSF_REQUEST; res: WSF_RESPONSE)
local local
rqst_uri: detachable STRING rqst_uri: detachable STRING
l_path_info: detachable STRING l_path_info: detachable STRING
h: EWF_HEADER h: WSF_HEADER
s: STRING s: STRING
l_redir_url: STRING l_redir_url: STRING
do do
@@ -96,6 +96,8 @@ feature -- Execution
res.write_string (s) res.write_string (s)
end end
request_count: INTEGER
-- execute_rescue (ctx: like new_request_context) -- execute_rescue (ctx: like new_request_context)
-- -- Execute the default rescue behavior -- -- Execute the default rescue behavior
-- do -- do
@@ -106,7 +108,7 @@ feature -- Implementation
-- execute_exception_trace (ctx: like new_request_context) -- execute_exception_trace (ctx: like new_request_context)
-- local -- local
-- h: EWF_HEADER -- h: WSF_HEADER
-- s: STRING -- s: STRING
-- do -- do
-- create h.make -- create h.make
@@ -121,7 +123,7 @@ feature -- Implementation
-- exit_with_code (-1) -- exit_with_code (-1)
-- end -- end
execute_exit_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_exit_application (ctx: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
local local
s: STRING s: STRING
do do

View File

@@ -2,17 +2,17 @@ deferred class
REST_APPLICATION_GATEWAY REST_APPLICATION_GATEWAY
inherit inherit
WGI_APPLICATION WSF_APPLICATION
feature -- Access feature -- Access
build_gateway_and_launch build_gateway_and_launch
local local
cgi: EWF_CGI_CONNECTOR cgi: WGI_CGI_CONNECTOR
do do
create cgi.make (Current) create cgi.make (Current)
cgi.launch cgi.launch
end end
gateway_name: STRING = "CGI" gateway_name: STRING = "CGI"
@@ -20,5 +20,5 @@ feature -- Access
do do
(create {EXCEPTIONS}).die (a_code) (create {EXCEPTIONS}).die (a_code)
end end
end end

View File

@@ -2,13 +2,13 @@ deferred class
REST_APPLICATION_GATEWAY REST_APPLICATION_GATEWAY
inherit inherit
WGI_APPLICATION WSF_APPLICATION
feature -- Access feature -- Access
build_gateway_and_launch build_gateway_and_launch
local local
libfcgi: EWF_LIBFCGI_CONNECTOR libfcgi: WGI_LIBFCGI_CONNECTOR
do do
create libfcgi.make (Current) create libfcgi.make (Current)
libfcgi.launch libfcgi.launch

View File

@@ -2,7 +2,7 @@ deferred class
REST_APPLICATION_GATEWAY REST_APPLICATION_GATEWAY
inherit inherit
WGI_APPLICATION WSF_APPLICATION
feature -- Access feature -- Access
@@ -18,7 +18,7 @@ feature -- Access
print ("Example: start a Nino web server on port " + port_number.out + print ("Example: start a Nino web server on port " + port_number.out +
", %Nand reply Hello World for any request such as http://localhost:" + port_number.out + "/" + base_url + "%N") ", %Nand reply Hello World for any request such as http://localhost:" + port_number.out + "/" + base_url + "%N")
end end
create app.make_custom (agent execute, base_url) create app.make_custom (agent wgi_execute, base_url)
app.force_single_threaded app.force_single_threaded
app.listen (port_number) app.listen (port_number)

View File

@@ -23,7 +23,7 @@ feature {NONE} -- Initialization
feature {NONE} -- Implementation feature {NONE} -- Implementation
wgi_value_iteration_to_string (v: ITERABLE [WGI_VALUE]; using_pre: BOOLEAN): STRING_8 wgi_value_iteration_to_string (v: ITERABLE [WSF_VALUE]; using_pre: BOOLEAN): STRING_8
do do
create Result.make (100) create Result.make (100)
if using_pre then if using_pre then

View File

@@ -16,14 +16,14 @@ create
feature -- Format feature -- Format
get_format_id (a_format_variable_name: detachable READABLE_STRING_GENERAL; a_content_type_supported: detachable ARRAY [STRING_8]) get_format_id (a_format_variable_name: detachable READABLE_STRING_8; a_content_type_supported: detachable ARRAY [STRING_8])
do do
if internal_format_id = 0 then if internal_format_id = 0 then
internal_format_id := request_format_id (a_format_variable_name, a_content_type_supported) internal_format_id := request_format_id (a_format_variable_name, a_content_type_supported)
end end
end end
get_format_name (a_format_variable_name: detachable READABLE_STRING_GENERAL; a_content_type_supported: detachable ARRAY [STRING_8]) get_format_name (a_format_variable_name: detachable READABLE_STRING_8; a_content_type_supported: detachable ARRAY [STRING_8])
do do
if internal_format_name = Void then if internal_format_name = Void then
internal_format_name := request_format (a_format_variable_name, a_content_type_supported) internal_format_name := request_format (a_format_variable_name, a_content_type_supported)

View File

@@ -9,7 +9,7 @@ deferred class
feature -- Helpers feature -- Helpers
send_error (a_path: STRING; a_error_id: INTEGER; a_error_name: STRING; a_error_message: detachable STRING; ctx: APP_REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) send_error (a_path: STRING; a_error_id: INTEGER; a_error_name: STRING; a_error_message: detachable STRING; ctx: APP_REQUEST_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
local local
s: STRING s: STRING
i,nb: INTEGER i,nb: INTEGER

View File

@@ -12,7 +12,7 @@
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/> <library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/>
<library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf" readonly="false"/> <library name="wsf" location="..\..\wsf\wsf-safe.ecf" readonly="false"/>
<library name="http" location="..\..\..\protocol\http\http-safe.ecf"/> <library name="http" location="..\..\..\protocol\http\http-safe.ecf"/>
<library name="uri_template" location="..\..\..\protocol\uri_template\uri_template-safe.ecf" readonly="false"/> <library name="uri_template" location="..\..\..\protocol\uri_template\uri_template-safe.ecf" readonly="false"/>
<cluster name="src" location="src\" recursive="true"/> <cluster name="src" location="src\" recursive="true"/>
@@ -29,7 +29,7 @@
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/> <library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/>
<library name="ewsgi" location="..\..\ewsgi\ewsgi_spec-safe.ecf" readonly="false"/> <library name="wsf" location="..\..\wsf\wsf_spec-safe.ecf" readonly="false"/>
<library name="http" location="..\..\..\protocol\http\http-safe.ecf"/> <library name="http" location="..\..\..\protocol\http\http-safe.ecf"/>
<library name="uri_template" location="..\..\..\protocol\uri_template\uri_template-safe.ecf" readonly="false"/> <library name="uri_template" location="..\..\..\protocol\uri_template\uri_template-safe.ecf" readonly="false"/>
<cluster name="src" location="src\" recursive="true"/> <cluster name="src" location="src\" recursive="true"/>

View File

@@ -12,7 +12,7 @@
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension.ecf"/> <library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension.ecf"/>
<library name="ewsgi" location="..\..\ewsgi\ewsgi.ecf"/> <library name="wsf" location="..\..\wsf\wsf.ecf"/>
<library name="http" location="..\..\..\protocol\http\http.ecf"/> <library name="http" location="..\..\..\protocol\http\http.ecf"/>
<library name="uri_template" location="..\..\..\protocol\uri_template\uri_template.ecf"/> <library name="uri_template" location="..\..\..\protocol\uri_template\uri_template.ecf"/>
<cluster name="src" location="src\" recursive="true"/> <cluster name="src" location="src\" recursive="true"/>
@@ -29,7 +29,7 @@
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension.ecf"/> <library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension.ecf"/>
<library name="ewsgi" location="..\..\ewsgi\ewsgi.ecf"/> <library name="wsf" location="..\..\wsf\wsf.ecf"/>
<library name="http" location="..\..\..\protocol\http\http.ecf"/> <library name="http" location="..\..\..\protocol\http\http.ecf"/>
<library name="uri_template" location="..\..\..\protocol\uri_template\uri_template.ecf"/> <library name="uri_template" location="..\..\..\protocol\uri_template\uri_template.ecf"/>
<cluster name="src" location="src\" recursive="true"/> <cluster name="src" location="src\" recursive="true"/>

View File

@@ -9,19 +9,16 @@ class
feature -- Access feature -- Access
accepted_content_types (req: WGI_REQUEST): detachable ARRAYED_LIST [READABLE_STRING_8] accepted_content_types (req: WSF_REQUEST): detachable ARRAYED_LIST [READABLE_STRING_8]
local local
l_accept: detachable READABLE_STRING_32
s: STRING_8 s: STRING_8
q: READABLE_STRING_8 q: READABLE_STRING_8
p: INTEGER p: INTEGER
lst: LIST [READABLE_STRING_8] lst: LIST [READABLE_STRING_8]
qs: QUICK_SORTER [READABLE_STRING_8] qs: QUICK_SORTER [READABLE_STRING_8]
do do
l_accept := req.http_accept --TEST if attached ("text/html,application/xhtml+xml;q=0.6,application/xml;q=0.2,text/plain;q=0.5,*/*;q=0.8") as l_accept then
--TEST l_accept := "text/html,application/xhtml+xml;q=0.6,application/xml;q=0.2,text/plain;q=0.5,*/*;q=0.8" if attached req.http_accept as l_accept then
if l_accept /= Void then
lst := l_accept.as_string_8.split (',') lst := l_accept.as_string_8.split (',')
create Result.make (lst.count) create Result.make (lst.count)
from from

View File

@@ -9,7 +9,7 @@ class
feature -- Execute template feature -- Execute template
execute_methods (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_methods (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request and dispatch according to the request method -- Execute request and dispatch according to the request method
local local
m: READABLE_STRING_8 m: READABLE_STRING_8
@@ -41,7 +41,7 @@ feature -- Execute template
feature -- Method Post feature -- Method Post
execute_post (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_post (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
if req.content_length_value > 0 then if req.content_length_value > 0 then
do_post (ctx, req, res) do_post (ctx, req, res)
@@ -50,14 +50,14 @@ feature -- Method Post
end end
end end
do_post (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) do_post (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
handle_not_implemented ("Method POST not implemented", ctx, req, res) handle_not_implemented ("Method POST not implemented", ctx, req, res)
end end
feature-- Method Put feature-- Method Put
execute_put (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_put (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
if req.content_length_value > 0 then if req.content_length_value > 0 then
do_put (ctx, req, res) do_put (ctx, req, res)
@@ -66,91 +66,91 @@ feature-- Method Put
end end
end end
do_put (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) do_put (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
handle_not_implemented ("Method PUT not implemented", ctx, req, res) handle_not_implemented ("Method PUT not implemented", ctx, req, res)
end end
feature -- Method Get feature -- Method Get
execute_get (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_get (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
do_get (ctx, req, res) do_get (ctx, req, res)
end end
do_get (ctx: C;req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) do_get (ctx: C;req: WSF_REQUEST; res: WSF_RESPONSE)
do do
handle_not_implemented ("Method HEAD not implemented", ctx, req, res) handle_not_implemented ("Method HEAD not implemented", ctx, req, res)
end end
feature -- Method DELETE feature -- Method DELETE
execute_delete (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_delete (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
do_delete (ctx, req, res) do_delete (ctx, req, res)
end end
do_delete (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) do_delete (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
handle_not_implemented ("Method DELETE not implemented", ctx, req, res) handle_not_implemented ("Method DELETE not implemented", ctx, req, res)
end end
feature -- Method CONNECT feature -- Method CONNECT
execute_connect (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_connect (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
do_connect (ctx, req, res) do_connect (ctx, req, res)
end end
do_connect (ctx: C;req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) do_connect (ctx: C;req: WSF_REQUEST; res: WSF_RESPONSE)
do do
handle_not_implemented ("Method CONNECT not implemented", ctx, req, res) handle_not_implemented ("Method CONNECT not implemented", ctx, req, res)
end end
feature -- Method HEAD feature -- Method HEAD
execute_head (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_head (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
do_head (ctx, req, res) do_head (ctx, req, res)
end end
do_head (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) do_head (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
handle_not_implemented ("Method HEAD not implemented", ctx, req, res) handle_not_implemented ("Method HEAD not implemented", ctx, req, res)
end end
feature -- Method OPTIONS feature -- Method OPTIONS
execute_options (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_options (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
do_options (ctx, req, res) do_options (ctx, req, res)
end end
do_options (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) do_options (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
handle_not_implemented ("Method OPTIONS not implemented", ctx, req, res) handle_not_implemented ("Method OPTIONS not implemented", ctx, req, res)
end end
feature -- Method TRACE feature -- Method TRACE
execute_trace (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_trace (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
do_trace (ctx, req, res) do_trace (ctx, req, res)
end end
do_trace (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) do_trace (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
handle_not_implemented ("Method TRACE not implemented", ctx, req, res) handle_not_implemented ("Method TRACE not implemented", ctx, req, res)
end end
feature -- Method Extension Method feature -- Method Extension Method
execute_extension_method (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_extension_method (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
do_extension_method (ctx, req, res) do_extension_method (ctx, req, res)
end end
do_extension_method (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) do_extension_method (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
handle_not_implemented ("Method extension-method not implemented", ctx, req, res) handle_not_implemented ("Method extension-method not implemented", ctx, req, res)
end end
@@ -164,9 +164,9 @@ feature -- Handle responses
Result := Void Result := Void
end end
handle_bad_request_response (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER ) handle_bad_request_response (a_description:STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE )
local local
h : EWF_HEADER h : WSF_HEADER
do do
create h.make create h.make
h.put_status ({HTTP_STATUS_CODE}.bad_request) h.put_status ({HTTP_STATUS_CODE}.bad_request)
@@ -182,9 +182,9 @@ feature -- Handle responses
res.write_string (a_description) res.write_string (a_description)
end end
handle_internal_server_error (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER ) handle_internal_server_error (a_description:STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE )
local local
h : EWF_HEADER h : WSF_HEADER
do do
create h.make create h.make
h.put_status ({HTTP_STATUS_CODE}.internal_server_error) h.put_status ({HTTP_STATUS_CODE}.internal_server_error)
@@ -202,9 +202,9 @@ feature -- Handle responses
res.write_string (a_description) res.write_string (a_description)
end end
handle_not_implemented (a_description: STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER ) handle_not_implemented (a_description: STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE )
local local
h : EWF_HEADER h : WSF_HEADER
do do
create h.make create h.make
h.put_status ({HTTP_STATUS_CODE}.not_implemented) h.put_status ({HTTP_STATUS_CODE}.not_implemented)
@@ -220,9 +220,9 @@ feature -- Handle responses
res.write_string (a_description) res.write_string (a_description)
end end
handle_resource_not_found_response (a_description:STRING; ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) handle_resource_not_found_response (a_description:STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
local local
h : EWF_HEADER h : WSF_HEADER
do do
create h.make create h.make
h.put_status ({HTTP_STATUS_CODE}.not_found) h.put_status ({HTTP_STATUS_CODE}.not_found)

View File

@@ -12,7 +12,7 @@ inherit
feature -- Helper feature -- Helper
execute_content_type_not_allowed (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_content_types: detachable ARRAY [STRING]; a_uri_formats: detachable ARRAY [STRING]) execute_content_type_not_allowed (req: WSF_REQUEST; res: WSF_RESPONSE; a_content_types: detachable ARRAY [STRING]; a_uri_formats: detachable ARRAY [STRING])
local local
accept_s, uri_s: detachable STRING accept_s, uri_s: detachable STRING
i, n: INTEGER i, n: INTEGER
@@ -62,7 +62,7 @@ feature -- Helper
end end
end end
execute_request_method_not_allowed (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_methods: ITERABLE [STRING]) execute_request_method_not_allowed (req: WSF_REQUEST; res: WSF_RESPONSE; a_methods: ITERABLE [STRING])
local local
s: STRING s: STRING
do do

View File

@@ -22,11 +22,11 @@ feature -- Initialization
feature -- Access feature -- Access
action: PROCEDURE [ANY, TUPLE [ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]] action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]
feature -- Execution feature -- Execution
execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
action.call ([ctx, req, res]) action.call ([ctx, req, res])
end end

View File

@@ -0,0 +1,335 @@
note
description: "[
Request handler used to respond file system request.
]"
date: "$Date$"
revision: "$Revision$"
class
REQUEST_FILE_SYSTEM_HANDLER [C -> REQUEST_HANDLER_CONTEXT]
inherit
REQUEST_HANDLER [C]
create
make
feature {NONE} -- Initialization
make (a_root: READABLE_STRING_8)
require
a_root_exists: node_exists (a_root)
do
document_root := a_root
end
feature -- Access
document_root: READABLE_STRING_8
-- Document root for the file system
directory_index: detachable ARRAY [READABLE_STRING_8]
-- File serve if a directory index is requested
feature -- Element change
set_directory_index (idx: like directory_index)
-- Set `directory_index' as `idx'
do
if idx = Void or else idx.is_empty then
directory_index := Void
else
directory_index := idx
end
end
feature -- Execution
execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
local
h: WSF_HEADER
s: STRING
uri: STRING
do
if attached ctx.path_parameter ("path") as l_path then
uri := l_path.as_string
process_uri (uri, ctx, req, res)
else
create h.make
h.put_content_type_text_html
s := "Hello " + ctx.path + "%N"
s.append ("root=" + document_root)
h.put_content_length (s.count)
res.set_status_code ({HTTP_STATUS_CODE}.ok)
res.write_headers_string (h.string)
res.write_string (s)
end
end
process_uri (uri: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
local
f: RAW_FILE
fn: READABLE_STRING_8
do
fn := resource_filename (uri)
create f.make (fn)
if f.exists then
if f.is_readable then
if f.is_directory then
respond_index (req.request_uri, fn, ctx, req, res)
else
respond_file (f, ctx, req, res)
end
else
respond_access_denied (uri, ctx, req, res)
end
else
respond_not_found (uri, ctx, req, res)
end
end
respond_index (a_uri: READABLE_STRING_8; dn: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
local
h: WSF_HEADER
uri, s: STRING_8
d: DIRECTORY
l_files: LIST [STRING_8]
do
create d.make_open_read (dn)
if attached directory_index_file (d) as f then
respond_file (f, ctx, req, res)
else
uri := a_uri
if not uri.is_empty and then uri [uri.count] /= '/' then
uri.append_character ('/')
end
s := "[
<html>
<head>
<title>Index for folder: $URI</title>
</head>
<body>
<h1>Index for $URI</h1>
<ul>
]"
s.replace_substring_all ("$URI", uri)
from
l_files := d.linear_representation
l_files.start
until
l_files.after
loop
s.append ("<li><a href=%"" + uri + l_files.item_for_iteration + "%">" + l_files.item_for_iteration + "</a></li>%N")
l_files.forth
end
s.append ("[
</ul>
</body>
</html>
]"
)
create h.make
h.put_content_type_text_html
res.set_status_code ({HTTP_STATUS_CODE}.ok)
h.put_content_length (s.count)
res.write_headers_string (h.string)
if not req.request_method.same_string ({HTTP_REQUEST_METHODS}.method_head) then
res.write_string (s)
end
res.flush
end
d.close
end
respond_file (f: FILE; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
local
fn: READABLE_STRING_8
h: WSF_HEADER
ext: READABLE_STRING_8
ct: detachable READABLE_STRING_8
do
fn := f.name
ext := extension (fn)
ct := extension_mime_mapping.mime_type (ext)
create h.make
if ct /= Void then
h.put_content_type (ct)
h.put_content_length (f.count)
res.set_status_code ({HTTP_STATUS_CODE}.ok)
res.write_headers_string (h.string)
else
create h.make
h.put_content_type ({HTTP_MIME_TYPES}.application_force_download)
h.put_content_length (f.count)
res.set_status_code ({HTTP_STATUS_CODE}.ok)
res.write_headers_string (h.string)
end
if not req.request_method.same_string ({HTTP_REQUEST_METHODS}.method_head) then
res.write_file_content (fn)
end
res.flush
end
respond_not_found (uri: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
local
h: WSF_HEADER
s: STRING_8
do
create h.make
h.put_content_type_text_plain
create s.make_empty
s.append ("Resource %"" + uri + "%" not found%N")
res.set_status_code ({HTTP_STATUS_CODE}.not_found)
h.put_content_length (s.count)
res.write_headers_string (h.string)
res.write_string (s)
res.flush
end
respond_access_denied (uri: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
local
h: WSF_HEADER
s: STRING_8
do
create h.make
h.put_content_type_text_plain
create s.make_empty
s.append ("Resource %"" + uri + "%": Access denied%N")
res.set_status_code ({HTTP_STATUS_CODE}.forbidden)
h.put_content_length (s.count)
res.write_headers_string (h.string)
res.write_string (s)
res.flush
end
feature {NONE} -- Implementation
directory_index_file (d: DIRECTORY): detachable FILE
local
f: detachable RAW_FILE
fn: FILE_NAME
do
if attached directory_index as default_index then
across
default_index as c
until
Result /= Void
loop
if d.has_entry (c.item) then
create fn.make_from_string (d.name)
fn.set_file_name (c.item)
if f = Void then
create f.make (fn.string)
else
f.make (fn.string)
end
if f.exists and then f.is_readable then
Result := f
end
end
end
end
end
resource_filename (uri: READABLE_STRING_8): READABLE_STRING_8
do
Result := real_filename (document_root + real_filename (uri))
end
dirname (uri: READABLE_STRING_8): READABLE_STRING_8
local
p: INTEGER
do
p := uri.last_index_of ('/', uri.count)
if p > 0 then
Result := uri.substring (1, p - 1)
else
create {STRING_8} Result.make_empty
end
end
filename (uri: READABLE_STRING_8): READABLE_STRING_8
local
p: INTEGER
do
p := uri.last_index_of ('/', uri.count)
if p > 0 then
Result := uri.substring (p + 1, uri.count)
else
Result := uri.twin
end
end
extension (uri: READABLE_STRING_8): READABLE_STRING_8
local
p: INTEGER
do
p := uri.last_index_of ('.', uri.count)
if p > 0 then
Result := uri.substring (p + 1, uri.count)
else
create {STRING_8} Result.make_empty
end
end
real_filename (fn: STRING): STRING
-- Real filename from url-path `fn'
--| Find a better design for this piece of code
--| Eventually in a spec/$ISE_PLATFORM/ specific cluster
do
if fn.is_empty then
Result := fn
else
if {PLATFORM}.is_windows then
create Result.make_from_string (fn)
Result.replace_substring_all ("/", "\")
if Result [Result.count] = '\' then
Result.remove_tail (1)
end
else
Result := fn
if Result [Result.count] = '/' then
Result.remove_tail (1)
end
end
end
end
feature {NONE} -- Implementation
node_exists (p: READABLE_STRING_8): BOOLEAN
local
f: RAW_FILE
do
create f.make (p)
Result := f.exists
end
extension_mime_mapping: HTTP_FILE_EXTENSION_MIME_MAPPING
local
f: RAW_FILE
once
create f.make ("mime.types")
if f.exists and then f.is_readable then
create Result.make_from_file (f.name)
else
create Result.make_default
end
end
note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -17,7 +17,7 @@ inherit
feature -- Status report feature -- Status report
is_valid_context (req: WGI_REQUEST): BOOLEAN is_valid_context (req: WSF_REQUEST): BOOLEAN
-- Is `req' valid context for current handler? -- Is `req' valid context for current handler?
do do
Result := True Result := True
@@ -25,7 +25,7 @@ feature -- Status report
feature -- Execution feature -- Execution
execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler -- Execute request handler
require require
is_valid_context: is_valid_context (req) is_valid_context: is_valid_context (req)
@@ -34,7 +34,7 @@ feature -- Execution
feature -- Execution: report feature -- Execution: report
url (req: WGI_REQUEST; a_base: detachable READABLE_STRING_8; args: detachable STRING; abs: BOOLEAN): STRING url (req: WSF_REQUEST; a_base: detachable READABLE_STRING_8; args: detachable STRING; abs: BOOLEAN): STRING
-- Associated url based on `a_base' and `args' -- Associated url based on `a_base' and `args'
-- if `abs' then return absolute url -- if `abs' then return absolute url
local local

View File

@@ -16,7 +16,7 @@ inherit
feature -- Access feature -- Access
request: WGI_REQUEST request: WSF_REQUEST
-- Associated request -- Associated request
path: READABLE_STRING_8 path: READABLE_STRING_8
@@ -31,7 +31,7 @@ feature {NONE} -- Constants
feature -- Query feature -- Query
request_format (a_format_variable_name: detachable READABLE_STRING_GENERAL; content_type_supported: detachable ARRAY [READABLE_STRING_8]): detachable READABLE_STRING_8 request_format (a_format_variable_name: detachable READABLE_STRING_8; content_type_supported: detachable ARRAY [READABLE_STRING_8]): detachable READABLE_STRING_8
-- Format id for the request based on {HTTP_FORMAT_CONSTANTS} -- Format id for the request based on {HTTP_FORMAT_CONSTANTS}
do do
if a_format_variable_name /= Void and then attached string_parameter (a_format_variable_name) as ctx_format then if a_format_variable_name /= Void and then attached string_parameter (a_format_variable_name) as ctx_format then
@@ -41,7 +41,7 @@ feature -- Query
end end
end end
request_format_id (a_format_variable_name: detachable READABLE_STRING_GENERAL; content_type_supported: detachable ARRAY [READABLE_STRING_8]): INTEGER request_format_id (a_format_variable_name: detachable READABLE_STRING_8; content_type_supported: detachable ARRAY [READABLE_STRING_8]): INTEGER
-- Format id for the request based on {HTTP_FORMAT_CONSTANTS} -- Format id for the request based on {HTTP_FORMAT_CONSTANTS}
do do
if attached request_format (a_format_variable_name, content_type_supported) as l_format then if attached request_format (a_format_variable_name, content_type_supported) as l_format then
@@ -71,12 +71,11 @@ feature -- Query
request_content_type (content_type_supported: detachable ARRAY [READABLE_STRING_8]): detachable READABLE_STRING_8 request_content_type (content_type_supported: detachable ARRAY [READABLE_STRING_8]): detachable READABLE_STRING_8
local local
s: detachable READABLE_STRING_32 s: detachable READABLE_STRING_8
i,n: INTEGER i,n: INTEGER
do do
s := request.content_type if attached request.content_type as ct then
if s /= Void then Result := ct
Result := s
else else
if attached accepted_content_types (request) as l_accept_lst then if attached accepted_content_types (request) as l_accept_lst then
from from
@@ -108,18 +107,18 @@ feature -- Query
feature -- Query feature -- Query
path_parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE path_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE
-- Parameter value for path variable `a_name' -- Parameter value for path variable `a_name'
deferred deferred
end end
query_parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE query_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE
-- Parameter value for query variable `a_name' -- Parameter value for query variable `a_name'
--| i.e after the ? character --| i.e after the ? character
deferred deferred
end end
parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE
-- Any parameter value for variable `a_name' -- Any parameter value for variable `a_name'
-- URI template parameter and query parameters -- URI template parameter and query parameters
do do
@@ -131,24 +130,24 @@ feature -- Query
feature -- String query feature -- String query
string_from (a_value: detachable WGI_VALUE): detachable READABLE_STRING_32 string_from (a_value: detachable WSF_VALUE): detachable READABLE_STRING_32
do do
if attached {WGI_STRING_VALUE} a_value as val then if attached {WSF_STRING_VALUE} a_value as val then
Result := val.string Result := val.string
end end
end end
string_path_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 string_path_parameter (a_name: READABLE_STRING_8): detachable READABLE_STRING_32
do do
Result := string_from (path_parameter (a_name)) Result := string_from (path_parameter (a_name))
end end
string_query_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 string_query_parameter (a_name: READABLE_STRING_8): detachable READABLE_STRING_32
do do
Result := string_from (query_parameter (a_name)) Result := string_from (query_parameter (a_name))
end end
string_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 string_parameter (a_name: READABLE_STRING_8): detachable READABLE_STRING_32
do do
Result := string_from (parameter (a_name)) Result := string_from (parameter (a_name))
end end

View File

@@ -34,12 +34,12 @@ feature -- Mapping
deferred deferred
end end
map_agent (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]]) map_agent (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]])
do do
map_agent_with_request_methods (a_resource, a_action, Void) map_agent_with_request_methods (a_resource, a_action, Void)
end end
map_agent_with_request_methods (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]]; 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 ARRAY [READABLE_STRING_8])
local local
rah: REQUEST_AGENT_HANDLER [C] rah: REQUEST_AGENT_HANDLER [C]
@@ -65,14 +65,14 @@ feature -- Base url
feature -- Execution feature -- Execution
dispatch (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER): BOOLEAN dispatch (req: WSF_REQUEST; res: WSF_RESPONSE): BOOLEAN
-- Dispatch `req, res' to the associated handler -- Dispatch `req, res' to the associated handler
-- And return True is handled, otherwise False -- And return True is handled, otherwise False
do do
Result := dispatch_and_return_handler (req, res) /= Void Result := dispatch_and_return_handler (req, res) /= Void
end end
dispatch_and_return_handler (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER): detachable H dispatch_and_return_handler (req: WSF_REQUEST; res: WSF_RESPONSE): detachable H
-- Dispatch `req, res' to the associated handler -- Dispatch `req, res' to the associated handler
-- And return this handler -- And return this handler
-- If Result is Void, this means no handler was found. -- If Result is Void, this means no handler was found.
@@ -108,13 +108,13 @@ feature -- Traversing
feature {NONE} -- Access: Implementation feature {NONE} -- Access: Implementation
source_uri (req: WGI_REQUEST): READABLE_STRING_32 source_uri (req: WSF_REQUEST): READABLE_STRING_32
-- URI to use to find handler. -- URI to use to find handler.
do do
Result := req.path_info Result := req.path_info
end end
handler (req: WGI_REQUEST): detachable TUPLE [handler: H; context: like default_handler_context] handler (req: WSF_REQUEST): detachable TUPLE [handler: H; context: like default_handler_context]
-- Handler whose map matched with `req' -- Handler whose map matched with `req'
require require
req_valid: source_uri (req) /= Void req_valid: source_uri (req) /= Void
@@ -179,7 +179,7 @@ feature {NONE} -- Implementation
deferred deferred
end end
default_handler_context (req: WGI_REQUEST): C default_handler_context (req: WSF_REQUEST): C
-- Default handler context associated with `default_handler' -- Default handler context associated with `default_handler'
require require
has_default_handler: default_handler /= Void has_default_handler: default_handler /= Void

View File

@@ -13,7 +13,7 @@ inherit
feature -- Execution feature -- Execution
execute (ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler -- Execute request handler
local local
hdl: detachable H hdl: detachable H
@@ -49,12 +49,12 @@ feature -- Mapping
router.map_with_request_methods (a_resource, h, rqst_methods) router.map_with_request_methods (a_resource, h, rqst_methods)
end end
map_agent (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]]) map_agent (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]])
do do
router.map_agent (a_resource, a_action) router.map_agent (a_resource, a_action)
end end
map_agent_with_request_methods (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]]; 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 ARRAY [READABLE_STRING_8])
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)

View File

@@ -35,7 +35,7 @@ feature -- Setup
feature -- Execution feature -- Execution
execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute (req: WSF_REQUEST; res: WSF_RESPONSE)
local local
l_handled: BOOLEAN l_handled: BOOLEAN
rescued: BOOLEAN rescued: BOOLEAN
@@ -50,11 +50,11 @@ feature -- Execution
end end
end end
execute_default (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_default (req: WSF_REQUEST; res: WSF_RESPONSE)
deferred deferred
end end
execute_rescue (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) execute_rescue (req: WSF_REQUEST; res: WSF_RESPONSE)
do do
if not res.header_committed then if not res.header_committed then
res.write_header ({HTTP_STATUS_CODE}.internal_server_error, Void) res.write_header ({HTTP_STATUS_CODE}.internal_server_error, Void)

View File

@@ -17,7 +17,7 @@ create
feature -- Mapping feature -- Mapping
map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REQUEST_URI_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]]; map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REQUEST_URI_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]];
rqst_methods: detachable ARRAY [READABLE_STRING_8]) rqst_methods: detachable ARRAY [READABLE_STRING_8])
local local
h: REQUEST_AGENT_HANDLER [REQUEST_URI_HANDLER_CONTEXT] h: REQUEST_AGENT_HANDLER [REQUEST_URI_HANDLER_CONTEXT]

View File

@@ -15,7 +15,7 @@ create
feature {NONE} -- Initialization feature {NONE} -- Initialization
make (req: WGI_REQUEST; p: like path) make (req: WSF_REQUEST; p: like path)
do do
request := req request := req
path := p path := p
@@ -23,11 +23,11 @@ feature {NONE} -- Initialization
feature -- Query feature -- Query
path_parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE path_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE
do do
end end
query_parameter (a_name: READABLE_STRING_GENERAL): detachable WGI_VALUE query_parameter (a_name: READABLE_STRING_8): detachable WSF_VALUE
do do
Result := request.query_parameter (a_name) Result := request.query_parameter (a_name)
end end

View File

@@ -38,7 +38,7 @@ feature -- Registration
feature {NONE} -- Access: Implementation feature {NONE} -- Access: Implementation
handler (req: WGI_REQUEST): detachable TUPLE [handler: H; context: like default_handler_context] handler (req: WSF_REQUEST): detachable TUPLE [handler: H; context: like default_handler_context]
local local
h: detachable H h: detachable H
ctx: detachable like default_handler_context ctx: detachable like default_handler_context
@@ -62,7 +62,7 @@ feature {NONE} -- Access: Implementation
end end
end end
smart_handler (req: WGI_REQUEST): detachable TUPLE [path: READABLE_STRING_8; handler: H] smart_handler (req: WSF_REQUEST): detachable TUPLE [path: READABLE_STRING_8; handler: H]
require require
req_valid: req /= Void and then source_uri (req) /= Void req_valid: req /= Void and then source_uri (req) /= Void
do do
@@ -124,7 +124,7 @@ feature {NONE} -- Access: Implementation
feature {NONE} -- Context factory feature {NONE} -- Context factory
handler_context (p: detachable STRING; req: WGI_REQUEST): C handler_context (p: detachable STRING; req: WSF_REQUEST): C
local local
ctx: C ctx: C
do do
@@ -184,7 +184,7 @@ feature {NONE} -- Default: implementation
default_handler := h default_handler := h
end end
default_handler_context (req: WGI_REQUEST): C default_handler_context (req: WSF_REQUEST): C
do do
Result := handler_context (Void, req) Result := handler_context (Void, req)
end end

View File

@@ -18,7 +18,7 @@ create
feature -- Mapping feature -- Mapping
map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]]; map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]];
rqst_methods: detachable ARRAY [READABLE_STRING_8]) rqst_methods: detachable ARRAY [READABLE_STRING_8])
local local
h: REQUEST_AGENT_HANDLER [REQUEST_URI_TEMPLATE_HANDLER_CONTEXT] h: REQUEST_AGENT_HANDLER [REQUEST_URI_TEMPLATE_HANDLER_CONTEXT]

Some files were not shown because too many files have changed in this diff Show More