Merge remote-tracking branch 'jocelynEWF/master'
This commit is contained in:
9
CHANGELOGS.txt
Normal file
9
CHANGELOGS.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
History for Eiffel-Web-Framework
|
||||||
|
|
||||||
|
[2011-09-07] Jocelyn
|
||||||
|
* library "router": now routing depends on uri (or uri template) and request methods
|
||||||
|
* Nino connector: Fixed issue where HTTP_ prefix were missing for header meta variable.
|
||||||
|
|
||||||
|
[2011-09-07] Jocelyn
|
||||||
|
* changelog: starting to write down changelogs file
|
||||||
|
|
||||||
2
doc/wiki
2
doc/wiki
Submodule doc/wiki updated: a2a1f89299...820bd7bd6f
@@ -8,16 +8,17 @@
|
|||||||
<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"/>
|
||||||
</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="..\..\library\server\ewsgi\default\ewsgi_nino-safe.ecf" readonly="false"/>
|
|
||||||
<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="encoder" location="..\..\library\text\encoder\encoder-safe.ecf" readonly="false"/>
|
||||||
<library name="ewsgi" location="..\..\library\server\ewsgi\ewsgi-safe.ecf" readonly="false"/>
|
<library name="ewsgi" location="..\..\library\server\ewsgi\ewsgi-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"/>
|
||||||
<library name="encoder" location="..\..\library\text\encoder\encoder-safe.ecf" readonly="false"/>
|
|
||||||
<library name="http" location="..\..\library\protocol\http\http-safe.ecf" readonly="false"/>
|
|
||||||
<cluster name="src" location="src\" recursive="true"/>
|
<cluster name="src" location="src\" recursive="true"/>
|
||||||
</target>
|
</target>
|
||||||
</system>
|
</system>
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ inherit
|
|||||||
|
|
||||||
feature -- Helper
|
feature -- Helper
|
||||||
|
|
||||||
execute_content_type_not_allowed (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER; a_content_types: detachable ARRAY [STRING]; a_uri_formats: detachable ARRAY [STRING])
|
execute_content_type_not_allowed (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_content_types: detachable ARRAY [STRING]; a_uri_formats: detachable ARRAY [STRING])
|
||||||
local
|
local
|
||||||
s, uri_s: detachable STRING
|
s, uri_s: detachable STRING
|
||||||
i, n: INTEGER
|
i, n: INTEGER
|
||||||
h: GW_HEADER
|
h: EWF_HEADER
|
||||||
do
|
do
|
||||||
create h.make
|
create h.make
|
||||||
h.put_status ({HTTP_STATUS_CODE}.unsupported_media_type)
|
h.put_status ({HTTP_STATUS_CODE}.unsupported_media_type)
|
||||||
@@ -60,6 +60,8 @@ feature -- Helper
|
|||||||
i := i + 1
|
i := i + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
res.set_status_code ({HTTP_STATUS_CODE}.unsupported_media_type)
|
||||||
|
res.write_headers_string (h.string)
|
||||||
if s /= Void then
|
if s /= Void then
|
||||||
res.write_string ("Unsupported request content-type, Accept: " + s + "%N")
|
res.write_string ("Unsupported request content-type, Accept: " + s + "%N")
|
||||||
end
|
end
|
||||||
@@ -68,7 +70,7 @@ feature -- Helper
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
execute_method_not_allowed (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER; a_methods: ARRAY [STRING])
|
execute_method_not_allowed (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_methods: ARRAY [STRING])
|
||||||
local
|
local
|
||||||
s: STRING
|
s: STRING
|
||||||
i, n: INTEGER
|
i, n: INTEGER
|
||||||
@@ -114,7 +116,7 @@ feature -- Context helper
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
content_type_to_request_format (a_content_type: detachable STRING): detachable STRING
|
content_type_to_request_format (a_content_type: detachable READABLE_STRING_8): detachable STRING
|
||||||
-- `a_content_type' converted into a request format name
|
-- `a_content_type' converted into a request format name
|
||||||
do
|
do
|
||||||
if a_content_type /= Void then
|
if a_content_type /= Void then
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ inherit
|
|||||||
|
|
||||||
ROUTED_APPLICATION_HELPER
|
ROUTED_APPLICATION_HELPER
|
||||||
|
|
||||||
DEFAULT_EWSGI_APPLICATION
|
DEFAULT_WGI_APPLICATION
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
@@ -30,6 +30,11 @@ feature {NONE} -- Initialization
|
|||||||
|
|
||||||
create_router
|
create_router
|
||||||
do
|
do
|
||||||
|
debug
|
||||||
|
create {REQUEST_URI_ROUTER} router.make (5)
|
||||||
|
create {REQUEST_URI_TEMPLATE_ROUTER} router.make (5)
|
||||||
|
end
|
||||||
|
|
||||||
-- create {REQUEST_URI_ROUTER} router.make (5)
|
-- create {REQUEST_URI_ROUTER} router.make (5)
|
||||||
create {REQUEST_URI_TEMPLATE_ROUTER} router.make (5)
|
create {REQUEST_URI_TEMPLATE_ROUTER} router.make (5)
|
||||||
end
|
end
|
||||||
@@ -48,13 +53,19 @@ feature {NONE} -- Initialization
|
|||||||
create ra.make (agent handle_anonymous_hello)
|
create ra.make (agent handle_anonymous_hello)
|
||||||
router.map ("/hello", ra)
|
router.map ("/hello", ra)
|
||||||
router.map ("/hello.{format}", ra)
|
router.map ("/hello.{format}", ra)
|
||||||
|
|
||||||
|
router.map_agent_with_request_methods ("/method/any", agent handle_method_any, Void)
|
||||||
|
router.map_agent_with_request_methods ("/method/guess", agent handle_method_get_or_post, <<"GET", "POST">>)
|
||||||
|
router.map_agent_with_request_methods ("/method/custom", agent handle_method_get, <<"GET">>)
|
||||||
|
router.map_agent_with_request_methods ("/method/custom", agent handle_method_post, <<"POST">>)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Execution
|
feature -- Execution
|
||||||
|
|
||||||
execute_default (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
|
execute_default (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
local
|
local
|
||||||
h: GW_HEADER
|
h: EWF_HEADER
|
||||||
l_url: STRING
|
l_url: STRING
|
||||||
e: EXECUTION_ENVIRONMENT
|
e: EXECUTION_ENVIRONMENT
|
||||||
n: INTEGER
|
n: INTEGER
|
||||||
@@ -65,7 +76,7 @@ feature -- Execution
|
|||||||
n := 3
|
n := 3
|
||||||
h.put_refresh (l_url, 5, 200)
|
h.put_refresh (l_url, 5, 200)
|
||||||
res.set_status_code (200)
|
res.set_status_code (200)
|
||||||
res.write_string (h.string)
|
res.write_headers_string (h.string)
|
||||||
from
|
from
|
||||||
create e
|
create e
|
||||||
until
|
until
|
||||||
@@ -97,7 +108,7 @@ feature -- Execution
|
|||||||
res.flush
|
res.flush
|
||||||
end
|
end
|
||||||
|
|
||||||
execute_home (ctx: REQUEST_HANDLER_CONTEXT; req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
|
execute_home (ctx: REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
do
|
do
|
||||||
res.write_header (200, <<["Content-Type", "text/html"]>>)
|
res.write_header (200, <<["Content-Type", "text/html"]>>)
|
||||||
res.write_string ("<html><body>Hello World ?!%N")
|
res.write_string ("<html><body>Hello World ?!%N")
|
||||||
@@ -111,17 +122,17 @@ feature -- Execution
|
|||||||
res.write_string ("<li><a href=%""+ req.script_url ("/hello/Joce") + "%">/hello/Joce</a></li>%N")
|
res.write_string ("<li><a href=%""+ req.script_url ("/hello/Joce") + "%">/hello/Joce</a></li>%N")
|
||||||
res.write_string ("</ul>%N")
|
res.write_string ("</ul>%N")
|
||||||
|
|
||||||
if attached req.environment_variable ("REQUEST_COUNT") as rqc then
|
if attached req.parameter ("REQUEST_COUNT") as rqc then
|
||||||
res.write_string ("request #"+ rqc + "%N")
|
res.write_string ("request #"+ rqc + "%N")
|
||||||
end
|
end
|
||||||
res.write_string ("</body></html>%N")
|
res.write_string ("</body></html>%N")
|
||||||
end
|
end
|
||||||
|
|
||||||
execute_hello (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER; a_name: detachable STRING_32; ctx: REQUEST_HANDLER_CONTEXT)
|
execute_hello (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_name: detachable READABLE_STRING_32; ctx: REQUEST_HANDLER_CONTEXT)
|
||||||
local
|
local
|
||||||
l_response_content_type: detachable STRING
|
l_response_content_type: detachable STRING
|
||||||
msg: STRING
|
msg: STRING
|
||||||
h: GW_HEADER
|
h: EWF_HEADER
|
||||||
content_type_supported: ARRAY [STRING]
|
content_type_supported: ARRAY [STRING]
|
||||||
do
|
do
|
||||||
if a_name /= Void then
|
if a_name /= Void then
|
||||||
@@ -152,7 +163,7 @@ feature -- Execution
|
|||||||
h.put_content_type (l_response_content_type)
|
h.put_content_type (l_response_content_type)
|
||||||
h.put_content_length (msg.count)
|
h.put_content_length (msg.count)
|
||||||
res.set_status_code (200)
|
res.set_status_code (200)
|
||||||
res.write_string (h.string)
|
res.write_headers_string (h.string)
|
||||||
-- res.write_header (200, <<
|
-- res.write_header (200, <<
|
||||||
-- ["Content-Type", l_response_content_type],
|
-- ["Content-Type", l_response_content_type],
|
||||||
-- ["Content-Length", msg.count.out
|
-- ["Content-Length", msg.count.out
|
||||||
@@ -161,16 +172,39 @@ feature -- Execution
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
handle_hello (ctx: REQUEST_HANDLER_CONTEXT; req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
|
handle_hello (ctx: REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
do
|
do
|
||||||
execute_hello (req, res, Void, ctx)
|
execute_hello (req, res, Void, ctx)
|
||||||
end
|
end
|
||||||
|
|
||||||
handle_anonymous_hello (ctx: REQUEST_HANDLER_CONTEXT; req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
|
handle_anonymous_hello (ctx: REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
do
|
do
|
||||||
execute_hello (req, res, ctx.parameter ("name"), ctx)
|
execute_hello (req, res, ctx.parameter ("name"), ctx)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
handle_method_any (ctx: REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
|
do
|
||||||
|
execute_hello (req, res, req.request_method, ctx)
|
||||||
|
end
|
||||||
|
|
||||||
|
handle_method_get (ctx: REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
|
do
|
||||||
|
execute_hello (req, res, "GET", ctx)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
handle_method_post (ctx: REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
|
do
|
||||||
|
execute_hello (req, res, "POST", ctx)
|
||||||
|
end
|
||||||
|
|
||||||
|
handle_method_get_or_post (ctx: REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
|
do
|
||||||
|
execute_hello (req, res, "GET or POST", ctx)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
note
|
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)"
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ note
|
|||||||
class
|
class
|
||||||
ERROR_HANDLER
|
ERROR_HANDLER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
ANY
|
||||||
|
|
||||||
|
DEBUG_OUTPUT
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
@@ -35,6 +40,18 @@ feature -- Status
|
|||||||
errors: LIST [ERROR]
|
errors: LIST [ERROR]
|
||||||
-- Errors container
|
-- Errors container
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
debug_output: STRING
|
||||||
|
-- String that should be displayed in debugger to represent `Current'.
|
||||||
|
do
|
||||||
|
if has_error then
|
||||||
|
Result := count.out + " errors"
|
||||||
|
else
|
||||||
|
Result := "no error"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Basic operation
|
feature -- Basic operation
|
||||||
|
|
||||||
add_error (a_error: ERROR)
|
add_error (a_error: ERROR)
|
||||||
@@ -52,6 +69,12 @@ feature -- Basic operation
|
|||||||
add_error (e)
|
add_error (e)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
append (a_err_handler: ERROR_HANDLER)
|
||||||
|
-- Append errors from `a_err_handler'
|
||||||
|
do
|
||||||
|
errors.append (a_err_handler.errors)
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
as_single_error: detachable ERROR
|
as_single_error: detachable ERROR
|
||||||
@@ -61,6 +84,20 @@ feature -- Access
|
|||||||
elseif count > 0 then
|
elseif count > 0 then
|
||||||
Result := errors.first
|
Result := errors.first
|
||||||
end
|
end
|
||||||
|
ensure
|
||||||
|
has_error_implies_result_attached: has_error implies Result /= Void
|
||||||
|
end
|
||||||
|
|
||||||
|
as_string_representation: STRING
|
||||||
|
require
|
||||||
|
has_error
|
||||||
|
do
|
||||||
|
if attached as_single_error as e then
|
||||||
|
Result := e.string_representation
|
||||||
|
else
|
||||||
|
check has_error: False end
|
||||||
|
Result := "Error occured"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Element changes
|
feature -- Element changes
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ feature -- Match
|
|||||||
exp: URI_TEMPLATE_EXPRESSION
|
exp: URI_TEMPLATE_EXPRESSION
|
||||||
vn, s,t: STRING
|
vn, s,t: STRING
|
||||||
vv: STRING
|
vv: STRING
|
||||||
l_vars, l_path_vars, l_query_vars: HASH_TABLE [STRING, STRING]
|
l_vars, l_path_vars, l_query_vars: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]
|
||||||
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
|
||||||
@@ -358,7 +358,7 @@ feature {NONE} -- Implementation
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
import_path_style_parameters_into (a_content: STRING; res: HASH_TABLE [STRING, STRING])
|
import_path_style_parameters_into (a_content: STRING; res: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL])
|
||||||
require
|
require
|
||||||
a_content_attached: a_content /= Void
|
a_content_attached: a_content /= Void
|
||||||
res_attached: res /= Void
|
res_attached: res /= Void
|
||||||
@@ -366,7 +366,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 [STRING, STRING])
|
import_form_style_parameters_into (a_content: STRING; res: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL])
|
||||||
require
|
require
|
||||||
a_content_attached: a_content /= Void
|
a_content_attached: a_content /= Void
|
||||||
res_attached: res /= Void
|
res_attached: res /= Void
|
||||||
@@ -374,7 +374,7 @@ 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 [STRING, STRING])
|
import_custom_style_parameters_into (a_content: STRING; a_separator: CHARACTER; res: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL])
|
||||||
require
|
require
|
||||||
a_content_attached: a_content /= Void
|
a_content_attached: a_content /= Void
|
||||||
res_attached: res /= Void
|
res_attached: res /= Void
|
||||||
|
|||||||
@@ -27,27 +27,27 @@ feature {NONE} -- Initialization
|
|||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
path_variables: HASH_TABLE [STRING, STRING]
|
path_variables: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]
|
||||||
-- Variables being part of the path segments
|
-- Variables being part of the path segments
|
||||||
|
|
||||||
query_variables: HASH_TABLE [STRING, STRING]
|
query_variables: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]
|
||||||
-- 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: STRING): detachable STRING
|
path_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
-- 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: STRING): detachable STRING
|
query_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
-- 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: STRING): detachable STRING
|
variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
-- Value related to variable name `n'
|
-- Value related to variable name `n'
|
||||||
do
|
do
|
||||||
Result := query_variable (n)
|
Result := query_variable (n)
|
||||||
@@ -58,7 +58,7 @@ feature -- Query
|
|||||||
|
|
||||||
feature -- Query: url-decoded
|
feature -- Query: url-decoded
|
||||||
|
|
||||||
url_decoded_query_variable (n: STRING): detachable STRING_32
|
url_decoded_query_variable (n: READABLE_STRING_GENERAL): detachable 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,15 +66,15 @@ feature -- Query: url-decoded
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
url_decoded_path_variable (n: STRING): detachable STRING_32
|
url_decoded_path_variable (n: READABLE_STRING_GENERAL): detachable 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
|
||||||
Result := url_decoded_string (v)
|
Result := url_decoded_string (v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
url_decoded_variable (n: STRING): detachable STRING_32
|
url_decoded_variable (n: READABLE_STRING_GENERAL): detachable 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
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {GW_CGI_CONNECTOR}."
|
description: "Summary description for {EWF_CGI_CONNECTOR}."
|
||||||
author: ""
|
author: ""
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
class
|
class
|
||||||
GW_CGI_CONNECTOR
|
EWF_CGI_CONNECTOR
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
EWSGI_CONNECTOR
|
WGI_CONNECTOR
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
@@ -17,10 +17,12 @@ feature -- Execution
|
|||||||
|
|
||||||
launch
|
launch
|
||||||
local
|
local
|
||||||
env: EWSGI_ENVIRONMENT_VARIABLES
|
req: WGI_REQUEST_FROM_TABLE
|
||||||
|
res: WGI_RESPONSE_STREAM_BUFFER
|
||||||
do
|
do
|
||||||
create env.make_with_variables ((create {EXECUTION_ENVIRONMENT}).starting_environment_variables)
|
create req.make ((create {EXECUTION_ENVIRONMENT}).starting_environment_variables, create {EWF_CGI_INPUT_STREAM}.make)
|
||||||
application.process (env, create {GW_CGI_INPUT_STREAM}.make, create {GW_CGI_OUTPUT_STREAM}.make)
|
create res.make (create {EWF_CGI_OUTPUT_STREAM}.make)
|
||||||
|
application.process (req, res)
|
||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for GW_CGI_INPUT_STREAM."
|
description: "Summary description for EWF_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
|
||||||
GW_CGI_INPUT_STREAM
|
EWF_CGI_INPUT_STREAM
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
EWSGI_INPUT_STREAM
|
WGI_INPUT_STREAM
|
||||||
|
|
||||||
CONSOLE
|
CONSOLE
|
||||||
rename
|
rename
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for GW_CGI_OUTPUT_STREAM."
|
description: "Summary description for EWF_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
|
||||||
GW_CGI_OUTPUT_STREAM
|
EWF_CGI_OUTPUT_STREAM
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
EWSGI_OUTPUT_STREAM
|
WGI_OUTPUT_STREAM
|
||||||
undefine
|
undefine
|
||||||
flush
|
flush
|
||||||
end
|
end
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {GW_LIBFCGI_CONNECTOR}."
|
description: "Summary description for {EWF_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
|
||||||
GW_LIBFCGI_CONNECTOR
|
EWF_LIBFCGI_CONNECTOR
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
EWSGI_CONNECTOR
|
WGI_CONNECTOR
|
||||||
redefine
|
redefine
|
||||||
initialize
|
initialize
|
||||||
end
|
end
|
||||||
@@ -22,8 +22,8 @@ feature {NONE} -- Initialization
|
|||||||
initialize
|
initialize
|
||||||
do
|
do
|
||||||
create fcgi.make
|
create fcgi.make
|
||||||
create {GW_LIBFCGI_INPUT_STREAM} input.make (fcgi)
|
create {EWF_LIBFCGI_INPUT_STREAM} input.make (fcgi)
|
||||||
create {GW_LIBFCGI_OUTPUT_STREAM} output.make (fcgi)
|
create {EWF_LIBFCGI_OUTPUT_STREAM} output.make (fcgi)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Server
|
feature -- Server
|
||||||
@@ -46,18 +46,20 @@ 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
|
||||||
gw_env: EWSGI_ENVIRONMENT_VARIABLES
|
req: WGI_REQUEST_FROM_TABLE
|
||||||
|
res: WGI_RESPONSE_STREAM_BUFFER
|
||||||
do
|
do
|
||||||
create gw_env.make_with_variables (vars)
|
create req.make (vars, a_input)
|
||||||
application.process (gw_env, a_input, a_output)
|
create res.make (a_output)
|
||||||
|
application.process (req, res)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Input/Output
|
feature -- Input/Output
|
||||||
|
|
||||||
input: EWSGI_INPUT_STREAM
|
input: WGI_INPUT_STREAM
|
||||||
-- Input from client (from httpd server via FCGI)
|
-- Input from client (from httpd server via FCGI)
|
||||||
|
|
||||||
output: EWSGI_OUTPUT_STREAM
|
output: WGI_OUTPUT_STREAM
|
||||||
-- Output to client (via httpd server/fcgi)
|
-- Output to client (via httpd server/fcgi)
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for GW_LIBFCGI_INPUT_STREAM."
|
description: "Summary description for EWF_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
|
||||||
GW_LIBFCGI_INPUT_STREAM
|
EWF_LIBFCGI_INPUT_STREAM
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
EWSGI_INPUT_STREAM
|
WGI_INPUT_STREAM
|
||||||
|
|
||||||
STRING_HANDLER
|
STRING_HANDLER
|
||||||
|
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {GW_LIBFCGI_OUTPUT_STREAM}."
|
description: "Summary description for {EWF_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
|
||||||
GW_LIBFCGI_OUTPUT_STREAM
|
EWF_LIBFCGI_OUTPUT_STREAM
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
EWSGI_OUTPUT_STREAM
|
WGI_OUTPUT_STREAM
|
||||||
|
|
||||||
HTTP_STATUS_CODE_MESSAGES
|
HTTP_STATUS_CODE_MESSAGES
|
||||||
export
|
export
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {GW_NINO_CONNECTOR}."
|
description: "Summary description for {EWF_NINO_CONNECTOR}."
|
||||||
author: ""
|
author: ""
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
class
|
class
|
||||||
GW_NINO_CONNECTOR
|
EWF_NINO_CONNECTOR
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
EWSGI_CONNECTOR
|
WGI_CONNECTOR
|
||||||
redefine
|
redefine
|
||||||
initialize
|
initialize
|
||||||
end
|
end
|
||||||
@@ -62,7 +62,7 @@ feature -- Server
|
|||||||
local
|
local
|
||||||
l_http_handler : HTTP_HANDLER
|
l_http_handler : HTTP_HANDLER
|
||||||
do
|
do
|
||||||
create {GW_NINO_HANDLER} l_http_handler.make_with_callback (server, "NINO_HANDLER", Current)
|
create {EWF_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")
|
||||||
@@ -73,11 +73,13 @@ 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
|
||||||
gw_env: EWSGI_ENVIRONMENT_VARIABLES
|
req: WGI_REQUEST_FROM_TABLE
|
||||||
|
res: WGI_RESPONSE_STREAM_BUFFER
|
||||||
do
|
do
|
||||||
create gw_env.make_with_variables (env)
|
create req.make (env, create {EWF_NINO_INPUT_STREAM}.make (a_input))
|
||||||
gw_env.set_variable ("RAW_HEADER_DATA", a_headers_text)
|
create res.make (create {EWF_NINO_OUTPUT_STREAM}.make (a_output))
|
||||||
application.process (gw_env, create {GW_NINO_INPUT_STREAM}.make (a_input), create {GW_NINO_OUTPUT_STREAM}.make (a_output))
|
req.set_meta_variable ("RAW_HEADER_DATA", a_headers_text)
|
||||||
|
application.execute (req, res)
|
||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
@@ -5,7 +5,7 @@ note
|
|||||||
revision : "$Revision$"
|
revision : "$Revision$"
|
||||||
|
|
||||||
class
|
class
|
||||||
GW_NINO_HANDLER
|
EWF_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: GW_NINO_CONNECTOR
|
callback: EWF_NINO_CONNECTOR
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ feature -- Request processing
|
|||||||
until
|
until
|
||||||
a_headers_map.after
|
a_headers_map.after
|
||||||
loop
|
loop
|
||||||
vn := a_headers_map.key_for_iteration.as_upper
|
vn := "HTTP_" + a_headers_map.key_for_iteration.as_upper
|
||||||
vn.replace_substring_all ("-", "_")
|
vn.replace_substring_all ("-", "_")
|
||||||
add_environment_variable (a_headers_map.item_for_iteration, vn, env)
|
add_environment_variable (a_headers_map.item_for_iteration, vn, env)
|
||||||
a_headers_map.forth
|
a_headers_map.forth
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {GW_NINO_INPUT_STREAM}."
|
description: "Summary description for {EWF_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
|
||||||
GW_NINO_INPUT_STREAM
|
EWF_NINO_INPUT_STREAM
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
EWSGI_INPUT_STREAM
|
WGI_INPUT_STREAM
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
@@ -22,7 +22,7 @@ feature {NONE} -- Initialization
|
|||||||
set_nino_input (a_nino_input)
|
set_nino_input (a_nino_input)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {GW_NINO_CONNECTOR, EWSGI_APPLICATION} -- Nino
|
feature {EWF_NINO_CONNECTOR, WGI_APPLICATION} -- Nino
|
||||||
|
|
||||||
set_nino_input (i: like nino_input)
|
set_nino_input (i: like nino_input)
|
||||||
do
|
do
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {GW_NINO_OUTPUT_STREAM}."
|
description: "Summary description for {EWF_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
|
||||||
GW_NINO_OUTPUT_STREAM
|
EWF_NINO_OUTPUT_STREAM
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
EWSGI_OUTPUT_STREAM
|
WGI_OUTPUT_STREAM
|
||||||
|
|
||||||
HTTP_STATUS_CODE_MESSAGES
|
HTTP_STATUS_CODE_MESSAGES
|
||||||
export
|
export
|
||||||
@@ -26,7 +26,7 @@ feature {NONE} -- Initialization
|
|||||||
set_nino_output (a_nino_output)
|
set_nino_output (a_nino_output)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {GW_NINO_CONNECTOR, EWSGI_APPLICATION} -- Nino
|
feature {EWF_NINO_CONNECTOR, WGI_APPLICATION} -- Nino
|
||||||
|
|
||||||
set_nino_output (o: like nino_output)
|
set_nino_output (o: like nino_output)
|
||||||
do
|
do
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {DEFAULT_EWSGI_APPLICATION}."
|
description: "Summary description for {DEFAULT_WGI_APPLICATION}."
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
DEFAULT_EWSGI_APPLICATION
|
DEFAULT_WGI_APPLICATION
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
EWSGI_APPLICATION
|
WGI_APPLICATION
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
make_and_launch
|
make_and_launch
|
||||||
local
|
local
|
||||||
cgi: GW_CGI_CONNECTOR
|
cgi: EWF_CGI_CONNECTOR
|
||||||
do
|
do
|
||||||
create cgi.make (Current)
|
create cgi.make (Current)
|
||||||
cgi.launch
|
cgi.launch
|
||||||
@@ -1,24 +1,30 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {DEFAULT_EWSGI_APPLICATION}."
|
description: "Summary description for {DEFAULT_WGI_APPLICATION}."
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
DEFAULT_EWSGI_APPLICATION
|
DEFAULT_WGI_APPLICATION
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
EWSGI_APPLICATION
|
WGI_APPLICATION
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
make_and_launch
|
make_and_launch
|
||||||
|
local
|
||||||
|
app: NINO_APPLICATION
|
||||||
do
|
do
|
||||||
print ("Example: start a Nino web server on port " + port_number.out + ", %Nand reply Hello World for any request such as http://localhost:8123/%N")
|
port_number := 8123
|
||||||
(create {NINO_APPLICATION}.make_custom (agent execute, "")).listen (port_number)
|
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 + "/%N")
|
||||||
|
create app.make_custom (agent execute, "")
|
||||||
|
app.listen (port_number)
|
||||||
end
|
end
|
||||||
|
|
||||||
port_number: INTEGER = 80
|
port_number: INTEGER
|
||||||
|
|
||||||
|
invariant
|
||||||
|
port_number_valid: port_number > 0
|
||||||
note
|
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)"
|
||||||
@@ -12,22 +12,22 @@ create
|
|||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
make (a_callback: like {EWSGI_AGENT_APPLICATION}.callback)
|
make (a_callback: like {WGI_AGENT_APPLICATION}.callback)
|
||||||
-- Initialize `Current'.
|
-- Initialize `Current'.
|
||||||
do
|
do
|
||||||
make_custom (a_callback, Void)
|
make_custom (a_callback, Void)
|
||||||
end
|
end
|
||||||
|
|
||||||
make_custom (a_callback: like {EWSGI_AGENT_APPLICATION}.callback; a_base_url: detachable STRING)
|
make_custom (a_callback: like {WGI_AGENT_APPLICATION}.callback; a_base_url: detachable STRING)
|
||||||
-- Initialize `Current'.
|
-- Initialize `Current'.
|
||||||
local
|
local
|
||||||
app: EWSGI_AGENT_APPLICATION
|
app: WGI_AGENT_APPLICATION
|
||||||
do
|
do
|
||||||
create app.make (a_callback)
|
create app.make (a_callback)
|
||||||
create connector.make_with_base (app, a_base_url)
|
create connector.make_with_base (app, a_base_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
connector: GW_NINO_CONNECTOR
|
connector: EWF_NINO_CONNECTOR
|
||||||
-- Web server connector
|
-- Web server connector
|
||||||
|
|
||||||
feature -- Status settings
|
feature -- Status settings
|
||||||
|
|||||||
@@ -15,5 +15,7 @@
|
|||||||
<library name="http" location="..\..\protocol\http\http-safe.ecf"/>
|
<library name="http" location="..\..\protocol\http\http-safe.ecf"/>
|
||||||
<library name="encoder" location="..\..\text\encoder\encoder-safe.ecf" readonly="false"/>
|
<library name="encoder" location="..\..\text\encoder\encoder-safe.ecf" readonly="false"/>
|
||||||
<cluster name="interface" location="src\" recursive="true"/>
|
<cluster name="interface" location="src\" recursive="true"/>
|
||||||
|
<cluster name="specification_request" location="specification\request" recursive="true"/>
|
||||||
|
<cluster name="specification_response" location="specification\response" recursive="true"/>
|
||||||
</target>
|
</target>
|
||||||
</system>
|
</system>
|
||||||
|
|||||||
@@ -15,5 +15,7 @@
|
|||||||
<library name="http" location="..\..\protocol\http\http.ecf"/>
|
<library name="http" location="..\..\protocol\http\http.ecf"/>
|
||||||
<library name="encoder" location="..\..\text\encoder\encoder.ecf" readonly="false"/>
|
<library name="encoder" location="..\..\text\encoder\encoder.ecf" readonly="false"/>
|
||||||
<cluster name="interface" location="src\" recursive="true" />
|
<cluster name="interface" location="src\" recursive="true" />
|
||||||
|
<cluster name="specification_request" location="specification\request" recursive="true"/>
|
||||||
|
<cluster name="specification_response" location="specification\response" recursive="true"/>
|
||||||
</target>
|
</target>
|
||||||
</system>
|
</system>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ feature {NONE} -- Initialization
|
|||||||
(create {NINO_APPLICATION}.make_custom (agent execute, "")).listen (port_number)
|
(create {NINO_APPLICATION}.make_custom (agent execute, "")).listen (port_number)
|
||||||
end
|
end
|
||||||
|
|
||||||
execute (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
|
execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
do
|
do
|
||||||
res.write_header (200, <<["Content-Type", "text/plain"]>>)
|
res.write_header (200, <<["Content-Type", "text/plain"]>>)
|
||||||
res.write_string ("Hello World!%N")
|
res.write_string ("Hello World!%N")
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
<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"/>
|
||||||
</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"/>
|
||||||
@@ -14,15 +15,14 @@
|
|||||||
</target>
|
</target>
|
||||||
<target name="hello_nino_world" extends="hello_world">
|
<target name="hello_nino_world" extends="hello_world">
|
||||||
<root class="HELLO_WORLD" feature="make_and_launch"/>
|
<root class="HELLO_WORLD" feature="make_and_launch"/>
|
||||||
<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="default_nino" location="..\..\default\ewsgi_nino-safe.ecf" readonly="false"/>
|
||||||
<cluster name="src" location="src\" recursive="true"/>
|
<cluster name="src" location="src\" recursive="true"/>
|
||||||
</target>
|
</target>
|
||||||
<target name="hello_cgi_world" extends="hello_world">
|
<target name="hello_cgi_world" extends="hello_world">
|
||||||
<root class="HELLO_WORLD" feature="make_and_launch"/>
|
<root class="HELLO_WORLD" feature="make_and_launch"/>
|
||||||
<library name="default_cgi" location="..\..\default\ewsgi_cgi-safe.ecf" readonly="false"/>
|
|
||||||
<library name="connector_cgi" location="..\..\connectors\cgi\cgi-safe.ecf" readonly="false"/>
|
<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"/>
|
<cluster name="src" location="src\" recursive="true"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
</system>
|
</system>
|
||||||
|
|||||||
@@ -8,18 +8,30 @@ class
|
|||||||
HELLO_WORLD
|
HELLO_WORLD
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
EWSGI_RESPONSE_APPLICATION
|
WGI_RESPONSE_APPLICATION
|
||||||
|
|
||||||
DEFAULT_EWSGI_APPLICATION
|
DEFAULT_WGI_APPLICATION
|
||||||
|
|
||||||
create
|
create
|
||||||
make_and_launch
|
make_and_launch
|
||||||
|
|
||||||
feature -- Response
|
feature -- Response
|
||||||
|
|
||||||
response (request: EWSGI_REQUEST): EWSGI_RESPONSE
|
response (request: WGI_REQUEST): WGI_RESPONSE
|
||||||
do
|
do
|
||||||
create {HELLO_WORLD_RESPONSE} Result.make
|
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_status (200)
|
||||||
Result.set_header ("Content-Type", "text/html; charset=utf-8")
|
Result.set_header ("Content-Type", "text/html; charset=utf-8")
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ note
|
|||||||
class HELLO_WORLD_RESPONSE
|
class HELLO_WORLD_RESPONSE
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
EWSGI_RESPONSE
|
WGI_RESPONSE
|
||||||
redefine
|
redefine
|
||||||
make,
|
make,
|
||||||
read_block
|
read_block
|
||||||
@@ -31,23 +31,26 @@ feature {NONE} -- Entity body
|
|||||||
local
|
local
|
||||||
i: INTEGER
|
i: INTEGER
|
||||||
do
|
do
|
||||||
if current_hello >= 100000 then
|
if current_hello >= 10000 then
|
||||||
end_of_blocks := True
|
end_of_blocks := True
|
||||||
else
|
else
|
||||||
if current_hello = 0 then
|
if current_hello = 0 then
|
||||||
current_block := "<html><body>%N"
|
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
|
end
|
||||||
from
|
from
|
||||||
i := 0
|
i := 0
|
||||||
until
|
until
|
||||||
i = 10000
|
i = 1000
|
||||||
loop
|
loop
|
||||||
current_block.append ("Hello World ("+ current_hello.out +","+ i.out +")<br/>%N")
|
current_block.append ("Hello World ("+ current_hello.out +","+ i.out +")<br/>%N")
|
||||||
i := i + 1
|
i := i + 1
|
||||||
end
|
end
|
||||||
current_hello := current_hello + i
|
current_hello := current_hello + i
|
||||||
if current_hello = 100000 then
|
current_block.append ("<div id=%"status%">In progress - "+ (100 * current_hello // 10000).out +"%%</div>")
|
||||||
current_block.append ("Bye bye..<br/></body></html>")
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {EWSGI_CONNECTOR}."
|
description: "Summary description for {WGI_CONNECTOR}."
|
||||||
author: ""
|
author: ""
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
EWSGI_CONNECTOR
|
WGI_CONNECTOR
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ feature {NONE} -- Initialization
|
|||||||
|
|
||||||
feature {NONE} -- Access
|
feature {NONE} -- Access
|
||||||
|
|
||||||
application: EWSGI_APPLICATION
|
application: WGI_APPLICATION
|
||||||
-- Gateway Application
|
-- Gateway Application
|
||||||
|
|
||||||
feature -- Server
|
feature -- Server
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
note
|
|
||||||
description: "[
|
|
||||||
Server request context of the httpd request
|
|
||||||
|
|
||||||
You can create your own descendant of this class to
|
|
||||||
add/remove specific value or processing
|
|
||||||
]"
|
|
||||||
legal: "See notice at end of class."
|
|
||||||
status: "See notice at end of class."
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
deferred class
|
|
||||||
EWSGI_REQUEST
|
|
||||||
|
|
||||||
feature -- Access: Input
|
|
||||||
|
|
||||||
input: EWSGI_INPUT_STREAM
|
|
||||||
-- Server input channel
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access: extra values
|
|
||||||
|
|
||||||
request_time: detachable DATE_TIME
|
|
||||||
-- Request time (UTC)
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access: environment variables
|
|
||||||
|
|
||||||
environment: EWSGI_ENVIRONMENT
|
|
||||||
-- Environment variables
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
environment_variable (a_name: STRING): detachable STRING
|
|
||||||
-- Environment variable related to `a_name'
|
|
||||||
require
|
|
||||||
a_name_valid: a_name /= Void and then not a_name.is_empty
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access: execution variables
|
|
||||||
|
|
||||||
execution_variables: EWSGI_VARIABLES [STRING_32]
|
|
||||||
-- Execution variables set by the application
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
execution_variable (a_name: STRING): detachable STRING_32
|
|
||||||
-- Execution variable related to `a_name'
|
|
||||||
require
|
|
||||||
a_name_valid: a_name /= Void and then not a_name.is_empty
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- URL Parameters
|
|
||||||
|
|
||||||
parameters: EWSGI_VARIABLES [STRING_32]
|
|
||||||
-- Variables extracted from QUERY_STRING
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
parameter (a_name: STRING): detachable STRING_32
|
|
||||||
-- 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_fields: EWSGI_VARIABLES [STRING_32]
|
|
||||||
-- Variables sent by POST request
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
form_field (a_name: STRING): detachable STRING_32
|
|
||||||
-- 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 [EWSGI_UPLOADED_FILE_DATA, STRING]
|
|
||||||
-- 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_variables: HASH_TABLE [STRING, STRING]
|
|
||||||
-- Expanded cookies variable
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
cookies_variable (a_name: STRING): detachable STRING
|
|
||||||
-- Field for name `a_name'.
|
|
||||||
require
|
|
||||||
a_name_valid: a_name /= Void and then not a_name.is_empty
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
cookies: HASH_TABLE [EWSGI_COOKIE, STRING]
|
|
||||||
-- Cookies Information
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access: global variable
|
|
||||||
|
|
||||||
variables: HASH_TABLE [STRING_32, STRING_32]
|
|
||||||
-- 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
|
|
||||||
|
|
||||||
variable (a_name: STRING_8): detachable STRING_32
|
|
||||||
-- 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: STRING): 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
|
|
||||||
|
|
||||||
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
|
|
||||||
@@ -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
|
|
||||||
EWSGI_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 {EWSGI_REQUEST, EWSGI_APPLICATION, EWSGI_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
|
|
||||||
@@ -8,7 +8,7 @@ note
|
|||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
class
|
class
|
||||||
EWSGI_COOKIE
|
WGI_COOKIE
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
@@ -8,7 +8,7 @@ note
|
|||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
EWSGI_VARIABLES [G -> STRING_GENERAL]
|
WGI_VARIABLES [G -> STRING_GENERAL]
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
ITERABLE [G]
|
ITERABLE [G]
|
||||||
@@ -49,7 +49,7 @@ feature -- Access
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {EWSGI_REQUEST, EWSGI_APPLICATION, EWSGI_CONNECTOR} -- Element change
|
feature {WGI_REQUEST, WGI_APPLICATION, WGI_CONNECTOR} -- Element change
|
||||||
|
|
||||||
set_variable (a_name: STRING; a_value: G)
|
set_variable (a_name: STRING; a_value: G)
|
||||||
require
|
require
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {EWSGI_ENVIRONMENT_NAMES}."
|
description: "Summary description for {WGI_META_NAMES}."
|
||||||
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
|
||||||
EWSGI_ENVIRONMENT_NAMES
|
WGI_META_NAMES
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
note
|
note
|
||||||
description: "[
|
description: "[
|
||||||
|
Server request context of the httpd request
|
||||||
Interface for a request environment
|
|
||||||
It includes CGI interface and a few extra values that are usually valuable
|
It includes CGI interface and a few extra values that are usually valuable
|
||||||
|
|
||||||
See http://www.ietf.org/rfc/rfc3875
|
See http://www.ietf.org/rfc/rfc3875
|
||||||
@@ -70,18 +70,33 @@ note
|
|||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
deferred
|
deferred class
|
||||||
class
|
WGI_REQUEST
|
||||||
EWSGI_ENVIRONMENT
|
|
||||||
|
|
||||||
inherit
|
feature -- Access: Input
|
||||||
EWSGI_VARIABLES [STRING_8]
|
|
||||||
|
|
||||||
ITERABLE [STRING_8]
|
input: WGI_INPUT_STREAM
|
||||||
|
-- Server input channel
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access: extra values
|
||||||
|
|
||||||
table: HASH_TABLE [STRING, STRING]
|
request_time: detachable DATE_TIME
|
||||||
|
-- Request time (UTC)
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access: CGI meta variables
|
||||||
|
|
||||||
|
meta_variable (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
|
-- Environment variable related to `a_name'
|
||||||
|
require
|
||||||
|
a_name_valid: a_name /= Void and then not a_name.is_empty
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
meta_variables: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]
|
||||||
-- 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.
|
||||||
@@ -111,17 +126,9 @@ feature -- Access
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access: table
|
|
||||||
|
|
||||||
new_cursor: HASH_TABLE_ITERATION_CURSOR [STRING_8, STRING_8]
|
|
||||||
-- Fresh cursor associated with current structure
|
|
||||||
do
|
|
||||||
create Result.make (table)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Common Gateway Interface - 1.1 8 January 1996
|
feature -- Common Gateway Interface - 1.1 8 January 1996
|
||||||
|
|
||||||
auth_type: detachable STRING
|
auth_type: detachable READABLE_STRING_32
|
||||||
-- This variable is specific to requests made via the "http"
|
-- This variable is specific to requests made via the "http"
|
||||||
-- scheme.
|
-- scheme.
|
||||||
--
|
--
|
||||||
@@ -143,7 +150,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
content_length: detachable STRING
|
content_length: detachable READABLE_STRING_32
|
||||||
-- 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
|
||||||
@@ -158,12 +165,12 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
content_length_value: INTEGER
|
content_length_value: NATURAL_64
|
||||||
-- Integer value related to `content_length"
|
-- Integer value related to `content_length"
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
content_type: detachable STRING
|
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,
|
||||||
@@ -206,7 +213,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
gateway_interface: STRING
|
gateway_interface: READABLE_STRING_32
|
||||||
-- 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:
|
||||||
--
|
--
|
||||||
@@ -239,7 +246,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
path_info: STRING assign update_path_info
|
path_info: READABLE_STRING_32
|
||||||
-- 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
|
||||||
@@ -270,7 +277,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
path_translated: detachable STRING
|
path_translated: detachable READABLE_STRING_32
|
||||||
-- 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
|
||||||
@@ -316,7 +323,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
query_string: STRING
|
query_string: READABLE_STRING_32
|
||||||
-- 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.)
|
||||||
--
|
--
|
||||||
@@ -333,7 +340,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
remote_addr: STRING
|
remote_addr: READABLE_STRING_32
|
||||||
-- 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).
|
||||||
@@ -348,7 +355,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
remote_host: detachable STRING
|
remote_host: detachable READABLE_STRING_32
|
||||||
-- 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
|
||||||
@@ -359,7 +366,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
remote_ident: detachable STRING
|
remote_ident: detachable READABLE_STRING_32
|
||||||
-- 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
|
||||||
@@ -375,7 +382,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
remote_user: detachable STRING
|
remote_user: detachable READABLE_STRING_32
|
||||||
-- 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
|
||||||
@@ -391,7 +398,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
request_method: STRING
|
request_method: READABLE_STRING_32
|
||||||
-- 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
|
||||||
@@ -412,7 +419,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
script_name: STRING
|
script_name: READABLE_STRING_32
|
||||||
-- 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
|
||||||
@@ -430,7 +437,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
server_name: STRING
|
server_name: READABLE_STRING_32
|
||||||
-- 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).
|
||||||
@@ -456,7 +463,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
server_protocol: STRING
|
server_protocol: READABLE_STRING_32
|
||||||
-- 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
|
||||||
@@ -484,7 +491,7 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
server_software: STRING
|
server_software: READABLE_STRING_32
|
||||||
-- 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).
|
||||||
@@ -499,42 +506,42 @@ feature -- Common Gateway Interface - 1.1 8 January 1996
|
|||||||
|
|
||||||
feature -- HTTP_*
|
feature -- HTTP_*
|
||||||
|
|
||||||
http_accept: detachable STRING
|
http_accept: detachable READABLE_STRING_32
|
||||||
-- 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 STRING
|
http_accept_charset: detachable READABLE_STRING_32
|
||||||
-- 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 STRING
|
http_accept_encoding: detachable READABLE_STRING_32
|
||||||
-- 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 STRING
|
http_accept_language: detachable READABLE_STRING_32
|
||||||
-- 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 STRING
|
http_connection: detachable READABLE_STRING_32
|
||||||
-- 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 STRING
|
http_host: detachable READABLE_STRING_32
|
||||||
-- 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 STRING
|
http_referer: detachable READABLE_STRING_32
|
||||||
-- 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.
|
||||||
@@ -542,7 +549,7 @@ feature -- HTTP_*
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
http_user_agent: detachable STRING
|
http_user_agent: detachable READABLE_STRING_32
|
||||||
-- 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).
|
||||||
@@ -551,46 +558,127 @@ feature -- HTTP_*
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
http_authorization: detachable STRING
|
http_authorization: detachable READABLE_STRING_32
|
||||||
-- 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
|
feature -- Extra CGI environment variables
|
||||||
|
|
||||||
request_uri: STRING
|
request_uri: READABLE_STRING_32
|
||||||
-- 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 STRING
|
orig_path_info: detachable READABLE_STRING_32
|
||||||
-- 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 {EWSGI_REQUEST} -- Element change
|
--feature -- Access: execution variables
|
||||||
|
|
||||||
set_orig_path_info (s: STRING)
|
-- execution_variables: WGI_VARIABLES [STRING_32]
|
||||||
-- Set ORIG_PATH_INFO to `s'
|
-- -- Execution variables set by the application
|
||||||
|
-- deferred
|
||||||
|
-- end
|
||||||
|
|
||||||
|
-- execution_variable (a_name: STRING): detachable STRING_32
|
||||||
|
-- -- Execution variable related to `a_name'
|
||||||
|
-- require
|
||||||
|
-- a_name_valid: a_name /= Void and then not a_name.is_empty
|
||||||
|
-- deferred
|
||||||
|
-- end
|
||||||
|
|
||||||
|
feature -- Query string Parameters
|
||||||
|
|
||||||
|
query_parameters: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]
|
||||||
|
-- Variables extracted from QUERY_STRING
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
query_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
|
-- Parameter for name `n'.
|
||||||
require
|
require
|
||||||
s_attached: s /= Void
|
a_name_valid: a_name /= Void and then not a_name.is_empty
|
||||||
deferred
|
deferred
|
||||||
ensure
|
|
||||||
same_orig_path_info: orig_path_info ~ variable ({EWSGI_ENVIRONMENT_NAMES}.orig_path_info)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
unset_orig_path_info
|
feature -- Form fields and related
|
||||||
-- Unset ORIG_PATH_INFO
|
|
||||||
|
form_data_parameters: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]
|
||||||
|
-- Variables sent by POST request
|
||||||
deferred
|
deferred
|
||||||
ensure
|
|
||||||
unset: not has_variable ({EWSGI_ENVIRONMENT_NAMES}.orig_path_info)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
update_path_info (a_path_info: like path_info)
|
form_data_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
-- Updated PATH_INFO
|
-- 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: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]
|
||||||
|
-- Expanded cookies variable
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
cookie (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
|
-- Field for name `a_name'.
|
||||||
|
require
|
||||||
|
a_name_valid: a_name /= Void and then not a_name.is_empty
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access: global variable
|
||||||
|
|
||||||
|
parameters: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]
|
||||||
|
-- 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
|
||||||
|
|
||||||
|
parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
|
-- 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
|
deferred
|
||||||
ensure
|
|
||||||
same_path_info: path_info ~ variable ({EWSGI_ENVIRONMENT_NAMES}.path_info)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
invariant
|
invariant
|
||||||
@@ -601,9 +689,12 @@ invariant
|
|||||||
query_string_attached: query_string /= Void
|
query_string_attached: query_string /= Void
|
||||||
remote_addr_attached: remote_addr /= Void
|
remote_addr_attached: remote_addr /= Void
|
||||||
|
|
||||||
path_info_identical: path_info ~ variable ({EWSGI_ENVIRONMENT_NAMES}.path_info)
|
same_orig_path_info: orig_path_info ~ meta_variable ({WGI_META_NAMES}.orig_path_info)
|
||||||
|
same_path_info: path_info ~ meta_variable ({WGI_META_NAMES}.path_info)
|
||||||
|
|
||||||
;note
|
path_info_identical: path_info ~ meta_variable ({WGI_META_NAMES}.path_info)
|
||||||
|
|
||||||
|
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: "[
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {GW_UPLOADED_FILE}."
|
description: "Summary description for {WGI_UPLOADED_FILE_DATA}."
|
||||||
author: ""
|
author: ""
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
class
|
class
|
||||||
EWSGI_UPLOADED_FILE_DATA
|
WGI_UPLOADED_FILE_DATA
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {EWSGI_RESPONSE_BUFFER}."
|
description: "Summary description for {WGI_RESPONSE_BUFFER}."
|
||||||
author: ""
|
author: ""
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
EWSGI_RESPONSE_BUFFER
|
WGI_RESPONSE_BUFFER
|
||||||
|
|
||||||
feature {EWSGI_APPLICATION} -- Commit
|
feature {WGI_APPLICATION} -- Commit
|
||||||
|
|
||||||
commit
|
commit
|
||||||
-- Commit the current response
|
-- Commit the current response
|
||||||
@@ -35,7 +35,7 @@ feature -- Status report
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Core output operation
|
feature {WGI_RESPONSE_BUFFER} -- Core output operation
|
||||||
|
|
||||||
write (s: STRING)
|
write (s: STRING)
|
||||||
-- Send the string `s'
|
-- Send the string `s'
|
||||||
@@ -67,13 +67,33 @@ feature -- Status setting
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Output operation
|
feature -- Header output operation
|
||||||
|
|
||||||
flush
|
write_headers_string (a_headers: STRING)
|
||||||
-- Flush if it makes sense
|
require
|
||||||
|
status_set: status_is_set
|
||||||
|
header_not_committed: not header_committed
|
||||||
deferred
|
deferred
|
||||||
|
ensure
|
||||||
|
status_set: status_is_set
|
||||||
|
header_committed: header_committed
|
||||||
|
message_writable: message_writable
|
||||||
end
|
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'
|
||||||
|
require
|
||||||
|
status_not_set: not status_is_set
|
||||||
|
header_not_committed: not header_committed
|
||||||
|
deferred
|
||||||
|
ensure
|
||||||
|
header_committed: header_committed
|
||||||
|
status_set: status_is_set
|
||||||
|
message_writable: message_writable
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Output operation
|
||||||
|
|
||||||
write_string (s: STRING)
|
write_string (s: STRING)
|
||||||
-- Send the string `s'
|
-- Send the string `s'
|
||||||
require
|
require
|
||||||
@@ -95,17 +115,9 @@ feature -- Output operation
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Header output operation
|
flush
|
||||||
|
-- Flush if it makes sense
|
||||||
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'
|
|
||||||
require
|
|
||||||
status_not_set: not status_is_set
|
|
||||||
header_not_committed: not header_committed
|
|
||||||
deferred
|
deferred
|
||||||
ensure
|
|
||||||
header_committed: header_committed
|
|
||||||
status_set: status_is_set
|
|
||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
@@ -8,7 +8,7 @@ note
|
|||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
EWSGI_INPUT_STREAM
|
WGI_INPUT_STREAM
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ note
|
|||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
EWSGI_OUTPUT_STREAM
|
WGI_OUTPUT_STREAM
|
||||||
|
|
||||||
feature -- Core operation
|
feature -- Core operation
|
||||||
|
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {EWSGI_APPLICATION}."
|
description: "Summary description for {WGI_APPLICATION}."
|
||||||
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$"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
EWSGI_APPLICATION
|
WGI_APPLICATION
|
||||||
|
|
||||||
feature {NONE} -- Execution
|
feature {NONE} -- Execution
|
||||||
|
|
||||||
execute (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
|
execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
-- Execute the request
|
-- Execute the request
|
||||||
-- See `req.input' for input stream
|
-- See `req.input' for input stream
|
||||||
-- `req.environment' for the Gateway environment
|
-- `req.environment' for the Gateway environment
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {EWSGI_AGENT_APPLICATION}."
|
description: "Summary description for {WGI_AGENT_APPLICATION}."
|
||||||
author: ""
|
author: ""
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
class
|
class
|
||||||
EWSGI_AGENT_APPLICATION
|
WGI_AGENT_APPLICATION
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
EWSGI_APPLICATION
|
WGI_APPLICATION
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
@@ -23,10 +23,10 @@ feature {NONE} -- Implementation
|
|||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
callback: PROCEDURE [ANY, TUPLE [req: like new_request; res: like new_response]]
|
callback: PROCEDURE [ANY, TUPLE [req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]]
|
||||||
-- Procedure called on `execute'
|
-- Procedure called on `execute'
|
||||||
|
|
||||||
execute (req: like new_request; res: like new_response)
|
execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
-- Execute the request
|
-- Execute the request
|
||||||
do
|
do
|
||||||
callback.call ([req, res])
|
callback.call ([req, res])
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
note
|
note
|
||||||
description: "[
|
description: "[
|
||||||
EWSGI_APPLICATION
|
WGI_APPLICATION
|
||||||
]"
|
]"
|
||||||
specification: "EWSGI specification https://github.com/Eiffel-World/Eiffel-Web-Framework/wiki/EWSGI-specification"
|
specification: "EWSGI specification https://github.com/Eiffel-World/Eiffel-Web-Framework/wiki/EWSGI-specification"
|
||||||
legal: "See notice at end of class."
|
legal: "See notice at end of class."
|
||||||
@@ -9,11 +9,11 @@ note
|
|||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
EWSGI_APPLICATION
|
WGI_APPLICATION
|
||||||
|
|
||||||
feature {NONE} -- Execution
|
feature -- Execution
|
||||||
|
|
||||||
execute (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
|
execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
-- Execute the request
|
-- Execute the request
|
||||||
-- See `req.input' for input stream
|
-- See `req.input' for input stream
|
||||||
-- `req.environment' for the Gateway environment
|
-- `req.environment' for the Gateway environment
|
||||||
@@ -23,23 +23,19 @@ feature {NONE} -- Execution
|
|||||||
deferred
|
deferred
|
||||||
ensure
|
ensure
|
||||||
res_status_set: res.status_is_set
|
res_status_set: res.status_is_set
|
||||||
res_committed: res.message_committed
|
-- res_committed: res.message_committed
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Process request
|
feature -- Process request
|
||||||
|
|
||||||
process (env: EWSGI_ENVIRONMENT; a_input: EWSGI_INPUT_STREAM; a_output: EWSGI_OUTPUT_STREAM)
|
process (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
-- Process request with environment `env', and i/o streams `a_input' and `a_output'
|
-- Process request with environment `env', and i/o streams `a_input' and `a_output'
|
||||||
local
|
local
|
||||||
rescued: BOOLEAN
|
rescued: BOOLEAN
|
||||||
req: detachable like new_request
|
|
||||||
res: detachable like new_response
|
|
||||||
do
|
do
|
||||||
if not rescued then
|
if not rescued then
|
||||||
request_count := request_count + 1
|
request_count := request_count + 1
|
||||||
pre_execute (env)
|
pre_execute (req)
|
||||||
req := new_request (env, a_input)
|
|
||||||
res := new_response (req, a_output)
|
|
||||||
execute (req, res)
|
execute (req, res)
|
||||||
post_execute (req, res)
|
post_execute (req, res)
|
||||||
else
|
else
|
||||||
@@ -57,24 +53,21 @@ feature -- Access
|
|||||||
|
|
||||||
feature {NONE} -- Execution
|
feature {NONE} -- Execution
|
||||||
|
|
||||||
pre_execute (env: EWSGI_ENVIRONMENT)
|
pre_execute (req: WGI_REQUEST)
|
||||||
-- Operation processed before `execute'
|
-- Operation processed before `execute'
|
||||||
require
|
|
||||||
env_attached: env /= Void
|
|
||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
post_execute (req: detachable EWSGI_REQUEST; res: detachable EWSGI_RESPONSE_BUFFER)
|
post_execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
-- Operation processed after `execute', or after `rescue_execute'
|
-- Operation processed after `execute', or after `rescue_execute'
|
||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
rescue_execute (req: detachable EWSGI_REQUEST; res: detachable EWSGI_RESPONSE_BUFFER; a_exception: detachable EXCEPTION)
|
rescue_execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_exception: detachable EXCEPTION)
|
||||||
-- Operation processed on rescue of `execute'
|
-- Operation processed on rescue of `execute'
|
||||||
do
|
do
|
||||||
if
|
if
|
||||||
req /= Void and res /= Void
|
a_exception /= Void and then attached a_exception.exception_trace as l_trace
|
||||||
and a_exception /= Void and then attached a_exception.exception_trace as l_trace
|
|
||||||
then
|
then
|
||||||
res.write_header ({HTTP_STATUS_CODE}.internal_server_error, Void)
|
res.write_header ({HTTP_STATUS_CODE}.internal_server_error, Void)
|
||||||
res.write_string ("<pre>" + l_trace + "</pre>")
|
res.write_string ("<pre>" + l_trace + "</pre>")
|
||||||
@@ -82,19 +75,6 @@ feature {NONE} -- Execution
|
|||||||
post_execute (req, res)
|
post_execute (req, res)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Factory
|
|
||||||
|
|
||||||
new_request (env: EWSGI_ENVIRONMENT; a_input: EWSGI_INPUT_STREAM): EWSGI_REQUEST
|
|
||||||
do
|
|
||||||
create {EWSGI_REQUEST} Result.make (env, a_input)
|
|
||||||
Result.environment.set_variable (request_count.out, "REQUEST_COUNT")
|
|
||||||
end
|
|
||||||
|
|
||||||
new_response (req: EWSGI_REQUEST; a_output: EWSGI_OUTPUT_STREAM): EWSGI_RESPONSE_BUFFER
|
|
||||||
do
|
|
||||||
create {EWSGI_RESPONSE_BUFFER} Result.make (a_output)
|
|
||||||
end
|
|
||||||
|
|
||||||
;note
|
;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)"
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {EWSGI_CONNECTOR}."
|
description: "Summary description for {WGI_CONNECTOR}."
|
||||||
specification: "EWSGI/connector specification https://github.com/Eiffel-World/Eiffel-Web-Framework/wiki/EWSGI-specification"
|
specification: "EWSGI/connector specification https://github.com/Eiffel-World/Eiffel-Web-Framework/wiki/EWSGI-specification"
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
EWSGI_CONNECTOR
|
WGI_CONNECTOR
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ feature {NONE} -- Initialization
|
|||||||
|
|
||||||
feature {NONE} -- Access
|
feature {NONE} -- Access
|
||||||
|
|
||||||
application: EWSGI_APPLICATION
|
application: WGI_APPLICATION
|
||||||
-- Gateway Application
|
-- Gateway Application
|
||||||
|
|
||||||
feature -- Server
|
feature -- Server
|
||||||
186
library/server/ewsgi/src/extra/ewf_buffered_response.e
Normal file
186
library/server/ewsgi/src/extra/ewf_buffered_response.e
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
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
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {GW_BUFFERED_RESPONSE}."
|
|
||||||
author: ""
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
GW_BUFFERED_RESPONSE
|
|
||||||
|
|
||||||
inherit
|
|
||||||
EWSGI_RESPONSE_BUFFER
|
|
||||||
rename
|
|
||||||
make as buffer_make
|
|
||||||
redefine
|
|
||||||
write,
|
|
||||||
flush,
|
|
||||||
commit
|
|
||||||
end
|
|
||||||
|
|
||||||
create {EWSGI_APPLICATION}
|
|
||||||
make
|
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
|
||||||
|
|
||||||
make (a_output: like output; a_buffer_size: INTEGER)
|
|
||||||
do
|
|
||||||
buffer_make (a_output)
|
|
||||||
buffer_capacity := a_buffer_size
|
|
||||||
create buffer.make (a_buffer_size)
|
|
||||||
end
|
|
||||||
|
|
||||||
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
|
|
||||||
output.put_string (buffer)
|
|
||||||
buffer_count := 0
|
|
||||||
ensure
|
|
||||||
buffer_flushed: buffer_count = 0 and buffer.count = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {EWSGI_APPLICATION} -- Commit
|
|
||||||
|
|
||||||
commit
|
|
||||||
do
|
|
||||||
flush_buffer
|
|
||||||
Precursor
|
|
||||||
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
|
|
||||||
@@ -1,38 +1,79 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {GW_IN_MEMORY_RESPONSE}."
|
description: "Summary description for {EWF_IN_MEMORY_RESPONSE}."
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
class
|
class
|
||||||
GW_IN_MEMORY_RESPONSE
|
EWF_IN_MEMORY_RESPONSE
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
EWSGI_RESPONSE_BUFFER
|
WGI_RESPONSE_BUFFER
|
||||||
redefine
|
|
||||||
make,
|
|
||||||
commit,
|
|
||||||
write,
|
|
||||||
set_status_code,
|
|
||||||
write_header,
|
|
||||||
flush
|
|
||||||
end
|
|
||||||
|
|
||||||
create {EWSGI_APPLICATION}
|
create {WGI_APPLICATION}
|
||||||
make
|
make
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
make (a_output: EWSGI_OUTPUT_STREAM)
|
make (res: WGI_RESPONSE_BUFFER)
|
||||||
do
|
do
|
||||||
Precursor (a_output)
|
response_buffer := res
|
||||||
create header.make
|
create header.make
|
||||||
create body.make (100)
|
create body.make (100)
|
||||||
end
|
end
|
||||||
|
|
||||||
header: GW_HEADER
|
response_buffer: WGI_RESPONSE_BUFFER
|
||||||
|
|
||||||
|
header: EWF_HEADER
|
||||||
|
|
||||||
body: STRING_8
|
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
|
feature {NONE} -- Status output
|
||||||
|
|
||||||
write (s: STRING)
|
write (s: STRING)
|
||||||
@@ -41,28 +82,18 @@ feature {NONE} -- Status output
|
|||||||
body.append (s)
|
body.append (s)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Status setting
|
feature -- Header output operation
|
||||||
|
|
||||||
set_status_code (a_code: INTEGER)
|
write_headers_string (a_headers: STRING)
|
||||||
-- Set response status code
|
|
||||||
-- Should be done before sending any data back to the client
|
|
||||||
do
|
do
|
||||||
status_code := a_code
|
write (a_headers)
|
||||||
|
header_committed := True
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Output operation
|
|
||||||
|
|
||||||
flush
|
|
||||||
do
|
|
||||||
--| Do nothing ... this is in_memory response
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Header output operation
|
|
||||||
|
|
||||||
write_header (a_status_code: INTEGER; a_headers: detachable ARRAY [TUPLE [key: STRING; value: STRING]])
|
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'
|
-- Send headers with status `a_status', and headers from `a_headers'
|
||||||
local
|
local
|
||||||
h: GW_HEADER
|
h: EWF_HEADER
|
||||||
i,n: INTEGER
|
i,n: INTEGER
|
||||||
do
|
do
|
||||||
set_status_code (a_status_code)
|
set_status_code (a_status_code)
|
||||||
@@ -81,19 +112,30 @@ feature -- Header output operation
|
|||||||
header := h
|
header := h
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {EWSGI_APPLICATION} -- Commit
|
feature -- Output operation
|
||||||
|
|
||||||
commit
|
write_string (s: STRING)
|
||||||
local
|
-- Send the string `s'
|
||||||
o: like output
|
|
||||||
do
|
do
|
||||||
o := output
|
write (s)
|
||||||
o.put_status_line (status_code)
|
end
|
||||||
o.put_string (header.string)
|
|
||||||
header_committed := True
|
write_substring (s: STRING; start_index, end_index: INTEGER)
|
||||||
o.put_string (body)
|
-- Send the substring `start_index:end_index]'
|
||||||
o.flush
|
--| Could be optimized according to the target output
|
||||||
Precursor
|
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
|
end
|
||||||
|
|
||||||
;note
|
;note
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
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
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {GW_IN_MEMORY_RESPONSE_APPLICATION}."
|
|
||||||
author: ""
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
deferred class
|
|
||||||
GW_IN_MEMORY_RESPONSE_APPLICATION
|
|
||||||
|
|
||||||
inherit
|
|
||||||
EWSGI_APPLICATION
|
|
||||||
redefine
|
|
||||||
new_response
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Factory
|
|
||||||
|
|
||||||
new_response (req: EWSGI_REQUEST; a_output: EWSGI_OUTPUT_STREAM): GW_IN_MEMORY_RESPONSE
|
|
||||||
do
|
|
||||||
create {GW_IN_MEMORY_RESPONSE} Result.make (a_output)
|
|
||||||
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
|
|
||||||
@@ -8,7 +8,7 @@ note
|
|||||||
author: "Paul Cohen <paul.cohen@seibostudio.se>"
|
author: "Paul Cohen <paul.cohen@seibostudio.se>"
|
||||||
status: "Draft"
|
status: "Draft"
|
||||||
|
|
||||||
class EWSGI_RESPONSE
|
class WGI_RESPONSE
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
@@ -26,12 +26,12 @@ feature {NONE} -- Initialization
|
|||||||
create headers_table.make (10)
|
create headers_table.make (10)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {EWSGI_RESPONSE_APPLICATION} -- Response status
|
feature {WGI_RESPONSE_APPLICATION} -- Response status
|
||||||
|
|
||||||
transmit_to (res: EWSGI_RESPONSE_BUFFER)
|
transmit_to (res: WGI_RESPONSE_BUFFER)
|
||||||
do
|
do
|
||||||
res.set_status_code (status)
|
res.set_status_code (status)
|
||||||
res.write_string (headers)
|
res.write_headers_string (headers)
|
||||||
from
|
from
|
||||||
read_block
|
read_block
|
||||||
res.write_string (last_block)
|
res.write_string (last_block)
|
||||||
@@ -64,7 +64,7 @@ feature {EWSGI_RESPONSE_APPLICATION} -- Response status
|
|||||||
ready_to_transmit
|
ready_to_transmit
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {EWSGI_RESPONSE_APPLICATION} -- Message start line and status
|
feature {WGI_RESPONSE_APPLICATION} -- Message start line and status
|
||||||
|
|
||||||
status: INTEGER
|
status: INTEGER
|
||||||
-- HTTP status code
|
-- HTTP status code
|
||||||
@@ -88,7 +88,7 @@ feature {EWSGI_RESPONSE_APPLICATION} -- Message start line and status
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {EWSGI_RESPONSE_APPLICATION} -- Message headers
|
feature {WGI_RESPONSE_APPLICATION} -- Message headers
|
||||||
|
|
||||||
headers: STRING
|
headers: STRING
|
||||||
-- HTTP message headers including trailing empty line.
|
-- HTTP message headers including trailing empty line.
|
||||||
@@ -119,7 +119,7 @@ feature {EWSGI_RESPONSE_APPLICATION} -- Message headers
|
|||||||
headers_table.has (key) and headers_table @ key = value
|
headers_table.has (key) and headers_table @ key = value
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {EWSGI_RESPONSE_APPLICATION} -- Message body
|
feature {WGI_RESPONSE_APPLICATION} -- Message body
|
||||||
|
|
||||||
read_block
|
read_block
|
||||||
-- Read a message body block.
|
-- Read a message body block.
|
||||||
@@ -131,7 +131,8 @@ feature {EWSGI_RESPONSE_APPLICATION} -- Message body
|
|||||||
-- -- TBD!
|
-- -- TBD!
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
not is_buffered implies last_block.count <= max_block_size
|
--Commented, since it is far from obvious to ensure that:
|
||||||
|
-- not is_buffered implies last_block.count <= max_block_size
|
||||||
end
|
end
|
||||||
|
|
||||||
last_block: STRING
|
last_block: STRING
|
||||||
@@ -1,23 +1,22 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {EWSGI_RESPONSE_APPLICATION} "
|
description: "Summary description for {WGI_RESPONSE_APPLICATION} "
|
||||||
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$"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
EWSGI_RESPONSE_APPLICATION
|
WGI_RESPONSE_APPLICATION
|
||||||
|
|
||||||
feature -- Execution
|
feature -- Execution
|
||||||
|
|
||||||
execute (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
|
execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
-- Execute the request
|
-- Execute the request
|
||||||
-- See `req.input' for input stream
|
-- See `req.input' for input stream
|
||||||
-- `req.environment' for the Gateway environment
|
-- `req.environment' for the Gateway environment
|
||||||
-- and `res.output' for output stream
|
-- and `res.output' for output stream
|
||||||
local
|
local
|
||||||
rs: EWSGI_RESPONSE
|
rs: WGI_RESPONSE
|
||||||
s: STRING
|
|
||||||
do
|
do
|
||||||
rs := response (req)
|
rs := response (req)
|
||||||
if rs.ready_to_transmit then
|
if rs.ready_to_transmit then
|
||||||
@@ -25,7 +24,7 @@ feature -- Execution
|
|||||||
else
|
else
|
||||||
-- Report internal server error.
|
-- Report internal server error.
|
||||||
-- Response not ready to transmit!
|
-- Response not ready to transmit!
|
||||||
-- Implementor of EWSGI_APPLICATION has not done his job!
|
-- Implementor of WGI_APPLICATION has not done his job!
|
||||||
create rs.make
|
create rs.make
|
||||||
rs.set_status (500)
|
rs.set_status (500)
|
||||||
rs.set_header ("Content-Type", "text/plain")
|
rs.set_header ("Content-Type", "text/plain")
|
||||||
@@ -36,7 +35,7 @@ feature -- Execution
|
|||||||
|
|
||||||
feature -- Response
|
feature -- Response
|
||||||
|
|
||||||
response (request: EWSGI_REQUEST): EWSGI_RESPONSE
|
response (request: WGI_REQUEST): WGI_RESPONSE
|
||||||
-- HTTP response for given 'request'.
|
-- HTTP response for given 'request'.
|
||||||
deferred
|
deferred
|
||||||
ensure
|
ensure
|
||||||
@@ -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
|
|
||||||
EWSGI_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
|
|
||||||
@@ -1,617 +0,0 @@
|
|||||||
note
|
|
||||||
description: "[
|
|
||||||
|
|
||||||
Interface for a request environment
|
|
||||||
It includes CGI interface and a few extra values that are usually valuable
|
|
||||||
|
|
||||||
See http://www.ietf.org/rfc/rfc3875
|
|
||||||
|
|
||||||
2.2. Basic Rules
|
|
||||||
|
|
||||||
The following rules are used throughout this specification to
|
|
||||||
describe basic parsing constructs.
|
|
||||||
|
|
||||||
alpha = lowalpha | hialpha
|
|
||||||
lowalpha = a | b | c | d | e | f | g | h |
|
|
||||||
i | j | k | l | m | n | o | p |
|
|
||||||
q | r | s | t | u | v | w | x |
|
|
||||||
y | z
|
|
||||||
hialpha = A | B | C | D | E | F | G | H |
|
|
||||||
I | J | K | L | M | N | O | P |
|
|
||||||
Q | R | S | T | U | V | W | X |
|
|
||||||
Y | Z
|
|
||||||
digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
|
||||||
8 | 9
|
|
||||||
alphanum = alpha | digit
|
|
||||||
OCTET = <any 8-bit byte>
|
|
||||||
CHAR = alpha | digit | separator | ! | # | $ |
|
|
||||||
%% | & | ' | * | + | - | . | ` |
|
|
||||||
^ | _ | { | | | } | ~ | CTL
|
|
||||||
CTL = <any control character>
|
|
||||||
SP = <space character>
|
|
||||||
HT = <horizontal tab character>
|
|
||||||
NL = <newline>
|
|
||||||
LWSP = SP | HT | NL
|
|
||||||
separator = ( | ) | < | > | @ | , | ; | : |
|
|
||||||
\ | " | / | [ | ] | ? | = | { |
|
|
||||||
} | SP | HT
|
|
||||||
token = 1*<any CHAR except CTLs or separators>
|
|
||||||
quoted-string = " *qdtext "
|
|
||||||
qdtext = <any CHAR except " and CTLs but including LWSP>
|
|
||||||
TEXT = <any printable character>
|
|
||||||
|
|
||||||
2.3. URL Encoding
|
|
||||||
|
|
||||||
reserved = ; | / | ? | : | @ | & | = | + | $ |
|
|
||||||
, | [ | ]
|
|
||||||
|
|
||||||
hex = digit | A | B | C | D | E | F | a | b
|
|
||||||
| c | d | e | f
|
|
||||||
escaped = "%%" hex hex
|
|
||||||
unreserved = alpha | digit | mark
|
|
||||||
mark = - | _ | . | ! | ~ | * | ' | ( | )
|
|
||||||
|
|
||||||
Note that newline (NL) need not be a single character, but can
|
|
||||||
be a character sequence.
|
|
||||||
|
|
||||||
3.2. The Script-URI
|
|
||||||
|
|
||||||
script-URI = <scheme> "://" <server-name> ":" <server-port>
|
|
||||||
<script-path> <extra-path> "?" <query-string>
|
|
||||||
|
|
||||||
where <scheme> is found from SERVER_PROTOCOL, <server-name>,
|
|
||||||
<server-port> and <query-string> are the values of the respective
|
|
||||||
meta-variables. The SCRIPT_NAME and PATH_INFO values, URL-encoded
|
|
||||||
with ";", "=" and "?" reserved, give <script-path> and <extra-path>.
|
|
||||||
|
|
||||||
]"
|
|
||||||
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$"
|
|
||||||
|
|
||||||
deferred
|
|
||||||
class
|
|
||||||
EWSGI_ENVIRONMENT
|
|
||||||
|
|
||||||
inherit
|
|
||||||
EWSGI_VARIABLES [STRING_8]
|
|
||||||
|
|
||||||
ITERABLE [STRING_8]
|
|
||||||
|
|
||||||
feature -- Access
|
|
||||||
|
|
||||||
table: HASH_TABLE [STRING, STRING]
|
|
||||||
-- These variables are specific to requests made with HTTP.
|
|
||||||
-- Interpretation of these variables may depend on the value of
|
|
||||||
-- SERVER_PROTOCOL.
|
|
||||||
--
|
|
||||||
-- Environment variables with names beginning with "HTTP_" contain
|
|
||||||
-- header data read from the client, if the protocol used was HTTP.
|
|
||||||
-- The HTTP header name is converted to upper case, has all
|
|
||||||
-- occurrences of "-" replaced with "_" and has "HTTP_" prepended to
|
|
||||||
-- give the environment variable name. The header data may be
|
|
||||||
-- presented as sent by the client, or may be rewritten in ways which
|
|
||||||
-- do not change its semantics. If multiple headers with the same
|
|
||||||
-- field-name are received then they must be rewritten as a single
|
|
||||||
-- header having the same semantics. Similarly, a header that is
|
|
||||||
-- received on more than one line must be merged onto a single line.
|
|
||||||
-- The server must, if necessary, change the representation of the
|
|
||||||
-- data (for example, the character set) to be appropriate for a CGI
|
|
||||||
-- environment variable.
|
|
||||||
--
|
|
||||||
-- The server is not required to create environment variables for all
|
|
||||||
-- the headers that it receives. In particular, it may remove any
|
|
||||||
-- headers carrying authentication information, such as
|
|
||||||
-- "Authorization"; it may remove headers whose value is available to
|
|
||||||
-- the script via other variables, such as "Content-Length" and
|
|
||||||
-- "Content-Type".
|
|
||||||
--
|
|
||||||
-- For convenience it might also include the following CGI entries
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access: table
|
|
||||||
|
|
||||||
new_cursor: HASH_TABLE_ITERATION_CURSOR [STRING_8, STRING_8]
|
|
||||||
-- Fresh cursor associated with current structure
|
|
||||||
do
|
|
||||||
create Result.make (table)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Common Gateway Interface - 1.1 8 January 1996
|
|
||||||
|
|
||||||
auth_type: detachable STRING
|
|
||||||
-- This variable is specific to requests made via the "http"
|
|
||||||
-- scheme.
|
|
||||||
--
|
|
||||||
-- If the Script-URI required access authentication for external
|
|
||||||
-- access, then the server MUST set the value of this variable
|
|
||||||
-- from the 'auth-scheme' token in the request's "Authorization"
|
|
||||||
-- header field. Otherwise it is set to NULL.
|
|
||||||
--
|
|
||||||
-- AUTH_TYPE = "" | auth-scheme
|
|
||||||
-- auth-scheme = "Basic" | "Digest" | token
|
|
||||||
--
|
|
||||||
-- HTTP access authentication schemes are described in section 11
|
|
||||||
-- of the HTTP/1.1 specification [8]. The auth-scheme is not
|
|
||||||
-- case-sensitive.
|
|
||||||
--
|
|
||||||
-- Servers MUST provide this metavariable to scripts if the
|
|
||||||
-- request header included an "Authorization" field that was
|
|
||||||
-- authenticated.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
content_length: detachable STRING
|
|
||||||
-- This metavariable is set to the size of the message-body
|
|
||||||
-- entity attached to the request, if any, in decimal number of
|
|
||||||
-- octets. If no data are attached, then this metavariable is
|
|
||||||
-- either NULL or not defined. The syntax is the same as for the
|
|
||||||
-- HTTP "Content-Length" header field (section 14.14, HTTP/1.1
|
|
||||||
-- specification [8]).
|
|
||||||
--
|
|
||||||
-- CONTENT_LENGTH = "" | 1*digit
|
|
||||||
--
|
|
||||||
-- Servers MUST provide this metavariable to scripts if the
|
|
||||||
-- request was accompanied by a message-body entity.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
content_length_value: INTEGER
|
|
||||||
-- Integer value related to `content_length"
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
content_type: detachable STRING
|
|
||||||
-- If the request includes a message-body, CONTENT_TYPE is set to
|
|
||||||
-- the Internet Media Type [9] of the attached entity if the type
|
|
||||||
-- was provided via a "Content-type" field in the request header,
|
|
||||||
-- or if the server can determine it in the absence of a supplied
|
|
||||||
-- "Content-type" field. The syntax is the same as for the HTTP
|
|
||||||
-- "Content-Type" header field.
|
|
||||||
--
|
|
||||||
-- CONTENT_TYPE = "" | media-type
|
|
||||||
-- media-type = type "/" subtype *( ";" parameter)
|
|
||||||
-- type = token
|
|
||||||
-- subtype = token
|
|
||||||
-- parameter = attribute "=" value
|
|
||||||
-- attribute = token
|
|
||||||
-- value = token | quoted-string
|
|
||||||
--
|
|
||||||
-- The type, subtype, and parameter attribute names are not
|
|
||||||
-- case-sensitive. Parameter values MAY be case sensitive. Media
|
|
||||||
-- types and their use in HTTP are described in section 3.7 of
|
|
||||||
-- the HTTP/1.1 specification [8].
|
|
||||||
--
|
|
||||||
-- Example:
|
|
||||||
--
|
|
||||||
-- application/x-www-form-urlencoded
|
|
||||||
--
|
|
||||||
-- There is no default value for this variable. If and only if it
|
|
||||||
-- is unset, then the script MAY attempt to determine the media
|
|
||||||
-- type from the data received. If the type remains unknown, then
|
|
||||||
-- the script MAY choose to either assume a content-type of
|
|
||||||
-- application/octet-stream or reject the request with a 415
|
|
||||||
-- ("Unsupported Media Type") error. See section 7.2.1.3 for more
|
|
||||||
-- information about returning error status values.
|
|
||||||
--
|
|
||||||
-- Servers MUST provide this metavariable to scripts if a
|
|
||||||
-- "Content-Type" field was present in the original request
|
|
||||||
-- header. If the server receives a request with an attached
|
|
||||||
-- entity but no "Content-Type" header field, it MAY attempt to
|
|
||||||
-- determine the correct datatype, or it MAY omit this
|
|
||||||
-- metavariable when communicating the request information to the
|
|
||||||
-- script.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
gateway_interface: STRING
|
|
||||||
-- This metavariable is set to the dialect of CGI being used by
|
|
||||||
-- the server to communicate with the script. Syntax:
|
|
||||||
--
|
|
||||||
-- GATEWAY_INTERFACE = "CGI" "/" major "." minor
|
|
||||||
-- major = 1*digit
|
|
||||||
-- minor = 1*digit
|
|
||||||
--
|
|
||||||
-- Note that the major and minor numbers are treated as separate
|
|
||||||
-- integers and hence each may be more than a single digit. Thus
|
|
||||||
-- CGI/2.4 is a lower version than CGI/2.13 which in turn is
|
|
||||||
-- lower than CGI/12.3. Leading zeros in either the major or the
|
|
||||||
-- minor number MUST be ignored by scripts and SHOULD NOT be
|
|
||||||
-- generated by servers.
|
|
||||||
--
|
|
||||||
-- This document defines the 1.1 version of the CGI interface
|
|
||||||
-- ("CGI/1.1").
|
|
||||||
--
|
|
||||||
-- Servers MUST provide this metavariable to scripts.
|
|
||||||
--
|
|
||||||
-- The version of the CGI specification to which this server
|
|
||||||
-- complies. Syntax:
|
|
||||||
--
|
|
||||||
-- GATEWAY_INTERFACE = "CGI" "/" 1*digit "." 1*digit
|
|
||||||
--
|
|
||||||
-- Note that the major and minor numbers are treated as separate
|
|
||||||
-- integers and that each may be incremented higher than a single
|
|
||||||
-- digit. Thus CGI/2.4 is a lower version than CGI/2.13 which in
|
|
||||||
-- turn is lower than CGI/12.3. Leading zeros must be ignored by
|
|
||||||
-- scripts and should never be generated by servers.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
path_info: STRING assign update_path_info
|
|
||||||
-- The PATH_INFO metavariable specifies a path to be interpreted
|
|
||||||
-- by the CGI script. It identifies the resource or sub-resource
|
|
||||||
-- to be returned by the CGI script, and it is derived from the
|
|
||||||
-- portion of the URI path following the script name but
|
|
||||||
-- preceding any query data. The syntax and semantics are similar
|
|
||||||
-- to a decoded HTTP URL 'path' token (defined in RFC 2396 [4]),
|
|
||||||
-- with the exception that a PATH_INFO of "/" represents a single
|
|
||||||
-- void path segment.
|
|
||||||
--
|
|
||||||
-- PATH_INFO = "" | ( "/" path )
|
|
||||||
-- path = segment *( "/" segment )
|
|
||||||
-- segment = *pchar
|
|
||||||
-- pchar = <any CHAR except "/">
|
|
||||||
--
|
|
||||||
-- The PATH_INFO string is the trailing part of the <path>
|
|
||||||
-- component of the Script-URI (see section 3.2) that follows the
|
|
||||||
-- SCRIPT_NAME portion of the path.
|
|
||||||
--
|
|
||||||
-- Servers MAY impose their own restrictions and limitations on
|
|
||||||
-- what values they will accept for PATH_INFO, and MAY reject or
|
|
||||||
-- edit any values they consider objectionable before passing
|
|
||||||
-- them to the script.
|
|
||||||
--
|
|
||||||
-- Servers MUST make this URI component available to CGI scripts.
|
|
||||||
-- The PATH_INFO value is case-sensitive, and the server MUST
|
|
||||||
-- preserve the case of the PATH_INFO element of the URI when
|
|
||||||
-- making it available to scripts.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
path_translated: detachable STRING
|
|
||||||
-- PATH_TRANSLATED is derived by taking any path-info component
|
|
||||||
-- 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
|
|
||||||
-- performing any virtual-to-physical translation appropriate to
|
|
||||||
-- map it onto the server's document repository structure. If the
|
|
||||||
-- request URI includes no path-info component, the
|
|
||||||
-- PATH_TRANSLATED metavariable SHOULD NOT be defined.
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- PATH_TRANSLATED = *CHAR
|
|
||||||
--
|
|
||||||
-- For a request such as the following:
|
|
||||||
--
|
|
||||||
-- http://somehost.com/cgi-bin/somescript/this%2eis%2epath%2einfo
|
|
||||||
--
|
|
||||||
-- the PATH_INFO component would be decoded, and the result
|
|
||||||
-- parsed as though it were a request for the following:
|
|
||||||
--
|
|
||||||
-- http://somehost.com/this.is.the.path.info
|
|
||||||
--
|
|
||||||
-- This would then be translated to a location in the server's
|
|
||||||
-- document repository, perhaps a filesystem path something like
|
|
||||||
-- this:
|
|
||||||
--
|
|
||||||
-- /usr/local/www/htdocs/this.is.the.path.info
|
|
||||||
--
|
|
||||||
-- The result of the translation is the value of PATH_TRANSLATED.
|
|
||||||
--
|
|
||||||
-- The value of PATH_TRANSLATED may or may not map to a valid
|
|
||||||
-- repository location. Servers MUST preserve the case of the
|
|
||||||
-- path-info segment if and only if the underlying repository
|
|
||||||
-- supports case-sensitive names. If the repository is only
|
|
||||||
-- case-aware, case-preserving, or case-blind with regard to
|
|
||||||
-- document names, servers are not required to preserve the case
|
|
||||||
-- of the original segment through the translation.
|
|
||||||
--
|
|
||||||
-- The translation algorithm the server uses to derive
|
|
||||||
-- PATH_TRANSLATED is implementation defined; CGI scripts which
|
|
||||||
-- use this variable may suffer limited portability.
|
|
||||||
--
|
|
||||||
-- Servers SHOULD provide this metavariable to scripts if and
|
|
||||||
-- only if the request URI includes a path-info component.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
query_string: STRING
|
|
||||||
-- A URL-encoded string; the <query> part of the Script-URI. (See
|
|
||||||
-- section 3.2.)
|
|
||||||
--
|
|
||||||
-- QUERY_STRING = query-string
|
|
||||||
-- query-string = *uric
|
|
||||||
|
|
||||||
-- The URL syntax for a query string is described in section 3 of
|
|
||||||
-- RFC 2396 [4].
|
|
||||||
--
|
|
||||||
-- Servers MUST supply this value to scripts. The QUERY_STRING
|
|
||||||
-- value is case-sensitive. If the Script-URI does not include a
|
|
||||||
-- query component, the QUERY_STRING metavariable MUST be defined
|
|
||||||
-- as an empty string ("").
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
remote_addr: STRING
|
|
||||||
-- The IP address of the client sending the request to the
|
|
||||||
-- server. This is not necessarily that of the user agent (such
|
|
||||||
-- as if the request came through a proxy).
|
|
||||||
--
|
|
||||||
-- REMOTE_ADDR = hostnumber
|
|
||||||
-- hostnumber = ipv4-address | ipv6-address
|
|
||||||
|
|
||||||
-- The definitions of ipv4-address and ipv6-address are provided
|
|
||||||
-- in Appendix B of RFC 2373 [13].
|
|
||||||
--
|
|
||||||
-- Servers MUST supply this value to scripts.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
remote_host: detachable STRING
|
|
||||||
-- The fully qualified domain name of the client sending the
|
|
||||||
-- request to the server, if available, otherwise NULL. (See
|
|
||||||
-- section 6.1.9.) Fully qualified domain names take the form as
|
|
||||||
-- described in section 3.5 of RFC 1034 [10] and section 2.1 of
|
|
||||||
-- RFC 1123 [5]. Domain names are not case sensitive.
|
|
||||||
--
|
|
||||||
-- Servers SHOULD provide this information to scripts.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
remote_ident: detachable STRING
|
|
||||||
-- The identity information reported about the connection by a
|
|
||||||
-- RFC 1413 [11] request to the remote agent, if available.
|
|
||||||
-- Servers MAY choose not to support this feature, or not to
|
|
||||||
-- request the data for efficiency reasons.
|
|
||||||
--
|
|
||||||
-- REMOTE_IDENT = *CHAR
|
|
||||||
--
|
|
||||||
-- The data returned may be used for authentication purposes, but
|
|
||||||
-- the level of trust reposed in them should be minimal.
|
|
||||||
--
|
|
||||||
-- Servers MAY supply this information to scripts if the RFC1413
|
|
||||||
-- [11] lookup is performed.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
remote_user: detachable STRING
|
|
||||||
-- If the request required authentication using the "Basic"
|
|
||||||
-- mechanism (i.e., the AUTH_TYPE metavariable is set to
|
|
||||||
-- "Basic"), then the value of the REMOTE_USER metavariable is
|
|
||||||
-- set to the user-ID supplied. In all other cases the value of
|
|
||||||
-- this metavariable is undefined.
|
|
||||||
--
|
|
||||||
-- REMOTE_USER = *OCTET
|
|
||||||
--
|
|
||||||
-- This variable is specific to requests made via the HTTP
|
|
||||||
-- protocol.
|
|
||||||
--
|
|
||||||
-- Servers SHOULD provide this metavariable to scripts.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
request_method: STRING
|
|
||||||
-- The REQUEST_METHOD metavariable is set to the method with
|
|
||||||
-- 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
|
|
||||||
-- HTTP/1.1 specification [8].
|
|
||||||
--
|
|
||||||
-- REQUEST_METHOD = http-method
|
|
||||||
-- http-method = "GET" | "HEAD" | "POST" | "PUT" | "DELETE"
|
|
||||||
-- | "OPTIONS" | "TRACE" | extension-method
|
|
||||||
-- extension-method = token
|
|
||||||
--
|
|
||||||
-- The method is case sensitive. CGI/1.1 servers MAY choose to
|
|
||||||
-- process some methods directly rather than passing them to
|
|
||||||
-- scripts.
|
|
||||||
--
|
|
||||||
-- This variable is specific to requests made with HTTP.
|
|
||||||
--
|
|
||||||
-- Servers MUST provide this metavariable to scripts.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
script_name: STRING
|
|
||||||
-- The SCRIPT_NAME metavariable is set to a URL path that could
|
|
||||||
-- identify the CGI script (rather than the script's output). The
|
|
||||||
-- syntax and semantics are identical to a decoded HTTP URL
|
|
||||||
-- 'path' token (see RFC 2396 [4]).
|
|
||||||
--
|
|
||||||
-- SCRIPT_NAME = "" | ( "/" [ path ] )
|
|
||||||
--
|
|
||||||
-- The SCRIPT_NAME string is some leading part of the <path>
|
|
||||||
-- component of the Script-URI derived in some implementation
|
|
||||||
-- defined manner. No PATH_INFO or QUERY_STRING segments (see
|
|
||||||
-- sections 6.1.6 and 6.1.8) are included in the SCRIPT_NAME
|
|
||||||
-- value.
|
|
||||||
--
|
|
||||||
-- Servers MUST provide this metavariable to scripts.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
server_name: STRING
|
|
||||||
-- The SERVER_NAME metavariable is set to the name of the server,
|
|
||||||
-- as derived from the <host> part of the Script-URI (see section
|
|
||||||
-- 3.2).
|
|
||||||
--
|
|
||||||
-- SERVER_NAME = hostname | hostnumber
|
|
||||||
--
|
|
||||||
-- Servers MUST provide this metavariable to scripts.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
server_port: INTEGER
|
|
||||||
-- The SERVER_PORT metavariable is set to the port on which the
|
|
||||||
-- request was received, as used in the <port> part of the
|
|
||||||
-- Script-URI.
|
|
||||||
--
|
|
||||||
-- SERVER_PORT = 1*digit
|
|
||||||
--
|
|
||||||
-- If the <port> portion of the script-URI is blank, the actual
|
|
||||||
-- port number upon which the request was received MUST be
|
|
||||||
-- supplied.
|
|
||||||
--
|
|
||||||
-- Servers MUST provide this metavariable to scripts.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
server_protocol: STRING
|
|
||||||
-- The SERVER_PROTOCOL metavariable is set to the name and
|
|
||||||
-- revision of the information protocol with which the request
|
|
||||||
-- arrived. This is not necessarily the same as the protocol
|
|
||||||
-- version used by the server in its response to the client.
|
|
||||||
--
|
|
||||||
-- SERVER_PROTOCOL = HTTP-Version | extension-version
|
|
||||||
-- | extension-token
|
|
||||||
-- HTTP-Version = "HTTP" "/" 1*digit "." 1*digit
|
|
||||||
-- extension-version = protocol "/" 1*digit "." 1*digit
|
|
||||||
-- protocol = 1*( alpha | digit | "+" | "-" | "." )
|
|
||||||
-- extension-token = token
|
|
||||||
--
|
|
||||||
-- 'protocol' is a version of the <scheme> part of the
|
|
||||||
-- Script-URI, but is not identical to it. For example, the
|
|
||||||
-- scheme of a request may be "https" while the protocol remains
|
|
||||||
-- "http". The protocol is not case sensitive, but by convention,
|
|
||||||
-- 'protocol' is in upper case.
|
|
||||||
--
|
|
||||||
-- A well-known extension token value is "INCLUDED", which
|
|
||||||
-- signals that the current document is being included as part of
|
|
||||||
-- a composite document, rather than being the direct target of
|
|
||||||
-- the client request.
|
|
||||||
--
|
|
||||||
-- Servers MUST provide this metavariable to scripts.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
server_software: STRING
|
|
||||||
-- The SERVER_SOFTWARE metavariable is set to the name and
|
|
||||||
-- version of the information server software answering the
|
|
||||||
-- request (and running the gateway).
|
|
||||||
--
|
|
||||||
-- SERVER_SOFTWARE = 1*product
|
|
||||||
-- product = token [ "/" product-version ]
|
|
||||||
-- product-version = token
|
|
||||||
|
|
||||||
-- Servers MUST provide this metavariable to scripts.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- HTTP_*
|
|
||||||
|
|
||||||
http_accept: detachable STRING
|
|
||||||
-- 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'
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
http_accept_charset: detachable STRING
|
|
||||||
-- Contents of the Accept-Charset: header from the current request, if there is one.
|
|
||||||
-- Example: 'iso-8859-1,*,utf-8'.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
http_accept_encoding: detachable STRING
|
|
||||||
-- Contents of the Accept-Encoding: header from the current request, if there is one.
|
|
||||||
-- Example: 'gzip'.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
http_accept_language: detachable STRING
|
|
||||||
-- Contents of the Accept-Language: header from the current request, if there is one.
|
|
||||||
-- Example: 'en'.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
http_connection: detachable STRING
|
|
||||||
-- Contents of the Connection: header from the current request, if there is one.
|
|
||||||
-- Example: 'Keep-Alive'.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
http_host: detachable STRING
|
|
||||||
-- Contents of the Host: header from the current request, if there is one.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
http_referer: detachable STRING
|
|
||||||
-- 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.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
http_user_agent: detachable STRING
|
|
||||||
-- 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.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
http_authorization: detachable STRING
|
|
||||||
-- Contents of the Authorization: header from the current request, if there is one.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Extra
|
|
||||||
|
|
||||||
request_uri: STRING
|
|
||||||
-- The URI which was given in order to access this page; for instance, '/index.html'.
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
orig_path_info: detachable STRING
|
|
||||||
-- Original version of `path_info' before processed by Current environment
|
|
||||||
deferred
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {EWSGI_REQUEST} -- Element change
|
|
||||||
|
|
||||||
set_orig_path_info (s: STRING)
|
|
||||||
-- Set ORIG_PATH_INFO to `s'
|
|
||||||
require
|
|
||||||
s_attached: s /= Void
|
|
||||||
deferred
|
|
||||||
ensure
|
|
||||||
same_orig_path_info: orig_path_info ~ variable ({EWSGI_ENVIRONMENT_NAMES}.orig_path_info)
|
|
||||||
end
|
|
||||||
|
|
||||||
unset_orig_path_info
|
|
||||||
-- Unset ORIG_PATH_INFO
|
|
||||||
deferred
|
|
||||||
ensure
|
|
||||||
unset: not has_variable ({EWSGI_ENVIRONMENT_NAMES}.orig_path_info)
|
|
||||||
end
|
|
||||||
|
|
||||||
update_path_info (a_path_info: like path_info)
|
|
||||||
-- Updated PATH_INFO
|
|
||||||
deferred
|
|
||||||
ensure
|
|
||||||
same_path_info: path_info ~ variable ({EWSGI_ENVIRONMENT_NAMES}.path_info)
|
|
||||||
end
|
|
||||||
|
|
||||||
invariant
|
|
||||||
server_name_not_empty: not server_name.is_empty
|
|
||||||
server_port_set: server_port /= 0
|
|
||||||
request_method_attached: request_method /= Void
|
|
||||||
path_info_attached: path_info /= Void
|
|
||||||
query_string_attached: query_string /= Void
|
|
||||||
remote_addr_attached: remote_addr /= Void
|
|
||||||
|
|
||||||
path_info_identical: path_info ~ variable ({EWSGI_ENVIRONMENT_NAMES}.path_info)
|
|
||||||
|
|
||||||
;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
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {EWSGI_ENVIRONMENT_NAMES}."
|
|
||||||
legal: "See notice at end of class."
|
|
||||||
status: "See notice at end of class."
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
EWSGI_ENVIRONMENT_NAMES
|
|
||||||
|
|
||||||
feature -- Access
|
|
||||||
|
|
||||||
request_uri: STRING = "REQUEST_URI"
|
|
||||||
|
|
||||||
request_method: STRING = "REQUEST_METHOD"
|
|
||||||
|
|
||||||
query_string: STRING = "QUERY_STRING"
|
|
||||||
|
|
||||||
content_type: STRING = "CONTENT_TYPE"
|
|
||||||
|
|
||||||
content_length: STRING = "CONTENT_LENGTH"
|
|
||||||
|
|
||||||
path_info: STRING = "PATH_INFO"
|
|
||||||
|
|
||||||
path_translated: STRING = "PATH_TRANSLATED"
|
|
||||||
|
|
||||||
http_user_agent: STRING = "HTTP_USER_AGENT"
|
|
||||||
|
|
||||||
http_authorization: STRING = "HTTP_AUTHORIZATION"
|
|
||||||
|
|
||||||
http_host: STRING = "HTTP_HOST"
|
|
||||||
|
|
||||||
http_cookie: STRING = "HTTP_COOKIE"
|
|
||||||
|
|
||||||
http_from: STRING = "HTTP_FROM"
|
|
||||||
|
|
||||||
http_accept: STRING = "HTTP_ACCEPT"
|
|
||||||
|
|
||||||
http_accept_charset: STRING = "HTTP_ACCEPT_CHARSET"
|
|
||||||
|
|
||||||
http_accept_encoding: STRING = "HTTP_ACCEPT_ENCODING"
|
|
||||||
|
|
||||||
http_accept_language: STRING = "HTTP_ACCEPT_LANGUAGE"
|
|
||||||
|
|
||||||
http_connection: STRING = "HTTP_CONNECTION"
|
|
||||||
|
|
||||||
http_referer: STRING = "HTTP_REFERER"
|
|
||||||
|
|
||||||
gateway_interface: STRING = "GATEWAY_INTERFACE"
|
|
||||||
|
|
||||||
auth_type: STRING = "AUTH_TYPE"
|
|
||||||
|
|
||||||
remote_host: STRING = "REMOTE_HOST"
|
|
||||||
|
|
||||||
remote_addr: STRING = "REMOTE_ADDR"
|
|
||||||
|
|
||||||
remote_ident: STRING = "REMOTE_IDENT"
|
|
||||||
|
|
||||||
remote_user: STRING = "REMOTE_USER"
|
|
||||||
|
|
||||||
script_name: STRING = "SCRIPT_NAME"
|
|
||||||
|
|
||||||
server_name: STRING = "SERVER_NAME"
|
|
||||||
|
|
||||||
server_port: STRING = "SERVER_PORT"
|
|
||||||
|
|
||||||
server_protocol: STRING = "SERVER_PROTOCOL"
|
|
||||||
|
|
||||||
server_software: STRING = "SERVER_SOFTWARE"
|
|
||||||
|
|
||||||
feature -- Extra names
|
|
||||||
|
|
||||||
request_time: STRING = "REQUEST_TIME"
|
|
||||||
|
|
||||||
self: STRING = "SELF"
|
|
||||||
|
|
||||||
orig_path_info: STRING = "ORIG_PATH_INFO"
|
|
||||||
|
|
||||||
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
|
|
||||||
@@ -1,292 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {EWSGI_ENVIRONMENT_VARIABLES}."
|
|
||||||
legal: "See notice at end of class."
|
|
||||||
status: "See notice at end of class."
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
EWSGI_ENVIRONMENT_VARIABLES
|
|
||||||
|
|
||||||
inherit
|
|
||||||
EWSGI_ENVIRONMENT
|
|
||||||
redefine
|
|
||||||
update_path_info
|
|
||||||
end
|
|
||||||
|
|
||||||
create
|
|
||||||
make_with_variables
|
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
|
||||||
|
|
||||||
make_with_variables (a_vars: HASH_TABLE [STRING, STRING])
|
|
||||||
-- Fill with variable from `a_vars'
|
|
||||||
local
|
|
||||||
s: detachable STRING
|
|
||||||
do
|
|
||||||
create empty_string.make_empty
|
|
||||||
|
|
||||||
create table.make (a_vars.count)
|
|
||||||
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
|
|
||||||
query_string := variable_or_default ({EWSGI_ENVIRONMENT_NAMES}.query_string, empty_string, False)
|
|
||||||
|
|
||||||
--| REQUEST_METHOD
|
|
||||||
request_method := variable_or_default ({EWSGI_ENVIRONMENT_NAMES}.request_method, empty_string, False)
|
|
||||||
|
|
||||||
--| CONTENT_TYPE
|
|
||||||
s := variable ({EWSGI_ENVIRONMENT_NAMES}.content_type)
|
|
||||||
if s /= Void and then not s.is_empty then
|
|
||||||
content_type := s
|
|
||||||
else
|
|
||||||
content_type := Void
|
|
||||||
end
|
|
||||||
|
|
||||||
--| CONTENT_LENGTH
|
|
||||||
s := variable ({EWSGI_ENVIRONMENT_NAMES}.content_length)
|
|
||||||
content_length := s
|
|
||||||
if s /= Void and then s.is_integer then
|
|
||||||
content_length_value := s.to_integer
|
|
||||||
else
|
|
||||||
--| content_length := 0
|
|
||||||
end
|
|
||||||
|
|
||||||
--| PATH_INFO
|
|
||||||
path_info := variable_or_default ({EWSGI_ENVIRONMENT_NAMES}.path_info, empty_string, False)
|
|
||||||
|
|
||||||
--| SERVER_NAME
|
|
||||||
server_name := variable_or_default ({EWSGI_ENVIRONMENT_NAMES}.server_name, empty_string, False)
|
|
||||||
|
|
||||||
--| SERVER_PORT
|
|
||||||
s := variable ({EWSGI_ENVIRONMENT_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 := variable_or_default ({EWSGI_ENVIRONMENT_NAMES}.script_name, empty_string, False)
|
|
||||||
|
|
||||||
--| REMOTE_ADDR
|
|
||||||
remote_addr := variable_or_default ({EWSGI_ENVIRONMENT_NAMES}.remote_addr, empty_string, False)
|
|
||||||
|
|
||||||
--| REMOTE_HOST
|
|
||||||
remote_host := variable_or_default ({EWSGI_ENVIRONMENT_NAMES}.remote_host, empty_string, False)
|
|
||||||
|
|
||||||
--| REQUEST_URI
|
|
||||||
request_uri := variable_or_default ({EWSGI_ENVIRONMENT_NAMES}.request_uri, empty_string, False)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access
|
|
||||||
|
|
||||||
table: HASH_TABLE [STRING, STRING]
|
|
||||||
|
|
||||||
feature -- Access
|
|
||||||
|
|
||||||
variable (a_name: STRING): detachable STRING
|
|
||||||
do
|
|
||||||
Result := table.item (a_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
has_variable (a_name: STRING): BOOLEAN
|
|
||||||
do
|
|
||||||
Result := table.has_key (a_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {EWSGI_REQUEST, EWSGI_APPLICATION, EWSGI_CONNECTOR} -- Element change
|
|
||||||
|
|
||||||
set_variable (a_name: STRING; a_value: STRING)
|
|
||||||
do
|
|
||||||
table.force (a_value, a_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
unset_variable (a_name: STRING)
|
|
||||||
do
|
|
||||||
table.remove (a_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Common Gateway Interface - 1.1 8 January 1996
|
|
||||||
|
|
||||||
auth_type: detachable STRING
|
|
||||||
|
|
||||||
content_length: detachable STRING
|
|
||||||
|
|
||||||
content_length_value: INTEGER
|
|
||||||
|
|
||||||
content_type: detachable STRING
|
|
||||||
|
|
||||||
gateway_interface: STRING
|
|
||||||
do
|
|
||||||
Result := variable_or_default ({EWSGI_ENVIRONMENT_NAMES}.gateway_interface, "", False)
|
|
||||||
end
|
|
||||||
|
|
||||||
path_info: STRING
|
|
||||||
-- <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 STRING
|
|
||||||
do
|
|
||||||
Result := variable ({EWSGI_ENVIRONMENT_NAMES}.path_translated)
|
|
||||||
end
|
|
||||||
|
|
||||||
query_string: STRING
|
|
||||||
|
|
||||||
remote_addr: STRING
|
|
||||||
|
|
||||||
remote_host: STRING
|
|
||||||
|
|
||||||
remote_ident: detachable STRING
|
|
||||||
do
|
|
||||||
Result := variable ({EWSGI_ENVIRONMENT_NAMES}.remote_ident)
|
|
||||||
end
|
|
||||||
|
|
||||||
remote_user: detachable STRING
|
|
||||||
do
|
|
||||||
Result := variable ({EWSGI_ENVIRONMENT_NAMES}.remote_user)
|
|
||||||
end
|
|
||||||
|
|
||||||
request_method: STRING
|
|
||||||
|
|
||||||
script_name: STRING
|
|
||||||
|
|
||||||
server_name: STRING
|
|
||||||
|
|
||||||
server_port: INTEGER
|
|
||||||
|
|
||||||
server_protocol: STRING
|
|
||||||
do
|
|
||||||
Result := variable_or_default ({EWSGI_ENVIRONMENT_NAMES}.server_protocol, "HTTP/1.0", True)
|
|
||||||
end
|
|
||||||
|
|
||||||
server_software: STRING
|
|
||||||
do
|
|
||||||
Result := variable_or_default ({EWSGI_ENVIRONMENT_NAMES}.server_software, "Unknown Server", True)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- HTTP_*
|
|
||||||
|
|
||||||
http_accept: detachable STRING
|
|
||||||
-- Contents of the Accept: header from the current request, if there is one.
|
|
||||||
do
|
|
||||||
Result := table.item ({EWSGI_ENVIRONMENT_NAMES}.http_accept)
|
|
||||||
end
|
|
||||||
|
|
||||||
http_accept_charset: detachable STRING
|
|
||||||
-- Contents of the Accept-Charset: header from the current request, if there is one.
|
|
||||||
-- Example: 'iso-8859-1,*,utf-8'.
|
|
||||||
do
|
|
||||||
Result := table.item ({EWSGI_ENVIRONMENT_NAMES}.http_accept_charset)
|
|
||||||
end
|
|
||||||
|
|
||||||
http_accept_encoding: detachable STRING
|
|
||||||
-- Contents of the Accept-Encoding: header from the current request, if there is one.
|
|
||||||
-- Example: 'gzip'.
|
|
||||||
do
|
|
||||||
Result := table.item ({EWSGI_ENVIRONMENT_NAMES}.http_accept_encoding)
|
|
||||||
end
|
|
||||||
|
|
||||||
http_accept_language: detachable STRING
|
|
||||||
-- Contents of the Accept-Language: header from the current request, if there is one.
|
|
||||||
-- Example: 'en'.
|
|
||||||
do
|
|
||||||
Result := table.item ({EWSGI_ENVIRONMENT_NAMES}.http_accept_language)
|
|
||||||
end
|
|
||||||
|
|
||||||
http_connection: detachable STRING
|
|
||||||
-- Contents of the Connection: header from the current request, if there is one.
|
|
||||||
-- Example: 'Keep-Alive'.
|
|
||||||
do
|
|
||||||
Result := table.item ({EWSGI_ENVIRONMENT_NAMES}.http_connection)
|
|
||||||
end
|
|
||||||
|
|
||||||
http_host: detachable STRING
|
|
||||||
-- Contents of the Host: header from the current request, if there is one.
|
|
||||||
do
|
|
||||||
Result := table.item ({EWSGI_ENVIRONMENT_NAMES}.http_host)
|
|
||||||
end
|
|
||||||
|
|
||||||
http_referer: detachable STRING
|
|
||||||
-- 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 := table.item ({EWSGI_ENVIRONMENT_NAMES}.http_referer)
|
|
||||||
end
|
|
||||||
|
|
||||||
http_user_agent: detachable STRING
|
|
||||||
-- 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 := table.item ({EWSGI_ENVIRONMENT_NAMES}.http_user_agent)
|
|
||||||
end
|
|
||||||
|
|
||||||
http_authorization: detachable STRING
|
|
||||||
-- Contents of the Authorization: header from the current request, if there is one.
|
|
||||||
do
|
|
||||||
Result := table.item ({EWSGI_ENVIRONMENT_NAMES}.http_authorization)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Extra
|
|
||||||
|
|
||||||
request_uri: STRING
|
|
||||||
-- The URI which was given in order to access this page; for instance, '/index.html'.
|
|
||||||
|
|
||||||
orig_path_info: detachable STRING
|
|
||||||
-- Original version of `path_info' before processed by Current environment
|
|
||||||
|
|
||||||
feature {EWSGI_REQUEST} -- Update
|
|
||||||
|
|
||||||
set_orig_path_info (s: STRING)
|
|
||||||
do
|
|
||||||
orig_path_info := s
|
|
||||||
set_variable ({EWSGI_ENVIRONMENT_NAMES}.orig_path_info, s)
|
|
||||||
end
|
|
||||||
|
|
||||||
unset_orig_path_info
|
|
||||||
do
|
|
||||||
orig_path_info := Void
|
|
||||||
unset_variable ({EWSGI_ENVIRONMENT_NAMES}.orig_path_info)
|
|
||||||
end
|
|
||||||
|
|
||||||
update_path_info (a_path_info: like path_info)
|
|
||||||
do
|
|
||||||
path_info := a_path_info
|
|
||||||
set_variable ({EWSGI_ENVIRONMENT_NAMES}.path_info, a_path_info)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
|
||||||
|
|
||||||
empty_string: STRING
|
|
||||||
-- 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
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
note
|
|
||||||
description: "[
|
|
||||||
Variables/field related to the current request.
|
|
||||||
]"
|
|
||||||
legal: "See notice at end of class."
|
|
||||||
status: "See notice at end of class."
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
EWSGI_REQUEST_VARIABLES
|
|
||||||
|
|
||||||
inherit
|
|
||||||
EWSGI_VARIABLES [STRING_32]
|
|
||||||
|
|
||||||
create
|
|
||||||
make,
|
|
||||||
make_from_urlencoded
|
|
||||||
|
|
||||||
feature -- Initialization
|
|
||||||
|
|
||||||
make (n: INTEGER)
|
|
||||||
do
|
|
||||||
create table.make (n)
|
|
||||||
table.compare_objects
|
|
||||||
end
|
|
||||||
|
|
||||||
make_from_urlencoded (a_content: STRING; decoding: BOOLEAN)
|
|
||||||
do
|
|
||||||
make (a_content.occurrences ('&') + 1)
|
|
||||||
import_urlencoded (a_content, decoding)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Status report
|
|
||||||
|
|
||||||
count: INTEGER
|
|
||||||
-- Variables count
|
|
||||||
do
|
|
||||||
Result := table.count
|
|
||||||
end
|
|
||||||
|
|
||||||
variable (a_name: STRING): detachable STRING_32
|
|
||||||
do
|
|
||||||
Result := table.item (a_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
has_variable (a_name: STRING): BOOLEAN
|
|
||||||
do
|
|
||||||
Result := table.has (a_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {EWSGI_REQUEST, EWSGI_APPLICATION, EWSGI_CONNECTOR} -- Element change
|
|
||||||
|
|
||||||
set_variable (a_name: STRING; a_value: STRING_32)
|
|
||||||
do
|
|
||||||
table.force (a_value, a_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
unset_variable (a_name: STRING)
|
|
||||||
do
|
|
||||||
table.remove (a_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Import urlencoded
|
|
||||||
|
|
||||||
import_urlencoded (a_content: STRING; decoding: BOOLEAN)
|
|
||||||
-- Import `a_content'
|
|
||||||
local
|
|
||||||
n, p, i, j: INTEGER
|
|
||||||
s: STRING
|
|
||||||
l_name,l_value: STRING_32
|
|
||||||
do
|
|
||||||
n := a_content.count
|
|
||||||
if n > 0 then
|
|
||||||
from
|
|
||||||
p := 1
|
|
||||||
until
|
|
||||||
p = 0
|
|
||||||
loop
|
|
||||||
i := a_content.index_of ('&', p)
|
|
||||||
if i = 0 then
|
|
||||||
s := a_content.substring (p, n)
|
|
||||||
p := 0
|
|
||||||
else
|
|
||||||
s := a_content.substring (p, i - 1)
|
|
||||||
p := i + 1
|
|
||||||
end
|
|
||||||
if not s.is_empty then
|
|
||||||
j := s.index_of ('=', 1)
|
|
||||||
if j > 0 then
|
|
||||||
l_name := s.substring (1, j - 1)
|
|
||||||
l_value := s.substring (j + 1, s.count)
|
|
||||||
if decoding then
|
|
||||||
l_name := url_encoder.decoded_string (l_name)
|
|
||||||
l_value := url_encoder.decoded_string (l_value)
|
|
||||||
end
|
|
||||||
add_variable (l_value, l_name)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access: table
|
|
||||||
|
|
||||||
new_cursor: HASH_TABLE_ITERATION_CURSOR [STRING_32, STRING_32]
|
|
||||||
-- Fresh cursor associated with current structure
|
|
||||||
do
|
|
||||||
create Result.make (table)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {EWSGI_REQUEST} -- Element change
|
|
||||||
|
|
||||||
add_variable (v: STRING_32; k: STRING_32)
|
|
||||||
-- Added `k,v' to variables table
|
|
||||||
-- Not exported to common client
|
|
||||||
-- Simulate Read Only Access
|
|
||||||
require
|
|
||||||
k_attached: k /= Void
|
|
||||||
v_attached: v /= Void
|
|
||||||
do
|
|
||||||
table.force (v, k)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {EWSGI_REQUEST} -- Element change
|
|
||||||
|
|
||||||
table: HASH_TABLE [STRING_32, STRING_32]
|
|
||||||
-- Variables table
|
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
|
||||||
|
|
||||||
url_encoder: URL_ENCODER
|
|
||||||
once
|
|
||||||
create Result
|
|
||||||
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
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {GW_UPLOADED_FILE}."
|
|
||||||
author: ""
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
EWSGI_UPLOADED_FILE_DATA
|
|
||||||
|
|
||||||
create
|
|
||||||
make
|
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
|
||||||
|
|
||||||
make (n: like name; t: like content_type; s: like size)
|
|
||||||
do
|
|
||||||
name := n
|
|
||||||
content_type := t
|
|
||||||
size := s
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access
|
|
||||||
|
|
||||||
name: STRING
|
|
||||||
-- original filename
|
|
||||||
|
|
||||||
content_type: STRING
|
|
||||||
-- Content type
|
|
||||||
|
|
||||||
size: INTEGER
|
|
||||||
-- Size of uploaded file
|
|
||||||
|
|
||||||
tmp_name: detachable STRING
|
|
||||||
-- Filename of tmp file
|
|
||||||
|
|
||||||
tmp_basename: detachable STRING
|
|
||||||
-- Basename of tmp file
|
|
||||||
|
|
||||||
feature -- Basic operation
|
|
||||||
|
|
||||||
move_to (a_destination: STRING): BOOLEAN
|
|
||||||
-- Move current uploaded file to `a_destination'
|
|
||||||
require
|
|
||||||
has_no_error: not has_error
|
|
||||||
local
|
|
||||||
f: RAW_FILE
|
|
||||||
do
|
|
||||||
if attached tmp_name as n then
|
|
||||||
create f.make (n)
|
|
||||||
if f.exists then
|
|
||||||
f.change_name (a_destination)
|
|
||||||
Result := True
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Status
|
|
||||||
|
|
||||||
has_error: BOOLEAN
|
|
||||||
-- Has error during uploading
|
|
||||||
do
|
|
||||||
Result := error /= 0
|
|
||||||
end
|
|
||||||
|
|
||||||
error: INTEGER
|
|
||||||
-- Eventual error code
|
|
||||||
--| no error => 0
|
|
||||||
|
|
||||||
feature -- Element change
|
|
||||||
|
|
||||||
set_error (e: like error)
|
|
||||||
-- Set `error' to `e'
|
|
||||||
do
|
|
||||||
error := e
|
|
||||||
end
|
|
||||||
|
|
||||||
set_tmp_name (n: like tmp_name)
|
|
||||||
-- Set `tmp_name' to `n'
|
|
||||||
do
|
|
||||||
tmp_name := n
|
|
||||||
end
|
|
||||||
|
|
||||||
set_tmp_basename (n: like tmp_basename)
|
|
||||||
-- Set `tmp_basename' to `n'
|
|
||||||
do
|
|
||||||
tmp_basename := n
|
|
||||||
end
|
|
||||||
|
|
||||||
invariant
|
|
||||||
|
|
||||||
valid_tmp_name: not has_error implies attached tmp_name as n and then not n.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
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
note
|
note
|
||||||
description: "[
|
description: "[
|
||||||
EWSGI interface to represent the Request
|
Request instanciated from a hash_table of meta variables
|
||||||
|
|
||||||
]"
|
]"
|
||||||
specification: "EWSGI specification https://github.com/Eiffel-World/Eiffel-Web-Framework/wiki/EWSGI-specification"
|
specification: "EWSGI specification https://github.com/Eiffel-World/Eiffel-Web-Framework/wiki/EWSGI-specification"
|
||||||
legal: "See notice at end of class."
|
legal: "See notice at end of class."
|
||||||
@@ -10,21 +9,23 @@ note
|
|||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
class
|
class
|
||||||
EWSGI_REQUEST
|
WGI_REQUEST_FROM_TABLE
|
||||||
|
|
||||||
|
inherit
|
||||||
|
WGI_REQUEST
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
make (env: EWSGI_ENVIRONMENT; a_input: like input)
|
make (a_vars: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]; a_input: like input)
|
||||||
require
|
require
|
||||||
env_attached: env /= Void
|
vars_attached: a_vars /= Void
|
||||||
do
|
do
|
||||||
create error_handler.make
|
create error_handler.make
|
||||||
input := a_input
|
input := a_input
|
||||||
environment := env
|
set_meta_parameters (a_vars)
|
||||||
content_length := env.content_length_value
|
|
||||||
create uploaded_files.make (0)
|
create uploaded_files.make (0)
|
||||||
|
|
||||||
raw_post_data_recorded := True
|
raw_post_data_recorded := True
|
||||||
@@ -33,26 +34,93 @@ feature {NONE} -- Initialization
|
|||||||
analyze
|
analyze
|
||||||
end
|
end
|
||||||
|
|
||||||
|
set_meta_parameters (a_vars: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8])
|
||||||
|
-- Fill with variable from `a_vars'
|
||||||
|
local
|
||||||
|
s: like meta_variable
|
||||||
|
table: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]
|
||||||
|
do
|
||||||
|
create {STRING_32} empty_string.make_empty
|
||||||
|
|
||||||
|
create table.make (a_vars.count)
|
||||||
|
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
|
||||||
|
query_string := meta_parameter_or_default ({WGI_META_NAMES}.query_string, empty_string, False)
|
||||||
|
|
||||||
|
--| REQUEST_METHOD
|
||||||
|
request_method := meta_parameter_or_default ({WGI_META_NAMES}.request_method, empty_string, False)
|
||||||
|
|
||||||
|
--| CONTENT_TYPE
|
||||||
|
s := meta_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
|
||||||
|
s := meta_variable ({WGI_META_NAMES}.content_length)
|
||||||
|
content_length := s
|
||||||
|
if s /= Void and then s.is_natural_64 then
|
||||||
|
content_length_value := s.to_natural_64
|
||||||
|
else
|
||||||
|
--| content_length := 0
|
||||||
|
end
|
||||||
|
|
||||||
|
--| PATH_INFO
|
||||||
|
path_info := meta_parameter_or_default ({WGI_META_NAMES}.path_info, empty_string, False)
|
||||||
|
|
||||||
|
--| SERVER_NAME
|
||||||
|
server_name := meta_parameter_or_default ({WGI_META_NAMES}.server_name, empty_string, False)
|
||||||
|
|
||||||
|
--| SERVER_PORT
|
||||||
|
s := meta_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_parameter_or_default ({WGI_META_NAMES}.script_name, empty_string, False)
|
||||||
|
|
||||||
|
--| REMOTE_ADDR
|
||||||
|
remote_addr := meta_parameter_or_default ({WGI_META_NAMES}.remote_addr, empty_string, False)
|
||||||
|
|
||||||
|
--| REMOTE_HOST
|
||||||
|
remote_host := meta_parameter_or_default ({WGI_META_NAMES}.remote_host, empty_string, False)
|
||||||
|
|
||||||
|
--| REQUEST_URI
|
||||||
|
request_uri := meta_parameter_or_default ({WGI_META_NAMES}.request_uri, empty_string, False)
|
||||||
|
end
|
||||||
|
|
||||||
initialize
|
initialize
|
||||||
-- Specific initialization
|
-- Specific initialization
|
||||||
local
|
local
|
||||||
p: INTEGER
|
p: INTEGER
|
||||||
env: like environment
|
|
||||||
do
|
do
|
||||||
env := environment
|
|
||||||
--| Here one can set its own environment entries if needed
|
--| Here one can set its own environment entries if needed
|
||||||
|
|
||||||
--| do not use `force', to avoid overwriting existing variable
|
--| do not use `force', to avoid overwriting existing variable
|
||||||
if attached env.request_uri as rq_uri then
|
if attached request_uri as rq_uri then
|
||||||
p := rq_uri.index_of ('?', 1)
|
p := rq_uri.index_of ('?', 1)
|
||||||
if p > 0 then
|
if p > 0 then
|
||||||
env.set_variable (rq_uri.substring (1, p-1), {EWSGI_ENVIRONMENT_NAMES}.self)
|
set_meta_variable (rq_uri.substring (1, p-1), {WGI_META_NAMES}.self)
|
||||||
else
|
else
|
||||||
env.set_variable (rq_uri, {EWSGI_ENVIRONMENT_NAMES}.self)
|
set_meta_variable (rq_uri, {WGI_META_NAMES}.self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if env.variable ({EWSGI_ENVIRONMENT_NAMES}.request_time) = Void then
|
if meta_variable ({WGI_META_NAMES}.request_time) = Void then
|
||||||
env.set_variable (date_time_utilities.unix_time_stamp (Void).out, {EWSGI_ENVIRONMENT_NAMES}.request_time)
|
set_meta_variable (date_time_utilities.unix_time_stamp (Void).out, {WGI_META_NAMES}.request_time)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -62,15 +130,10 @@ feature {NONE} -- Initialization
|
|||||||
extract_variables
|
extract_variables
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access: Input
|
|
||||||
|
|
||||||
input: EWSGI_INPUT_STREAM
|
|
||||||
-- Server input channel
|
|
||||||
|
|
||||||
feature -- Status
|
feature -- Status
|
||||||
|
|
||||||
raw_post_data_recorded: BOOLEAN assign set_raw_post_data_recorded
|
raw_post_data_recorded: BOOLEAN assign set_raw_post_data_recorded
|
||||||
-- Record RAW POST DATA in environment variables
|
-- Record RAW POST DATA in meta parameters
|
||||||
-- otherwise just forget about it
|
-- otherwise just forget about it
|
||||||
-- Default: true
|
-- Default: true
|
||||||
--| warning: you might keep in memory big amount of memory ...
|
--| warning: you might keep in memory big amount of memory ...
|
||||||
@@ -86,37 +149,261 @@ feature -- Error handling
|
|||||||
-- Error handler
|
-- Error handler
|
||||||
-- By default initialized to new handler
|
-- By default initialized to new handler
|
||||||
|
|
||||||
feature -- Access: environment variables
|
feature -- Access: Input
|
||||||
|
|
||||||
environment: EWSGI_ENVIRONMENT
|
input: WGI_INPUT_STREAM
|
||||||
-- Environment variables
|
-- Server input channel
|
||||||
|
|
||||||
environment_variable (a_name: STRING): detachable STRING
|
feature -- Access extra information
|
||||||
-- Environment variable related to `a_name'
|
|
||||||
require
|
request_time: detachable DATE_TIME
|
||||||
a_name_valid: a_name /= Void and then not a_name.is_empty
|
-- Request time (UTC)
|
||||||
do
|
do
|
||||||
Result := environment.variable (a_name)
|
if
|
||||||
|
attached meta_variable ({WGI_META_NAMES}.request_time) as t and then
|
||||||
|
t.is_integer_64
|
||||||
|
then
|
||||||
|
Result := date_time_utilities.unix_time_stamp_to_date_time (t.to_integer_64)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
content_length: INTEGER
|
feature -- Access: CGI meta parameters
|
||||||
-- Extracted Content-Length value
|
|
||||||
|
|
||||||
feature -- URL parameters
|
meta_variables: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]
|
||||||
|
-- CGI Environment parameters
|
||||||
|
|
||||||
parameters: EWSGI_REQUEST_VARIABLES
|
meta_variable (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
|
-- CGI meta variable related to `a_name'
|
||||||
|
do
|
||||||
|
Result := meta_variables.item (a_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
meta_parameter_or_default (a_name: READABLE_STRING_GENERAL; a_default: READABLE_STRING_32; use_default_when_empty: BOOLEAN): READABLE_STRING_32
|
||||||
|
-- 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 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
|
||||||
|
|
||||||
|
set_meta_variable (a_name: READABLE_STRING_GENERAL; a_value: READABLE_STRING_32)
|
||||||
|
do
|
||||||
|
meta_variables.force (a_value, a_name)
|
||||||
|
ensure
|
||||||
|
param_set: meta_variable (a_name) ~ a_value
|
||||||
|
end
|
||||||
|
|
||||||
|
unset_meta_variable (a_name: READABLE_STRING_GENERAL)
|
||||||
|
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_32
|
||||||
|
|
||||||
|
content_length: detachable READABLE_STRING_32
|
||||||
|
|
||||||
|
content_length_value: NATURAL_64
|
||||||
|
|
||||||
|
content_type: detachable READABLE_STRING_32
|
||||||
|
|
||||||
|
gateway_interface: READABLE_STRING_32
|
||||||
|
do
|
||||||
|
Result := meta_parameter_or_default ({WGI_META_NAMES}.gateway_interface, "", False)
|
||||||
|
end
|
||||||
|
|
||||||
|
path_info: READABLE_STRING_32
|
||||||
|
-- <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_32
|
||||||
|
do
|
||||||
|
Result := meta_variable ({WGI_META_NAMES}.path_translated)
|
||||||
|
end
|
||||||
|
|
||||||
|
query_string: READABLE_STRING_32
|
||||||
|
|
||||||
|
remote_addr: READABLE_STRING_32
|
||||||
|
|
||||||
|
remote_host: READABLE_STRING_32
|
||||||
|
|
||||||
|
remote_ident: detachable READABLE_STRING_32
|
||||||
|
do
|
||||||
|
Result := meta_variable ({WGI_META_NAMES}.remote_ident)
|
||||||
|
end
|
||||||
|
|
||||||
|
remote_user: detachable READABLE_STRING_32
|
||||||
|
do
|
||||||
|
Result := meta_variable ({WGI_META_NAMES}.remote_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
request_method: READABLE_STRING_32
|
||||||
|
|
||||||
|
script_name: READABLE_STRING_32
|
||||||
|
|
||||||
|
server_name: READABLE_STRING_32
|
||||||
|
|
||||||
|
server_port: INTEGER
|
||||||
|
|
||||||
|
server_protocol: READABLE_STRING_32
|
||||||
|
do
|
||||||
|
Result := meta_parameter_or_default ({WGI_META_NAMES}.server_protocol, "HTTP/1.0", True)
|
||||||
|
end
|
||||||
|
|
||||||
|
server_software: READABLE_STRING_32
|
||||||
|
do
|
||||||
|
Result := meta_parameter_or_default ({WGI_META_NAMES}.server_software, "Unknown Server", True)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access: HTTP_* CGI meta parameters - 1.1
|
||||||
|
|
||||||
|
http_accept: detachable READABLE_STRING_32
|
||||||
|
-- Contents of the Accept: header from the current request, if there is one.
|
||||||
|
do
|
||||||
|
Result := meta_variable ({WGI_META_NAMES}.http_accept)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_accept_charset: detachable READABLE_STRING_32
|
||||||
|
-- Contents of the Accept-Charset: header from the current request, if there is one.
|
||||||
|
-- Example: 'iso-8859-1,*,utf-8'.
|
||||||
|
do
|
||||||
|
Result := meta_variable ({WGI_META_NAMES}.http_accept_charset)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_accept_encoding: detachable READABLE_STRING_32
|
||||||
|
-- Contents of the Accept-Encoding: header from the current request, if there is one.
|
||||||
|
-- Example: 'gzip'.
|
||||||
|
do
|
||||||
|
Result := meta_variable ({WGI_META_NAMES}.http_accept_encoding)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_accept_language: detachable READABLE_STRING_32
|
||||||
|
-- Contents of the Accept-Language: header from the current request, if there is one.
|
||||||
|
-- Example: 'en'.
|
||||||
|
do
|
||||||
|
Result := meta_variable ({WGI_META_NAMES}.http_accept_language)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_connection: detachable READABLE_STRING_32
|
||||||
|
-- Contents of the Connection: header from the current request, if there is one.
|
||||||
|
-- Example: 'Keep-Alive'.
|
||||||
|
do
|
||||||
|
Result := meta_variable ({WGI_META_NAMES}.http_connection)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_host: detachable READABLE_STRING_32
|
||||||
|
-- Contents of the Host: header from the current request, if there is one.
|
||||||
|
do
|
||||||
|
Result := meta_variable ({WGI_META_NAMES}.http_host)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_referer: detachable READABLE_STRING_32
|
||||||
|
-- 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_variable ({WGI_META_NAMES}.http_referer)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_user_agent: detachable READABLE_STRING_32
|
||||||
|
-- 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_variable ({WGI_META_NAMES}.http_user_agent)
|
||||||
|
end
|
||||||
|
|
||||||
|
http_authorization: detachable READABLE_STRING_32
|
||||||
|
-- Contents of the Authorization: header from the current request, if there is one.
|
||||||
|
do
|
||||||
|
Result := meta_variable ({WGI_META_NAMES}.http_authorization)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access: Extension to CGI meta parameters - 1.1
|
||||||
|
|
||||||
|
request_uri: READABLE_STRING_32
|
||||||
|
-- The URI which was given in order to access this page; for instance, '/index.html'.
|
||||||
|
|
||||||
|
orig_path_info: detachable READABLE_STRING_32
|
||||||
|
-- Original version of `path_info' before processed by Current environment
|
||||||
|
|
||||||
|
feature {NONE} -- Element change: CGI meta parameter related to PATH_INFO
|
||||||
|
|
||||||
|
set_orig_path_info (s: READABLE_STRING_32)
|
||||||
|
-- Set ORIG_PATH_INFO to `s'
|
||||||
|
require
|
||||||
|
s_attached: s /= Void
|
||||||
|
do
|
||||||
|
orig_path_info := s
|
||||||
|
set_meta_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 -- Query parameters
|
||||||
|
|
||||||
|
query_parameters: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]
|
||||||
-- Variables extracted from QUERY_STRING
|
-- Variables extracted from QUERY_STRING
|
||||||
local
|
local
|
||||||
vars: like internal_parameters
|
vars: like internal_query_parameters
|
||||||
p,e: INTEGER
|
p,e: INTEGER
|
||||||
rq_uri: like environment.request_uri
|
rq_uri: like request_uri
|
||||||
s: detachable STRING
|
s: detachable STRING
|
||||||
do
|
do
|
||||||
vars := internal_parameters
|
vars := internal_query_parameters
|
||||||
if vars = Void then
|
if vars = Void then
|
||||||
s := environment.query_string
|
s := query_string
|
||||||
if s = Void then
|
if s = Void then
|
||||||
rq_uri := environment.request_uri
|
rq_uri := request_uri
|
||||||
p := rq_uri.index_of ('?', 1)
|
p := rq_uri.index_of ('?', 1)
|
||||||
if p > 0 then
|
if p > 0 then
|
||||||
e := rq_uri.index_of ('#', p + 1)
|
e := rq_uri.index_of ('#', p + 1)
|
||||||
@@ -128,71 +415,110 @@ feature -- URL parameters
|
|||||||
s := rq_uri.substring (p+1, e)
|
s := rq_uri.substring (p+1, e)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if s /= Void and then not s.is_empty then
|
vars := urlencoded_parameters (s, True)
|
||||||
create vars.make_from_urlencoded (s, True)
|
internal_query_parameters := vars
|
||||||
else
|
|
||||||
create vars.make (0)
|
|
||||||
end
|
|
||||||
internal_parameters := vars
|
|
||||||
end
|
end
|
||||||
Result := vars
|
Result := vars
|
||||||
end
|
end
|
||||||
|
|
||||||
parameter (a_name: STRING): detachable STRING_32
|
query_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
-- Parameter for name `n'.
|
-- Parameter for name `n'.
|
||||||
require
|
|
||||||
a_name_valid: a_name /= Void and then not a_name.is_empty
|
|
||||||
do
|
do
|
||||||
Result := parameters.variable (a_name)
|
Result := query_parameters.item (a_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Query parameters: implementation
|
||||||
|
|
||||||
|
urlencoded_parameters (a_content: detachable READABLE_STRING_8; decoding: BOOLEAN): HASH_TABLE [READABLE_STRING_32, STRING]
|
||||||
|
-- Import `a_content'
|
||||||
|
local
|
||||||
|
n, p, i, j: INTEGER
|
||||||
|
s: STRING
|
||||||
|
l_name,l_value: STRING_32
|
||||||
|
do
|
||||||
|
if a_content = Void then
|
||||||
|
create Result.make (0)
|
||||||
|
else
|
||||||
|
n := a_content.count
|
||||||
|
if n = 0 then
|
||||||
|
create Result.make (0)
|
||||||
|
else
|
||||||
|
create Result.make (3)
|
||||||
|
from
|
||||||
|
p := 1
|
||||||
|
until
|
||||||
|
p = 0
|
||||||
|
loop
|
||||||
|
i := a_content.index_of ('&', p)
|
||||||
|
if i = 0 then
|
||||||
|
s := a_content.substring (p, n)
|
||||||
|
p := 0
|
||||||
|
else
|
||||||
|
s := a_content.substring (p, i - 1)
|
||||||
|
p := i + 1
|
||||||
|
end
|
||||||
|
if not s.is_empty then
|
||||||
|
j := s.index_of ('=', 1)
|
||||||
|
if j > 0 then
|
||||||
|
l_name := s.substring (1, j - 1)
|
||||||
|
l_value := s.substring (j + 1, s.count)
|
||||||
|
if decoding then
|
||||||
|
l_name := url_encoder.decoded_string (l_name)
|
||||||
|
l_value := url_encoder.decoded_string (l_value)
|
||||||
|
end
|
||||||
|
Result.force (l_value, l_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Form fields and related
|
feature -- Form fields and related
|
||||||
|
|
||||||
form_fields: EWSGI_REQUEST_VARIABLES
|
form_data_parameters: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]
|
||||||
-- Variables sent by POST request
|
-- Variables sent by POST request
|
||||||
local
|
local
|
||||||
vars: like internal_form_fields
|
vars: like internal_form_data_parameters
|
||||||
s: STRING
|
s: STRING
|
||||||
n: INTEGER
|
n: NATURAL_64
|
||||||
l_type: detachable STRING
|
l_type: like content_type
|
||||||
do
|
do
|
||||||
vars := internal_form_fields
|
vars := internal_form_data_parameters
|
||||||
if vars = Void then
|
if vars = Void then
|
||||||
n := content_length
|
n := content_length_value
|
||||||
if n > 0 then
|
if n > 0 then
|
||||||
l_type := environment.content_type
|
l_type := content_type
|
||||||
if
|
if
|
||||||
l_type /= Void and then
|
l_type /= Void and then
|
||||||
l_type.starts_with ({HTTP_CONSTANTS}.multipart_form)
|
l_type.starts_with ({HTTP_CONSTANTS}.multipart_form)
|
||||||
then
|
then
|
||||||
create vars.make (5)
|
create vars.make (5)
|
||||||
--| FIXME: optimization ... fetch the input data progressively, otherwise we might run out of memory ...
|
--| FIXME: optimization ... fetch the input data progressively, otherwise we might run out of memory ...
|
||||||
s := form_input_data (n)
|
s := form_input_data (n.to_integer_32) --| FIXME truncated from NAT64 to INT32
|
||||||
analyze_multipart_form (l_type, s, vars)
|
analyze_multipart_form (l_type, s, vars)
|
||||||
else
|
else
|
||||||
s := form_input_data (n)
|
s := form_input_data (n.to_integer_32) --| FIXME truncated from NAT64 to INT32
|
||||||
create vars.make_from_urlencoded (s, True)
|
vars := urlencoded_parameters (s, True)
|
||||||
end
|
end
|
||||||
if raw_post_data_recorded then
|
if raw_post_data_recorded then
|
||||||
vars.add_variable (s, "RAW_POST_DATA")
|
vars.force (s, "RAW_POST_DATA")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
create vars.make (0)
|
create vars.make (0)
|
||||||
end
|
end
|
||||||
internal_form_fields := vars
|
internal_form_data_parameters := vars
|
||||||
end
|
end
|
||||||
Result := vars
|
Result := vars
|
||||||
end
|
end
|
||||||
|
|
||||||
form_field (a_name: STRING): detachable STRING_32
|
form_data_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
-- Field for name `a_name'.
|
-- Field for name `a_name'.
|
||||||
require
|
|
||||||
a_name_valid: a_name /= Void and then not a_name.is_empty
|
|
||||||
do
|
do
|
||||||
Result := form_fields.variable (a_name)
|
Result := form_data_parameters.item (a_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
uploaded_files: HASH_TABLE [EWSGI_UPLOADED_FILE_DATA, STRING]
|
uploaded_files: HASH_TABLE [WGI_UPLOADED_FILE_DATA, STRING]
|
||||||
-- Table of uploaded files information
|
-- Table of uploaded files information
|
||||||
--| name: original path from the user
|
--| name: original path from the user
|
||||||
--| type: content type
|
--| type: content type
|
||||||
@@ -203,45 +529,8 @@ feature -- Form fields and related
|
|||||||
|
|
||||||
feature -- Cookies
|
feature -- Cookies
|
||||||
|
|
||||||
cookies_variables: HASH_TABLE [STRING, STRING]
|
cookies: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]
|
||||||
-- Expanded cookies variable
|
-- Expanded cookies variable
|
||||||
local
|
|
||||||
l_cookies: like cookies
|
|
||||||
do
|
|
||||||
l_cookies := cookies
|
|
||||||
create Result.make (l_cookies.count)
|
|
||||||
from
|
|
||||||
l_cookies.start
|
|
||||||
until
|
|
||||||
l_cookies.after
|
|
||||||
loop
|
|
||||||
if attached l_cookies.item_for_iteration.variables as vars then
|
|
||||||
from
|
|
||||||
vars.start
|
|
||||||
until
|
|
||||||
vars.after
|
|
||||||
loop
|
|
||||||
Result.force (vars.item_for_iteration, vars.key_for_iteration)
|
|
||||||
vars.forth
|
|
||||||
end
|
|
||||||
else
|
|
||||||
check same_name: l_cookies.key_for_iteration.same_string (l_cookies.item_for_iteration.name) end
|
|
||||||
Result.force (l_cookies.item_for_iteration.value, l_cookies.key_for_iteration)
|
|
||||||
end
|
|
||||||
l_cookies.forth
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
cookies_variable (a_name: STRING): detachable STRING
|
|
||||||
-- Field for name `a_name'.
|
|
||||||
require
|
|
||||||
a_name_valid: a_name /= Void and then not a_name.is_empty
|
|
||||||
do
|
|
||||||
Result := cookies_variables.item (a_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
cookies: HASH_TABLE [EWSGI_COOKIE, STRING]
|
|
||||||
-- Cookies Information
|
|
||||||
local
|
local
|
||||||
i,j,p,n: INTEGER
|
i,j,p,n: INTEGER
|
||||||
l_cookies: like internal_cookies
|
l_cookies: like internal_cookies
|
||||||
@@ -249,7 +538,7 @@ feature -- Cookies
|
|||||||
do
|
do
|
||||||
l_cookies := internal_cookies
|
l_cookies := internal_cookies
|
||||||
if l_cookies = Void then
|
if l_cookies = Void then
|
||||||
if attached environment_variable ({EWSGI_ENVIRONMENT_NAMES}.http_cookie) as s then
|
if attached meta_variable ({WGI_META_NAMES}.http_cookie) as s then
|
||||||
create l_cookies.make (5)
|
create l_cookies.make (5)
|
||||||
from
|
from
|
||||||
n := s.count
|
n := s.count
|
||||||
@@ -272,7 +561,7 @@ feature -- Cookies
|
|||||||
v := s.substring (i + 1, j - 1)
|
v := s.substring (i + 1, j - 1)
|
||||||
p := j + 1
|
p := j + 1
|
||||||
end
|
end
|
||||||
l_cookies.put (create {EWSGI_COOKIE}.make (k,v), k)
|
l_cookies.force (v, k)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -283,72 +572,78 @@ feature -- Cookies
|
|||||||
Result := l_cookies
|
Result := l_cookies
|
||||||
end
|
end
|
||||||
|
|
||||||
|
cookie (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
|
-- Field for name `a_name'.
|
||||||
|
do
|
||||||
|
Result := cookies.item (a_name)
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Access: global variable
|
feature -- Access: global variable
|
||||||
|
|
||||||
variables: HASH_TABLE [STRING_32, STRING_32]
|
parameters: HASH_TABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]
|
||||||
-- Table containing all the various variables
|
-- Table containing all the various variables
|
||||||
-- Warning: this is computed each time, if you change the content of other containers
|
-- 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
|
-- this won't update this Result's content, unless you query it again
|
||||||
local
|
local
|
||||||
vars: HASH_TABLE [STRING_GENERAL, STRING_GENERAL]
|
vars: HASH_TABLE [READABLE_STRING_GENERAL, READABLE_STRING_GENERAL]
|
||||||
do
|
do
|
||||||
create Result.make (100)
|
create Result.make (100)
|
||||||
|
|
||||||
vars := environment.table
|
vars := meta_variables
|
||||||
from
|
from
|
||||||
vars.start
|
vars.start
|
||||||
until
|
until
|
||||||
vars.after
|
vars.after
|
||||||
loop
|
loop
|
||||||
Result.put (vars.item_for_iteration, vars.key_for_iteration)
|
Result.force (vars.item_for_iteration.as_string_32, vars.key_for_iteration)
|
||||||
vars.forth
|
vars.forth
|
||||||
end
|
end
|
||||||
|
|
||||||
vars := parameters.table
|
vars := query_parameters
|
||||||
from
|
from
|
||||||
vars.start
|
vars.start
|
||||||
until
|
until
|
||||||
vars.after
|
vars.after
|
||||||
loop
|
loop
|
||||||
Result.put (vars.item_for_iteration, vars.key_for_iteration)
|
Result.force (vars.item_for_iteration.as_string_32, vars.key_for_iteration)
|
||||||
vars.forth
|
vars.forth
|
||||||
end
|
end
|
||||||
|
|
||||||
vars := form_fields.table
|
vars := form_data_parameters
|
||||||
from
|
from
|
||||||
vars.start
|
vars.start
|
||||||
until
|
until
|
||||||
vars.after
|
vars.after
|
||||||
loop
|
loop
|
||||||
Result.put (vars.item_for_iteration, vars.key_for_iteration)
|
Result.force (vars.item_for_iteration.as_string_32, vars.key_for_iteration)
|
||||||
vars.forth
|
vars.forth
|
||||||
end
|
end
|
||||||
|
|
||||||
vars := cookies_variables
|
vars := cookies
|
||||||
from
|
from
|
||||||
vars.start
|
vars.start
|
||||||
until
|
until
|
||||||
vars.after
|
vars.after
|
||||||
loop
|
loop
|
||||||
Result.put (vars.item_for_iteration, vars.key_for_iteration)
|
Result.force (vars.item_for_iteration.as_string_32, vars.key_for_iteration)
|
||||||
vars.forth
|
vars.forth
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
variable (a_name: STRING_8): detachable STRING_32
|
parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
-- Variable named `a_name' from any of the variables container
|
-- Variable named `a_name' from any of the variables container
|
||||||
-- and following a specific order
|
-- and following a specific order
|
||||||
-- execution, environment, get, post, cookies
|
-- execution, environment, get, post, cookies
|
||||||
local
|
local
|
||||||
s: detachable STRING_GENERAL
|
s: detachable READABLE_STRING_GENERAL
|
||||||
do
|
do
|
||||||
s := environment_variable (a_name)
|
s := meta_variable (a_name)
|
||||||
if s = Void then
|
if s = Void then
|
||||||
s := parameter (a_name)
|
s := query_parameter (a_name)
|
||||||
if s = Void then
|
if s = Void then
|
||||||
s := form_field (a_name)
|
s := form_data_parameter (a_name)
|
||||||
if s = Void then
|
if s = Void then
|
||||||
s := cookies_variable (a_name)
|
s := cookie (a_name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -357,19 +652,6 @@ feature -- Access: global variable
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access extra information
|
|
||||||
|
|
||||||
request_time: detachable DATE_TIME
|
|
||||||
-- Request time (UTC)
|
|
||||||
do
|
|
||||||
if
|
|
||||||
attached environment.variable ({EWSGI_ENVIRONMENT_NAMES}.request_time) as t and then
|
|
||||||
t.is_integer_64
|
|
||||||
then
|
|
||||||
Result := date_time_utilities.unix_time_stamp_to_date_time (t.to_integer_64)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Uploaded File Handling
|
feature -- Uploaded File Handling
|
||||||
|
|
||||||
is_uploaded_file (a_filename: STRING): BOOLEAN
|
is_uploaded_file (a_filename: STRING): BOOLEAN
|
||||||
@@ -398,7 +680,7 @@ feature -- URL Utility
|
|||||||
-- Absolute Url for the script if any, extended by `a_path'
|
-- Absolute Url for the script if any, extended by `a_path'
|
||||||
do
|
do
|
||||||
Result := script_url (a_path)
|
Result := script_url (a_path)
|
||||||
if attached environment.http_host as h then
|
if attached http_host as h then
|
||||||
Result.prepend (h)
|
Result.prepend (h)
|
||||||
else
|
else
|
||||||
--| Issue ??
|
--| Issue ??
|
||||||
@@ -410,14 +692,12 @@ feature -- URL Utility
|
|||||||
local
|
local
|
||||||
l_base_url: like internal_url_base
|
l_base_url: like internal_url_base
|
||||||
i,m,n: INTEGER
|
i,m,n: INTEGER
|
||||||
l_rq_uri: like environment.request_uri
|
l_rq_uri: like request_uri
|
||||||
env: like environment
|
|
||||||
do
|
do
|
||||||
l_base_url := internal_url_base
|
l_base_url := internal_url_base
|
||||||
if l_base_url = Void then
|
if l_base_url = Void then
|
||||||
env := environment
|
if attached script_name as l_script_name then
|
||||||
if attached env.script_name as l_script_name then
|
l_rq_uri := request_uri
|
||||||
l_rq_uri := env.request_uri
|
|
||||||
if l_rq_uri.starts_with (l_script_name) then
|
if l_rq_uri.starts_with (l_script_name) then
|
||||||
l_base_url := l_script_name
|
l_base_url := l_script_name
|
||||||
else
|
else
|
||||||
@@ -466,32 +746,9 @@ feature -- Element change
|
|||||||
error_handler := ehdl
|
error_handler := ehdl
|
||||||
end
|
end
|
||||||
|
|
||||||
update_path_info (env: EWSGI_ENVIRONMENT)
|
|
||||||
-- Fix and update PATH_INFO value if needed
|
|
||||||
local
|
|
||||||
l_path_info: STRING
|
|
||||||
do
|
|
||||||
l_path_info := env.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
|
|
||||||
env.unset_orig_path_info
|
|
||||||
else
|
|
||||||
env.set_orig_path_info (l_path_info)
|
|
||||||
if attached env.script_name as l_script_name then
|
|
||||||
if l_path_info.starts_with (l_script_name) then
|
|
||||||
env.path_info := l_path_info.substring (l_script_name.count + 1 , l_path_info.count)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Temporary File handling
|
feature {NONE} -- Temporary File handling
|
||||||
|
|
||||||
delete_uploaded_file (uf: EWSGI_UPLOADED_FILE_DATA)
|
delete_uploaded_file (uf: WGI_UPLOADED_FILE_DATA)
|
||||||
-- Delete file `a_filename'
|
-- Delete file `a_filename'
|
||||||
require
|
require
|
||||||
uf_valid: uf /= Void
|
uf_valid: uf /= Void
|
||||||
@@ -514,7 +771,7 @@ feature {NONE} -- Temporary File handling
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
save_uploaded_file (a_content: STRING; a_up_fn_info: EWSGI_UPLOADED_FILE_DATA)
|
save_uploaded_file (a_content: STRING; a_up_fn_info: WGI_UPLOADED_FILE_DATA)
|
||||||
-- Save uploaded file content to `a_filename'
|
-- Save uploaded file content to `a_filename'
|
||||||
local
|
local
|
||||||
bn: STRING
|
bn: STRING
|
||||||
@@ -605,7 +862,7 @@ feature {NONE} -- Temporary File handling
|
|||||||
|
|
||||||
feature {NONE} -- Implementation: Form analyzer
|
feature {NONE} -- Implementation: Form analyzer
|
||||||
|
|
||||||
analyze_multipart_form (t: STRING; s: STRING; vars: like form_fields)
|
analyze_multipart_form (t: STRING; s: STRING; vars: like form_data_parameters)
|
||||||
-- Analyze multipart form content
|
-- Analyze multipart form content
|
||||||
--| FIXME[2011-06-21]: integrate eMIME parser library
|
--| FIXME[2011-06-21]: integrate eMIME parser library
|
||||||
require
|
require
|
||||||
@@ -671,7 +928,7 @@ feature {NONE} -- Implementation: Form analyzer
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
analyze_multipart_form_input (s: STRING; vars_post: like form_fields)
|
analyze_multipart_form_input (s: STRING; vars_post: like form_data_parameters)
|
||||||
-- Analyze multipart entry
|
-- Analyze multipart entry
|
||||||
require
|
require
|
||||||
s_not_empty: s /= Void and then not s.is_empty
|
s_not_empty: s /= Void and then not s.is_empty
|
||||||
@@ -681,7 +938,7 @@ feature {NONE} -- Implementation: Form analyzer
|
|||||||
l_header: detachable STRING
|
l_header: detachable STRING
|
||||||
l_content: detachable STRING
|
l_content: detachable STRING
|
||||||
l_line: detachable STRING
|
l_line: detachable STRING
|
||||||
l_up_file_info: EWSGI_UPLOADED_FILE_DATA
|
l_up_file_info: WGI_UPLOADED_FILE_DATA
|
||||||
do
|
do
|
||||||
from
|
from
|
||||||
p := 1
|
p := 1
|
||||||
@@ -778,7 +1035,7 @@ feature {NONE} -- Implementation: Form analyzer
|
|||||||
save_uploaded_file (l_content, l_up_file_info)
|
save_uploaded_file (l_content, l_up_file_info)
|
||||||
uploaded_files.force (l_up_file_info, l_name)
|
uploaded_files.force (l_up_file_info, l_name)
|
||||||
else
|
else
|
||||||
vars_post.add_variable (l_content, l_name)
|
vars_post.force (l_content, l_name)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
error_handler.add_custom_error (0, "unamed multipart entry", Void)
|
error_handler.add_custom_error (0, "unamed multipart entry", Void)
|
||||||
@@ -818,10 +1075,10 @@ feature {NONE} -- Internal value
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
internal_parameters: detachable like parameters
|
internal_query_parameters: detachable like query_parameters
|
||||||
-- cached value for `parameters'
|
-- cached value for `query_parameters'
|
||||||
|
|
||||||
internal_form_fields: detachable like form_fields
|
internal_form_data_parameters: detachable like form_data_parameters
|
||||||
-- cached value for `form_fields'
|
-- cached value for `form_fields'
|
||||||
|
|
||||||
internal_cookies: detachable like cookies
|
internal_cookies: detachable like cookies
|
||||||
@@ -846,7 +1103,7 @@ feature {NONE} -- Implementation
|
|||||||
report_bad_request_error (a_message: detachable STRING)
|
report_bad_request_error (a_message: detachable STRING)
|
||||||
-- Report error
|
-- Report error
|
||||||
local
|
local
|
||||||
e: GW_ERROR
|
e: EWF_ERROR
|
||||||
do
|
do
|
||||||
create e.make ({HTTP_STATUS_CODE}.bad_request)
|
create e.make ({HTTP_STATUS_CODE}.bad_request)
|
||||||
if a_message /= Void then
|
if a_message /= Void then
|
||||||
@@ -856,39 +1113,50 @@ feature {NONE} -- Implementation
|
|||||||
end
|
end
|
||||||
|
|
||||||
extract_variables
|
extract_variables
|
||||||
-- Extract relevant environment variables
|
-- Extract relevant meta parameters
|
||||||
local
|
local
|
||||||
s: detachable STRING
|
s: detachable READABLE_STRING_32
|
||||||
do
|
do
|
||||||
s := environment.request_uri
|
s := request_uri
|
||||||
if s.is_empty then
|
if s.is_empty then
|
||||||
report_bad_request_error ("Missing URI")
|
report_bad_request_error ("Missing URI")
|
||||||
end
|
end
|
||||||
if not has_error then
|
if not has_error then
|
||||||
s := environment.request_method
|
s := request_method
|
||||||
if s.is_empty then
|
if s.is_empty then
|
||||||
report_bad_request_error ("Missing request method")
|
report_bad_request_error ("Missing request method")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not has_error then
|
if not has_error then
|
||||||
s := environment.http_host
|
s := http_host
|
||||||
if s = Void or else s.is_empty then
|
if s = Void or else s.is_empty then
|
||||||
report_bad_request_error ("Missing host header")
|
report_bad_request_error ("Missing host header")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not has_error then
|
if not has_error then
|
||||||
update_path_info (environment)
|
update_path_info
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Implementation: utilities
|
feature {NONE} -- Implementation: utilities
|
||||||
|
|
||||||
|
empty_string: READABLE_STRING_32
|
||||||
|
-- Reusable empty string
|
||||||
|
|
||||||
|
url_encoder: URL_ENCODER
|
||||||
|
once
|
||||||
|
create Result
|
||||||
|
end
|
||||||
|
|
||||||
date_time_utilities: HTTP_DATE_TIME_UTILITIES
|
date_time_utilities: HTTP_DATE_TIME_UTILITIES
|
||||||
-- Utilities classes related to date and time.
|
-- Utilities classes related to date and time.
|
||||||
once
|
once
|
||||||
create Result
|
create Result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
invariant
|
||||||
|
empty_string_unchanged: empty_string.is_empty
|
||||||
|
|
||||||
note
|
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)"
|
||||||
@@ -8,9 +8,12 @@ note
|
|||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
class
|
class
|
||||||
EWSGI_RESPONSE_BUFFER
|
WGI_RESPONSE_STREAM_BUFFER
|
||||||
|
|
||||||
create {EWSGI_APPLICATION}
|
inherit
|
||||||
|
WGI_RESPONSE_BUFFER
|
||||||
|
|
||||||
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
@@ -20,17 +23,13 @@ feature {NONE} -- Initialization
|
|||||||
output := a_output
|
output := a_output
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {EWSGI_APPLICATION} -- Commit
|
feature {WGI_APPLICATION} -- Commit
|
||||||
|
|
||||||
commit
|
commit
|
||||||
-- Commit the current response
|
-- Commit the current response
|
||||||
do
|
do
|
||||||
output.flush
|
output.flush
|
||||||
message_committed := True
|
message_committed := True
|
||||||
ensure
|
|
||||||
status_is_set: status_is_set
|
|
||||||
header_committed: header_committed
|
|
||||||
message_committed: message_committed
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Status report
|
feature -- Status report
|
||||||
@@ -67,61 +66,26 @@ feature -- Status setting
|
|||||||
set_status_code (a_code: INTEGER)
|
set_status_code (a_code: INTEGER)
|
||||||
-- Set response status code
|
-- Set response status code
|
||||||
-- Should be done before sending any data back to the client
|
-- Should be done before sending any data back to the client
|
||||||
require
|
|
||||||
status_not_set: not status_is_set
|
|
||||||
header_not_committed: not header_committed
|
|
||||||
do
|
do
|
||||||
status_code := a_code
|
status_code := a_code
|
||||||
output.put_status_line (a_code)
|
output.put_status_line (a_code)
|
||||||
ensure
|
|
||||||
status_code_set: status_code = a_code
|
|
||||||
status_set: status_is_set
|
|
||||||
end
|
end
|
||||||
|
|
||||||
status_code: INTEGER
|
status_code: INTEGER
|
||||||
-- Response status
|
-- Response status
|
||||||
|
|
||||||
feature -- Output operation
|
|
||||||
|
|
||||||
flush
|
|
||||||
do
|
|
||||||
output.flush
|
|
||||||
end
|
|
||||||
|
|
||||||
write_string (s: STRING)
|
|
||||||
-- Send the string `s'
|
|
||||||
require
|
|
||||||
message_writable: message_writable
|
|
||||||
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
|
|
||||||
require
|
|
||||||
message_writable: message_writable
|
|
||||||
do
|
|
||||||
output.put_substring (s, start_index, end_index)
|
|
||||||
end
|
|
||||||
|
|
||||||
write_file_content (fn: STRING)
|
|
||||||
-- Send the content of file `fn'
|
|
||||||
require
|
|
||||||
message_writable: message_writable
|
|
||||||
do
|
|
||||||
output.put_file_content (fn)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Header output operation
|
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]])
|
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'
|
-- Send headers with status `a_status', and headers from `a_headers'
|
||||||
require
|
|
||||||
status_not_set: not status_is_set
|
|
||||||
header_not_committed: not header_committed
|
|
||||||
local
|
local
|
||||||
h: GW_HEADER
|
h: EWF_HEADER
|
||||||
i,n: INTEGER
|
i,n: INTEGER
|
||||||
do
|
do
|
||||||
set_status_code (a_status_code)
|
set_status_code (a_status_code)
|
||||||
@@ -138,16 +102,38 @@ feature -- Header output operation
|
|||||||
i := i + 1
|
i := i + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
write (h.string)
|
write_headers_string (h.string)
|
||||||
header_committed := True
|
end
|
||||||
ensure
|
|
||||||
status_set: status_is_set
|
feature -- Output operation
|
||||||
header_committed: header_committed
|
|
||||||
|
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
|
||||||
|
output.put_substring (s, start_index, end_index)
|
||||||
|
end
|
||||||
|
|
||||||
|
write_file_content (fn: STRING)
|
||||||
|
-- Send the content of file `fn'
|
||||||
|
do
|
||||||
|
output.put_file_content (fn)
|
||||||
|
end
|
||||||
|
|
||||||
|
flush
|
||||||
|
do
|
||||||
|
output.flush
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Implementation: Access
|
feature {NONE} -- Implementation: Access
|
||||||
|
|
||||||
output: EWSGI_OUTPUT_STREAM
|
output: WGI_OUTPUT_STREAM
|
||||||
-- Server output channel
|
-- Server output channel
|
||||||
|
|
||||||
;note
|
;note
|
||||||
@@ -9,7 +9,7 @@ note
|
|||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
EWSGI_INPUT_STREAM
|
WGI_INPUT_STREAM
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ note
|
|||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
EWSGI_OUTPUT_STREAM
|
WGI_OUTPUT_STREAM
|
||||||
|
|
||||||
feature -- Core operation
|
feature -- Core operation
|
||||||
|
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {GW_ERROR}."
|
description: "Summary description for {EWF_ERROR}."
|
||||||
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
|
||||||
GW_ERROR
|
EWF_ERROR
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
ERROR
|
ERROR
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
note
|
note
|
||||||
description: "[
|
description: "[
|
||||||
Summary description for {GW_HEADER}.
|
Summary description for {EWF_HEADER}.
|
||||||
|
|
||||||
Note the return status code is not part of the HTTP header
|
Note the return status code is not part of the HTTP header
|
||||||
]"
|
]"
|
||||||
@@ -10,7 +10,7 @@ note
|
|||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
class
|
class
|
||||||
GW_HEADER
|
EWF_HEADER
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
ANY
|
ANY
|
||||||
@@ -20,5 +20,8 @@
|
|||||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||||
<cluster name="connectors" location="..\connectors\" recursive="true"/>
|
<cluster name="connectors" location="..\connectors\" recursive="true"/>
|
||||||
<cluster name="interface" location="..\src\" recursive="true"/>
|
<cluster name="interface" location="..\src\" recursive="true"/>
|
||||||
|
<cluster name="specification_request" location="..\specification\request" recursive="true"/>
|
||||||
|
<cluster name="specification_response" location="..\specification\response" recursive="true"/>
|
||||||
|
|
||||||
</target>
|
</target>
|
||||||
</system>
|
</system>
|
||||||
|
|||||||
@@ -10,9 +10,9 @@
|
|||||||
<option warning="true" full_class_checking="true" syntax="provisional">
|
<option warning="true" full_class_checking="true" syntax="provisional">
|
||||||
</option>
|
</option>
|
||||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||||
|
<library name="encoder" location="..\..\..\text\encoder\encoder.ecf" readonly="false"/>
|
||||||
<library name="error" location="..\..\..\error\error.ecf"/>
|
<library name="error" location="..\..\..\error\error.ecf"/>
|
||||||
<library name="http" location="..\..\..\protocol\http\http.ecf"/>
|
<library name="http" location="..\..\..\protocol\http\http.ecf"/>
|
||||||
<library name="encoder" location="..\..\..\text\encoder\encoder.ecf" readonly="false"/>
|
|
||||||
<library name="libfcgi" location="..\..\libfcgi\libfcgi.ecf"/>
|
<library name="libfcgi" location="..\..\libfcgi\libfcgi.ecf"/>
|
||||||
<library name="nino" location="..\..\..\..\ext\server\nino\nino.ecf" readonly="false">
|
<library name="nino" location="..\..\..\..\ext\server\nino\nino.ecf" readonly="false">
|
||||||
<renaming old_name="HTTP_CONSTANTS" new_name="NINO_HTTP_CONSTANTS"/>
|
<renaming old_name="HTTP_CONSTANTS" new_name="NINO_HTTP_CONSTANTS"/>
|
||||||
@@ -20,5 +20,7 @@
|
|||||||
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||||
<cluster name="connectors" location="..\connectors\" recursive="true"/>
|
<cluster name="connectors" location="..\connectors\" recursive="true"/>
|
||||||
<cluster name="interface" location="..\src\" recursive="true"/>
|
<cluster name="interface" location="..\src\" recursive="true"/>
|
||||||
|
<cluster name="specification_request" location="..\specification\request" recursive="true"/>
|
||||||
|
<cluster name="specification_response" location="..\specification\response" recursive="true"/>
|
||||||
</target>
|
</target>
|
||||||
</system>
|
</system>
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ feature -- Setup
|
|||||||
|
|
||||||
feature -- Execution
|
feature -- Execution
|
||||||
|
|
||||||
execute (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
|
execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
do
|
do
|
||||||
if attached router.dispatch (req, res) as r then
|
if attached router.dispatch (req, res) as r then
|
||||||
--| done
|
--| done
|
||||||
@@ -44,7 +44,7 @@ feature -- Execution
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
execute_default (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
|
execute_default (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -17,43 +17,42 @@ inherit
|
|||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
request: EWSGI_REQUEST
|
request: WGI_REQUEST
|
||||||
-- Associated request
|
-- Associated request
|
||||||
|
|
||||||
path: STRING
|
path: READABLE_STRING_GENERAL
|
||||||
-- ???
|
-- Associated path
|
||||||
|
|
||||||
request_content_type (content_type_supported: detachable ARRAY [STRING]): detachable STRING
|
request_content_type (content_type_supported: detachable ARRAY [STRING]): detachable READABLE_STRING_8
|
||||||
local
|
local
|
||||||
s: detachable STRING
|
s: detachable READABLE_STRING_32
|
||||||
i,n: INTEGER
|
i,n: INTEGER
|
||||||
do
|
do
|
||||||
Result := request.environment.content_type
|
s := request.content_type
|
||||||
if Result = Void then
|
if s /= Void then
|
||||||
s := request.environment.http_accept
|
Result := s
|
||||||
if s /= Void then
|
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
|
||||||
l_accept_lst.start
|
l_accept_lst.start
|
||||||
until
|
until
|
||||||
l_accept_lst.after or Result /= Void
|
l_accept_lst.after or Result /= Void
|
||||||
loop
|
loop
|
||||||
s := l_accept_lst.item
|
s := l_accept_lst.item
|
||||||
if content_type_supported /= Void then
|
if content_type_supported /= Void then
|
||||||
from
|
from
|
||||||
i := content_type_supported.lower
|
i := content_type_supported.lower
|
||||||
n := content_type_supported.upper
|
n := content_type_supported.upper
|
||||||
until
|
until
|
||||||
i > n or Result /= Void
|
i > n or Result /= Void
|
||||||
loop
|
loop
|
||||||
if content_type_supported[i].same_string (s) then
|
if content_type_supported[i].same_string (s) then
|
||||||
Result := s
|
Result := s
|
||||||
end
|
|
||||||
i := i + 1
|
|
||||||
end
|
end
|
||||||
|
i := i + 1
|
||||||
end
|
end
|
||||||
l_accept_lst.forth
|
|
||||||
end
|
end
|
||||||
|
l_accept_lst.forth
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -61,18 +60,18 @@ feature -- Access
|
|||||||
|
|
||||||
feature -- Query
|
feature -- Query
|
||||||
|
|
||||||
path_parameter (a_name: STRING): detachable STRING_32
|
path_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
-- Parameter value for path variable `a_name'
|
-- Parameter value for path variable `a_name'
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
query_parameter (a_name: STRING): detachable STRING_32
|
query_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
-- 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: STRING): detachable STRING_32
|
parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
-- 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
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ create
|
|||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
make (req: EWSGI_REQUEST; p: like path)
|
make (req: WGI_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: STRING): detachable STRING_32
|
path_parameter (a_name: READABLE_STRING_GENERAL): detachable STRING_32
|
||||||
do
|
do
|
||||||
end
|
end
|
||||||
|
|
||||||
query_parameter (a_name: STRING): detachable STRING_32
|
query_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
do
|
do
|
||||||
Result := request.parameter (a_name)
|
Result := request.parameter (a_name)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ create
|
|||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
make (req: EWSGI_REQUEST; tpl: URI_TEMPLATE; tpl_res: URI_TEMPLATE_MATCH_RESULT; p: like path)
|
make (req: WGI_REQUEST; tpl: URI_TEMPLATE; tpl_res: URI_TEMPLATE_MATCH_RESULT; p: like path)
|
||||||
do
|
do
|
||||||
request := req
|
request := req
|
||||||
uri_template := tpl
|
uri_template := tpl
|
||||||
@@ -31,12 +31,12 @@ feature -- Access
|
|||||||
|
|
||||||
feature -- Query
|
feature -- Query
|
||||||
|
|
||||||
path_parameter (a_name: STRING): detachable STRING_32
|
path_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
do
|
do
|
||||||
Result := uri_template_match.url_decoded_path_variable (a_name)
|
Result := uri_template_match.url_decoded_path_variable (a_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
query_parameter (a_name: STRING): detachable STRING_32
|
query_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||||
do
|
do
|
||||||
Result := uri_template_match.url_decoded_query_variable (a_name)
|
Result := uri_template_match.url_decoded_query_variable (a_name)
|
||||||
if Result = Void then
|
if Result = Void then
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ feature -- Initialization
|
|||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
action: PROCEDURE [ANY, TUPLE [ctx: REQUEST_HANDLER_CONTEXT; req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER]]
|
action: PROCEDURE [ANY, TUPLE [ctx: REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]]
|
||||||
|
|
||||||
feature -- Execution
|
feature -- Execution
|
||||||
|
|
||||||
execute_application (ctx: REQUEST_HANDLER_CONTEXT; req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
|
execute_application (ctx: REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
do
|
do
|
||||||
action.call ([ctx, req, res])
|
action.call ([ctx, req, res])
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -21,15 +21,15 @@ feature -- Access
|
|||||||
|
|
||||||
feature -- Status report
|
feature -- Status report
|
||||||
|
|
||||||
is_valid_context (req: EWSGI_REQUEST): BOOLEAN
|
is_valid_context (req: WGI_REQUEST): BOOLEAN
|
||||||
-- Is `req' valid context for current handler?
|
-- Is `req' valid context for current handler?
|
||||||
do
|
do
|
||||||
Result := request_method_name_supported (req.environment.request_method)
|
Result := request_method_name_supported (req.request_method)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Execution
|
feature -- Execution
|
||||||
|
|
||||||
execute (a_hdl_context: REQUEST_HANDLER_CONTEXT; req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
|
execute (a_hdl_context: REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
-- Execute request handler
|
-- Execute request handler
|
||||||
require
|
require
|
||||||
is_valid_context: is_valid_context (req)
|
is_valid_context: is_valid_context (req)
|
||||||
@@ -37,7 +37,7 @@ feature -- Execution
|
|||||||
rescued: BOOLEAN
|
rescued: BOOLEAN
|
||||||
do
|
do
|
||||||
if not rescued then
|
if not rescued then
|
||||||
if request_method_name_supported (req.environment.request_method) then
|
if request_method_name_supported (req.request_method) then
|
||||||
pre_execute (req)
|
pre_execute (req)
|
||||||
execute_application (a_hdl_context, req, res)
|
execute_application (a_hdl_context, req, res)
|
||||||
post_execute (req, res)
|
post_execute (req, res)
|
||||||
@@ -52,7 +52,7 @@ feature -- Execution
|
|||||||
retry
|
retry
|
||||||
end
|
end
|
||||||
|
|
||||||
execute_method_not_allowed (a_hdl_context: REQUEST_HANDLER_CONTEXT; req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
|
execute_method_not_allowed (a_hdl_context: REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
local
|
local
|
||||||
s: STRING
|
s: STRING
|
||||||
lst: LIST [STRING]
|
lst: LIST [STRING]
|
||||||
@@ -75,24 +75,24 @@ feature -- Execution
|
|||||||
res.write_header ({HTTP_STATUS_CODE}.method_not_allowed, <<["Allow", s]>>)
|
res.write_header ({HTTP_STATUS_CODE}.method_not_allowed, <<["Allow", s]>>)
|
||||||
end
|
end
|
||||||
|
|
||||||
execute_application (a_hdl_context: REQUEST_HANDLER_CONTEXT; req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
|
execute_application (a_hdl_context: REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
-- Execute request handler
|
-- Execute request handler
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
pre_execute (req: EWSGI_REQUEST)
|
pre_execute (req: WGI_REQUEST)
|
||||||
-- Operation processed before `execute'
|
-- Operation processed before `execute'
|
||||||
do
|
do
|
||||||
--| To be redefined if needed
|
--| To be redefined if needed
|
||||||
end
|
end
|
||||||
|
|
||||||
post_execute (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
|
post_execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
-- Operation processed after `execute'
|
-- Operation processed after `execute'
|
||||||
do
|
do
|
||||||
--| To be redefined if needed
|
--| To be redefined if needed
|
||||||
end
|
end
|
||||||
|
|
||||||
rescue_execute (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
|
rescue_execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
-- Operation processed after a rescue
|
-- Operation processed after a rescue
|
||||||
do
|
do
|
||||||
--| To be redefined if needed
|
--| To be redefined if needed
|
||||||
@@ -101,7 +101,7 @@ feature -- Execution
|
|||||||
|
|
||||||
feature -- Execution: report
|
feature -- Execution: report
|
||||||
|
|
||||||
-- execution_information (req: EWSGI_REQUEST): detachable REQUEST_HANDLER_CONTEXT
|
-- execution_information (req: WGI_REQUEST): detachable REQUEST_HANDLER_CONTEXT
|
||||||
-- -- Execution information related to the request
|
-- -- Execution information related to the request
|
||||||
-- do
|
-- do
|
||||||
-- if attached path_information (req, req.environment.path_info) as info then
|
-- if attached path_information (req, req.environment.path_info) as info then
|
||||||
@@ -109,7 +109,7 @@ feature -- Execution: report
|
|||||||
-- end
|
-- end
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
-- path_information (req: EWSGI_REQUEST; a_rq_path: STRING): detachable TUPLE [format: detachable STRING; arguments: detachable STRING]
|
-- path_information (req: WGI_REQUEST; a_rq_path: STRING): detachable TUPLE [format: detachable STRING; arguments: detachable STRING]
|
||||||
-- -- Information related to `a_path'
|
-- -- Information related to `a_path'
|
||||||
-- local
|
-- local
|
||||||
-- l_rq_path: STRING
|
-- l_rq_path: STRING
|
||||||
@@ -156,7 +156,7 @@ feature -- Execution: report
|
|||||||
-- end
|
-- end
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
url (req: EWSGI_REQUEST; args: detachable STRING; abs: BOOLEAN): STRING
|
url (req: WGI_REQUEST; args: detachable STRING; abs: BOOLEAN): STRING
|
||||||
-- Associated url based on `path' and `args'
|
-- Associated url based on `path' and `args'
|
||||||
-- if `abs' then return absolute url
|
-- if `abs' then return absolute url
|
||||||
local
|
local
|
||||||
@@ -165,12 +165,12 @@ feature -- Execution: report
|
|||||||
s := args
|
s := args
|
||||||
if s /= Void and then s.count > 0 then
|
if s /= Void and then s.count > 0 then
|
||||||
if s[1] /= '/' then
|
if s[1] /= '/' then
|
||||||
s := req.environment.request_uri + "/" + s
|
s := req.request_uri + "/" + s
|
||||||
else
|
else
|
||||||
s := req.environment.request_uri + s
|
s := req.request_uri + s
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
s := req.environment.request_uri
|
s := req.request_uri
|
||||||
end
|
end
|
||||||
if abs then
|
if abs then
|
||||||
Result := req.absolute_script_url (s)
|
Result := req.absolute_script_url (s)
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ note
|
|||||||
deferred class
|
deferred class
|
||||||
REQUEST_ROUTER
|
REQUEST_ROUTER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
ITERABLE [TUPLE [handler: REQUEST_HANDLER; resource: READABLE_STRING_8; request_methods: detachable ARRAY [READABLE_STRING_8]]]
|
||||||
|
|
||||||
feature -- Registration
|
feature -- Registration
|
||||||
|
|
||||||
map_default (r: like default_handler)
|
map_default (r: like default_handler)
|
||||||
@@ -17,22 +20,33 @@ feature -- Registration
|
|||||||
default_handler := r
|
default_handler := r
|
||||||
end
|
end
|
||||||
|
|
||||||
map (a_id: STRING; h: REQUEST_HANDLER)
|
map (a_id: READABLE_STRING_8; h: REQUEST_HANDLER)
|
||||||
-- Map handler `h' with `a_id'
|
-- Map handler `h' with `a_id'
|
||||||
|
do
|
||||||
|
map_with_request_methods (a_id, h, Void)
|
||||||
|
end
|
||||||
|
|
||||||
|
map_with_request_methods (a_id: READABLE_STRING_8; h: REQUEST_HANDLER; rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
||||||
|
-- Map handler `h' with `a_id' and `rqst_methods'
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
map_agent (a_id: STRING; a_action: like {REQUEST_AGENT_HANDLER}.action)
|
map_agent (a_id: READABLE_STRING_8; a_action: like {REQUEST_AGENT_HANDLER}.action)
|
||||||
|
do
|
||||||
|
map_agent_with_request_methods (a_id, a_action, Void)
|
||||||
|
end
|
||||||
|
|
||||||
|
map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: like {REQUEST_AGENT_HANDLER}.action; rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
||||||
local
|
local
|
||||||
h: REQUEST_AGENT_HANDLER
|
h: REQUEST_AGENT_HANDLER
|
||||||
do
|
do
|
||||||
create h.make (a_action)
|
create h.make (a_action)
|
||||||
map (a_id, h)
|
map_with_request_methods (a_id, h, rqst_methods)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Execution
|
feature -- Execution
|
||||||
|
|
||||||
dispatch (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER): detachable REQUEST_HANDLER
|
dispatch (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER): detachable REQUEST_HANDLER
|
||||||
-- 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.
|
||||||
@@ -60,13 +74,55 @@ feature -- Execution
|
|||||||
|
|
||||||
feature {NONE} -- Access: Implementation
|
feature {NONE} -- Access: Implementation
|
||||||
|
|
||||||
handler (req: EWSGI_REQUEST): detachable TUPLE [handler: REQUEST_HANDLER; context: REQUEST_HANDLER_CONTEXT]
|
handler (req: WGI_REQUEST): detachable TUPLE [handler: REQUEST_HANDLER; context: REQUEST_HANDLER_CONTEXT]
|
||||||
-- Handler whose map matched with `req'
|
-- Handler whose map matched with `req'
|
||||||
require
|
require
|
||||||
req_valid: req /= Void and then req.environment.path_info /= Void
|
req_valid: req /= Void and then req.path_info /= Void
|
||||||
deferred
|
deferred
|
||||||
ensure
|
ensure
|
||||||
req_path_info_unchanged: req.environment.path_info.same_string (old req.environment.path_info)
|
req_path_info_unchanged: req.path_info.same_string (old req.path_info)
|
||||||
|
end
|
||||||
|
|
||||||
|
is_matching_request_methods (a_request_method: READABLE_STRING_GENERAL; rqst_methods: like formatted_request_methods): BOOLEAN
|
||||||
|
-- `a_request_method' is matching `rqst_methods' contents
|
||||||
|
local
|
||||||
|
i,n: INTEGER
|
||||||
|
m: READABLE_STRING_GENERAL
|
||||||
|
do
|
||||||
|
if rqst_methods /= Void and then not rqst_methods.is_empty then
|
||||||
|
m := a_request_method
|
||||||
|
from
|
||||||
|
i := rqst_methods.lower
|
||||||
|
n := rqst_methods.upper
|
||||||
|
until
|
||||||
|
i > n or Result
|
||||||
|
loop
|
||||||
|
Result := m.same_string (rqst_methods[i])
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Result := True
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
formatted_request_methods (rqst_methods: like formatted_request_methods): detachable ARRAY [READABLE_STRING_8]
|
||||||
|
-- Formatted request methods values
|
||||||
|
local
|
||||||
|
i,l,u: INTEGER
|
||||||
|
do
|
||||||
|
if rqst_methods /= Void and then not rqst_methods.is_empty then
|
||||||
|
l := rqst_methods.lower
|
||||||
|
u := rqst_methods.upper
|
||||||
|
create Result.make_filled (rqst_methods[l], l, u)
|
||||||
|
from
|
||||||
|
i := l + 1
|
||||||
|
until
|
||||||
|
i > u
|
||||||
|
loop
|
||||||
|
Result[i] := rqst_methods[i].as_string_8.as_upper
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|||||||
@@ -10,11 +10,6 @@ class
|
|||||||
inherit
|
inherit
|
||||||
REQUEST_ROUTER
|
REQUEST_ROUTER
|
||||||
|
|
||||||
ITERABLE [REQUEST_HANDLER]
|
|
||||||
redefine
|
|
||||||
new_cursor
|
|
||||||
end
|
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
@@ -28,21 +23,21 @@ feature -- Initialization
|
|||||||
|
|
||||||
feature -- Registration
|
feature -- Registration
|
||||||
|
|
||||||
map (p: STRING; h: REQUEST_HANDLER)
|
map_with_request_methods (p: READABLE_STRING_8; h: REQUEST_HANDLER; rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
||||||
do
|
do
|
||||||
handlers.force (h, p)
|
handlers.force ([h, p, formatted_request_methods (rqst_methods)])
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Access: Implementation
|
feature {NONE} -- Access: Implementation
|
||||||
|
|
||||||
handler (req: EWSGI_REQUEST): detachable TUPLE [handler: REQUEST_HANDLER; context: REQUEST_HANDLER_CONTEXT]
|
handler (req: WGI_REQUEST): detachable TUPLE [handler: REQUEST_HANDLER; context: REQUEST_HANDLER_CONTEXT]
|
||||||
local
|
local
|
||||||
h: detachable REQUEST_HANDLER
|
h: detachable REQUEST_HANDLER
|
||||||
ctx: detachable REQUEST_HANDLER_CONTEXT
|
ctx: detachable REQUEST_HANDLER_CONTEXT
|
||||||
do
|
do
|
||||||
h := handler_by_path (req.environment.path_info)
|
h := handler_by_path (req.path_info, req.request_method)
|
||||||
if h = Void then
|
if h = Void then
|
||||||
if attached smart_handler_by_path (req.environment.path_info) as info then
|
if attached smart_handler_by_path (req.path_info, req.request_method) as info then
|
||||||
h := info.handler
|
h := info.handler
|
||||||
ctx := handler_context (info.path, req)
|
ctx := handler_context (info.path, req)
|
||||||
end
|
end
|
||||||
@@ -59,30 +54,45 @@ feature {NONE} -- Access: Implementation
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
smart_handler (req: EWSGI_REQUEST): detachable TUPLE [path: STRING; handler: REQUEST_HANDLER]
|
smart_handler (req: WGI_REQUEST): detachable TUPLE [path: READABLE_STRING_8; handler: REQUEST_HANDLER]
|
||||||
require
|
require
|
||||||
req_valid: req /= Void and then req.environment.path_info /= Void
|
req_valid: req /= Void and then req.path_info /= Void
|
||||||
do
|
do
|
||||||
Result := smart_handler_by_path (req.environment.path_info)
|
Result := smart_handler_by_path (req.path_info, req.request_method)
|
||||||
ensure
|
ensure
|
||||||
req_path_info_unchanged: req.environment.path_info.same_string (old req.environment.path_info)
|
req_path_info_unchanged: req.path_info.same_string (old req.path_info)
|
||||||
end
|
end
|
||||||
|
|
||||||
handler_by_path (a_path: STRING): detachable REQUEST_HANDLER
|
handler_by_path (a_path: READABLE_STRING_GENERAL; rqst_method: READABLE_STRING_GENERAL): detachable REQUEST_HANDLER
|
||||||
require
|
require
|
||||||
a_path_valid: a_path /= Void
|
a_path_valid: a_path /= Void
|
||||||
|
local
|
||||||
|
l_handlers: like handlers
|
||||||
|
l_item: like handlers.item
|
||||||
do
|
do
|
||||||
Result := handlers.item (context_path (a_path))
|
l_handlers := handlers
|
||||||
|
from
|
||||||
|
l_handlers.start
|
||||||
|
until
|
||||||
|
l_handlers.after or Result /= Void
|
||||||
|
loop
|
||||||
|
l_item := l_handlers.item
|
||||||
|
if is_matching_request_methods (rqst_method, l_item.request_methods) and a_path.same_string (l_item.resource) then
|
||||||
|
Result := l_item.handler
|
||||||
|
end
|
||||||
|
l_handlers.forth
|
||||||
|
end
|
||||||
|
-- Result := handlers.item (context_path (a_path))
|
||||||
ensure
|
ensure
|
||||||
a_path_unchanged: a_path.same_string (old a_path)
|
a_path_unchanged: a_path.same_string (old a_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
smart_handler_by_path (a_path: STRING): detachable TUPLE [path: STRING; handler: REQUEST_HANDLER]
|
smart_handler_by_path (a_path: READABLE_STRING_8; rqst_method: READABLE_STRING_GENERAL): detachable TUPLE [path: READABLE_STRING_8; handler: REQUEST_HANDLER]
|
||||||
require
|
require
|
||||||
a_path_valid: a_path /= Void
|
a_path_valid: a_path /= Void
|
||||||
local
|
local
|
||||||
p: INTEGER
|
p: INTEGER
|
||||||
l_context_path, l_path: STRING
|
l_context_path, l_path: READABLE_STRING_8
|
||||||
h: detachable REQUEST_HANDLER
|
h: detachable REQUEST_HANDLER
|
||||||
do
|
do
|
||||||
l_context_path := context_path (a_path)
|
l_context_path := context_path (a_path)
|
||||||
@@ -92,7 +102,7 @@ feature {NONE} -- Access: Implementation
|
|||||||
p <= 1 or Result /= Void
|
p <= 1 or Result /= Void
|
||||||
loop
|
loop
|
||||||
l_path := l_context_path.substring (1, p - 1)
|
l_path := l_context_path.substring (1, p - 1)
|
||||||
h := handler_by_path (l_path)
|
h := handler_by_path (l_path, rqst_method)
|
||||||
if h /= Void then
|
if h /= Void then
|
||||||
Result := [l_path, h]
|
Result := [l_path, h]
|
||||||
else
|
else
|
||||||
@@ -107,45 +117,44 @@ feature {NONE} -- Access: Implementation
|
|||||||
|
|
||||||
feature -- Context factory
|
feature -- Context factory
|
||||||
|
|
||||||
handler_context (p: detachable STRING; req: EWSGI_REQUEST): REQUEST_URI_HANDLER_CONTEXT
|
handler_context (p: detachable STRING; req: WGI_REQUEST): REQUEST_URI_HANDLER_CONTEXT
|
||||||
do
|
do
|
||||||
if p /= Void then
|
if p /= Void then
|
||||||
create Result.make (req, p)
|
create Result.make (req, p)
|
||||||
else
|
else
|
||||||
create Result.make (req, req.environment.path_info)
|
create Result.make (req, req.path_info)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
new_cursor: HASH_TABLE_ITERATION_CURSOR [REQUEST_HANDLER, STRING]
|
new_cursor: ITERATION_CURSOR [TUPLE [handler: REQUEST_HANDLER; resource: READABLE_STRING_8; request_methods: detachable ARRAY [READABLE_STRING_8]]]
|
||||||
-- Fresh cursor associated with current structure
|
-- Fresh cursor associated with current structure
|
||||||
do
|
do
|
||||||
Result := handlers.new_cursor
|
Result := handlers.new_cursor
|
||||||
end
|
end
|
||||||
|
|
||||||
item (a_path: STRING): detachable REQUEST_HANDLER
|
|
||||||
do
|
|
||||||
Result := handler_by_path (a_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
handlers: HASH_TABLE [REQUEST_HANDLER, STRING]
|
handlers: ARRAYED_LIST [TUPLE [handler: REQUEST_HANDLER; resource: READABLE_STRING_8; request_methods: detachable ARRAY [READABLE_STRING_8]]]
|
||||||
-- Handlers
|
-- Handlers indexed by the template expression
|
||||||
|
-- see `templates'
|
||||||
|
|
||||||
context_path (a_path: STRING): STRING
|
context_path (a_path: READABLE_STRING_8): READABLE_STRING_8
|
||||||
-- Prepared path from context which match requirement
|
-- Prepared path from context which match requirement
|
||||||
-- i.e: not empty, starting with '/'
|
-- i.e: not empty, starting with '/'
|
||||||
local
|
local
|
||||||
p: INTEGER
|
p: INTEGER
|
||||||
|
s: STRING_8
|
||||||
do
|
do
|
||||||
Result := a_path
|
Result := a_path
|
||||||
if Result.is_empty then
|
if Result.is_empty then
|
||||||
Result := "/"
|
Result := "/"
|
||||||
else
|
else
|
||||||
if Result[1] /= '/' then
|
if Result[1] /= '/' then
|
||||||
Result := "/" + Result
|
create s.make_from_string (Result)
|
||||||
|
s.prepend_character ('/')
|
||||||
|
Result := s
|
||||||
end
|
end
|
||||||
p := Result.index_of ('.', 1)
|
p := Result.index_of ('.', 1)
|
||||||
if p > 0 then
|
if p > 0 then
|
||||||
|
|||||||
@@ -10,11 +10,6 @@ class
|
|||||||
inherit
|
inherit
|
||||||
REQUEST_ROUTER
|
REQUEST_ROUTER
|
||||||
|
|
||||||
ITERABLE [REQUEST_HANDLER]
|
|
||||||
redefine
|
|
||||||
new_cursor
|
|
||||||
end
|
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
@@ -31,40 +26,51 @@ feature -- Registration
|
|||||||
|
|
||||||
map_with_uri_template (uri: URI_TEMPLATE; h: REQUEST_HANDLER)
|
map_with_uri_template (uri: URI_TEMPLATE; h: REQUEST_HANDLER)
|
||||||
do
|
do
|
||||||
handlers.force (h, uri.template)
|
map_with_uri_template_and_request_methods (uri, h, Void)
|
||||||
|
end
|
||||||
|
|
||||||
|
map_with_uri_template_and_request_methods (uri: URI_TEMPLATE; h: REQUEST_HANDLER; rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
||||||
|
do
|
||||||
|
handlers.force ([h, uri.template, formatted_request_methods (rqst_methods)])
|
||||||
templates.force (uri, uri.template)
|
templates.force (uri, uri.template)
|
||||||
end
|
end
|
||||||
|
|
||||||
map (tpl: STRING; h: REQUEST_HANDLER)
|
map_with_request_methods (tpl: READABLE_STRING_8; h: REQUEST_HANDLER; rqst_methods: detachable ARRAY [READABLE_STRING_8])
|
||||||
local
|
local
|
||||||
uri: URI_TEMPLATE
|
uri: URI_TEMPLATE
|
||||||
do
|
do
|
||||||
create uri.make (tpl)
|
create uri.make (tpl)
|
||||||
map_with_uri_template (uri, h)
|
map_with_uri_template_and_request_methods (uri, h, rqst_methods)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Access: Implementation
|
feature {NONE} -- Access: Implementation
|
||||||
|
|
||||||
handler (req: EWSGI_REQUEST): detachable TUPLE [handler: REQUEST_HANDLER; context: REQUEST_HANDLER_CONTEXT]
|
handler (req: WGI_REQUEST): detachable TUPLE [handler: REQUEST_HANDLER; context: REQUEST_HANDLER_CONTEXT]
|
||||||
local
|
local
|
||||||
ctx: detachable REQUEST_URI_TEMPLATE_HANDLER_CONTEXT
|
ctx: detachable REQUEST_URI_TEMPLATE_HANDLER_CONTEXT
|
||||||
l_handlers: like handlers
|
l_handlers: like handlers
|
||||||
t: STRING
|
t: STRING
|
||||||
p: STRING
|
p: STRING
|
||||||
|
l_req_method: READABLE_STRING_GENERAL
|
||||||
do
|
do
|
||||||
p := req.environment.request_uri
|
p := req.request_uri
|
||||||
from
|
from
|
||||||
|
l_req_method := req.request_method
|
||||||
l_handlers := handlers
|
l_handlers := handlers
|
||||||
l_handlers.start
|
l_handlers.start
|
||||||
until
|
until
|
||||||
l_handlers.after or Result /= Void
|
l_handlers.after or Result /= Void
|
||||||
loop
|
loop
|
||||||
t := l_handlers.key_for_iteration
|
if attached l_handlers.item as l_info then
|
||||||
if attached templates.item (t) as tpl and then
|
if is_matching_request_methods (l_req_method, l_info.request_methods) then
|
||||||
attached tpl.match (p) as res
|
t := l_info.resource
|
||||||
then
|
if attached templates.item (t) as tpl and then
|
||||||
ctx := handler_context (p, req, tpl, res)
|
attached tpl.match (p) as res
|
||||||
Result := [l_handlers.item_for_iteration, ctx]
|
then
|
||||||
|
ctx := handler_context (p, req, tpl, res)
|
||||||
|
Result := [l_info.handler, ctx]
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
l_handlers.forth
|
l_handlers.forth
|
||||||
end
|
end
|
||||||
@@ -72,35 +78,30 @@ feature {NONE} -- Access: Implementation
|
|||||||
|
|
||||||
feature -- Context factory
|
feature -- Context factory
|
||||||
|
|
||||||
handler_context (p: detachable STRING; req: EWSGI_REQUEST; tpl: URI_TEMPLATE; tpl_res: URI_TEMPLATE_MATCH_RESULT): REQUEST_URI_TEMPLATE_HANDLER_CONTEXT
|
handler_context (p: detachable STRING; req: WGI_REQUEST; tpl: URI_TEMPLATE; tpl_res: URI_TEMPLATE_MATCH_RESULT): REQUEST_URI_TEMPLATE_HANDLER_CONTEXT
|
||||||
do
|
do
|
||||||
if p /= Void then
|
if p /= Void then
|
||||||
create Result.make (req, tpl, tpl_res, p)
|
create Result.make (req, tpl, tpl_res, p)
|
||||||
else
|
else
|
||||||
create Result.make (req, tpl, tpl_res, req.environment.path_info)
|
create Result.make (req, tpl, tpl_res, req.path_info)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access: ITERABLE
|
||||||
|
|
||||||
new_cursor: HASH_TABLE_ITERATION_CURSOR [REQUEST_HANDLER, STRING]
|
new_cursor: ITERATION_CURSOR [TUPLE [handler: REQUEST_HANDLER; resource: READABLE_STRING_8; request_methods: detachable ARRAY [READABLE_STRING_8]]]
|
||||||
-- Fresh cursor associated with current structure
|
-- Fresh cursor associated with current structure
|
||||||
do
|
do
|
||||||
Result := handlers.new_cursor
|
Result := handlers.new_cursor
|
||||||
end
|
end
|
||||||
|
|
||||||
item (a_path: STRING): detachable REQUEST_HANDLER
|
|
||||||
do
|
|
||||||
Result := handlers.item (a_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
handlers: HASH_TABLE [REQUEST_HANDLER, STRING]
|
handlers: ARRAYED_LIST [TUPLE [handler: REQUEST_HANDLER; resource: READABLE_STRING_8; request_methods: detachable ARRAY [READABLE_STRING_8]]]
|
||||||
-- Handlers indexed by the template expression
|
-- Handlers indexed by the template expression
|
||||||
-- see `templates'
|
-- see `templates'
|
||||||
|
|
||||||
templates: HASH_TABLE [URI_TEMPLATE, STRING]
|
templates: HASH_TABLE [URI_TEMPLATE, READABLE_STRING_8]
|
||||||
-- URI Template indexed by the template expression
|
-- URI Template indexed by the template expression
|
||||||
|
|
||||||
context_path (a_path: STRING): STRING
|
context_path (a_path: STRING): STRING
|
||||||
|
|||||||
@@ -9,19 +9,20 @@ class
|
|||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
accepted_content_types (req: EWSGI_REQUEST): detachable ARRAYED_LIST [STRING]
|
accepted_content_types (req: WGI_REQUEST): detachable ARRAYED_LIST [READABLE_STRING_8]
|
||||||
local
|
local
|
||||||
l_accept: detachable STRING
|
l_accept: detachable READABLE_STRING_32
|
||||||
s,q: STRING
|
s: STRING_8
|
||||||
|
q: READABLE_STRING_8
|
||||||
p: INTEGER
|
p: INTEGER
|
||||||
lst: LIST [STRING]
|
lst: LIST [READABLE_STRING_8]
|
||||||
qs: QUICK_SORTER [STRING]
|
qs: QUICK_SORTER [READABLE_STRING_8]
|
||||||
do
|
do
|
||||||
l_accept := req.environment.http_accept
|
l_accept := req.http_accept
|
||||||
--TEST l_accept := "text/html,application/xhtml+xml;q=0.6,application/xml;q=0.2,text/plain;q=0.5,*/*;q=0.8"
|
--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 l_accept /= Void then
|
if l_accept /= Void then
|
||||||
lst := l_accept.split (',')
|
lst := l_accept.as_string_8.split (',')
|
||||||
create Result.make (lst.count)
|
create Result.make (lst.count)
|
||||||
from
|
from
|
||||||
lst.start
|
lst.start
|
||||||
@@ -40,7 +41,7 @@ feature -- Access
|
|||||||
|
|
||||||
lst.forth
|
lst.forth
|
||||||
end
|
end
|
||||||
create qs.make (create {COMPARABLE_COMPARATOR [STRING]})
|
create qs.make (create {COMPARABLE_COMPARATOR [READABLE_STRING_8]})
|
||||||
qs.reverse_sort (Result)
|
qs.reverse_sort (Result)
|
||||||
from
|
from
|
||||||
Result.start
|
Result.start
|
||||||
|
|||||||
Reference in New Issue
Block a user