Added the possibility to set the "Status" header (different from the status line) in GW_HEADER
Renamed EWSGI_RESPONSE as EWSGI_RESPONSE_STREAM to avoid confusion with EWSGI_RESPONSE as stated in Paul's proposal Added default "configuration" (for nino and cgi) to be independant of the connector (at compilation time) Added example implementing Paul's proposal on top of EWSGI
This commit is contained in:
@@ -11,7 +11,6 @@
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="ewsgi_spec" location="..\..\ewsgi_specification-safe.ecf" readonly="false"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/>
|
||||
<library name="http" location="..\..\..\..\protocol\http\http-safe.ecf"/>
|
||||
<library name="nino" location="..\..\..\..\..\ext\server\nino\nino-safe.ecf" readonly="false">
|
||||
<renaming old_name="HTTP_CONSTANTS" new_name="NINO_HTTP_CONSTANTS"/>
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="ewsgi_spec" location="..\..\ewsgi_specification.ecf" readonly="false"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi.ecf" readonly="false"/>
|
||||
<library name="http" location="..\..\..\..\protocol\http\http.ecf"/>
|
||||
<library name="nino" location="..\..\..\..\..\ext\server\nino\nino.ecf" readonly="false">
|
||||
<renaming old_name="HTTP_CONSTANTS" new_name="NINO_HTTP_CONSTANTS"/>
|
||||
|
||||
32
library/server/ewsgi/default/cgi/default_ewsgi_application.e
Normal file
32
library/server/ewsgi/default/cgi/default_ewsgi_application.e
Normal file
@@ -0,0 +1,32 @@
|
||||
note
|
||||
description: "Summary description for {DEFAULT_EWSGI_APPLICATION}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
DEFAULT_EWSGI_APPLICATION
|
||||
|
||||
inherit
|
||||
GW_APPLICATION_IMP
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_and_launch
|
||||
local
|
||||
cgi: GW_CGI_CONNECTOR
|
||||
do
|
||||
create cgi.make (Current)
|
||||
cgi.launch
|
||||
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
|
||||
22
library/server/ewsgi/default/ewsgi_cgi-safe.ecf
Normal file
22
library/server/ewsgi/default/ewsgi_cgi-safe.ecf
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="ewsgi_cgi" uuid="82D0E5BA-3EBD-4E0F-94D1-776375158DAA" library_target="ewsgi_cgi">
|
||||
<target name="ewsgi_cgi">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||
<library name="ewsgi_spec" location="../ewsgi_specification-safe.ecf"/>
|
||||
<library name="ewsgi" location="../ewsgi-safe.ecf"/>
|
||||
<library name="connector_cgi" location="../connectors/cgi/cgi-safe.ecf"/>
|
||||
<library name="error" location="..\..\..\error\error-safe.ecf"/>
|
||||
<library name="http" location="..\..\..\protocol\http\http-safe.ecf"/>
|
||||
<library name="encoder" location="..\..\..\text\encoder\encoder-safe.ecf" readonly="false"/>
|
||||
<cluster name="default_cgi" location="./cgi" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
26
library/server/ewsgi/default/ewsgi_nino-safe.ecf
Normal file
26
library/server/ewsgi/default/ewsgi_nino-safe.ecf
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="ewsgi_nino" uuid="11D70618-3D82-4C5B-9501-8833DD04A3D6" library_target="ewsgi_nino">
|
||||
<target name="ewsgi_nino">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||
<library name="ewsgi_spec" location="../ewsgi_specification-safe.ecf"/>
|
||||
<library name="ewsgi" location="../ewsgi-safe.ecf"/>
|
||||
<library name="connector_nino" location="../connectors/nino/nino-safe.ecf"/>
|
||||
<library name="nino" location="..\..\..\..\ext\server\nino\nino-safe.ecf" readonly="false">
|
||||
<renaming old_name="HTTP_CONSTANTS" new_name="NINO_HTTP_CONSTANTS"/>
|
||||
</library>
|
||||
|
||||
<library name="error" location="..\..\..\error\error-safe.ecf"/>
|
||||
<library name="http" location="..\..\..\protocol\http\http-safe.ecf"/>
|
||||
<library name="encoder" location="..\..\..\text\encoder\encoder-safe.ecf" readonly="false"/>
|
||||
<cluster name="default_nino" location="./nino" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
@@ -0,0 +1,32 @@
|
||||
note
|
||||
description: "Summary description for {DEFAULT_EWSGI_APPLICATION}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
DEFAULT_EWSGI_APPLICATION
|
||||
|
||||
inherit
|
||||
GW_APPLICATION_IMP
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_and_launch
|
||||
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")
|
||||
(create {NINO_APPLICATION}.make_custom (agent execute, "")).listen (port_number)
|
||||
end
|
||||
|
||||
port_number: INTEGER = 80
|
||||
|
||||
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,10 +1,10 @@
|
||||
note
|
||||
description: "Summary description for {GW_NINO_APPLICATION}."
|
||||
description: "Summary description for {NINO_APPLICATION}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
GW_NINO_APPLICATION
|
||||
NINO_APPLICATION
|
||||
|
||||
create
|
||||
make,
|
||||
@@ -18,7 +18,7 @@ feature {NONE} -- Initialization
|
||||
(create {GW_NINO_APPLICATION}.make_custom (agent execute, "")).listen (port_number)
|
||||
end
|
||||
|
||||
execute (req: EWSGI_REQUEST; res: EWSGI_RESPONSE)
|
||||
execute (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_STREAM)
|
||||
do
|
||||
res.write_header (200, <<["Content-Type", "text/plain"]>>)
|
||||
res.write_string ("Hello World!%N")
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="hello_world" uuid="09AE4913-629B-4D3C-B15D-BB615D9A7B7F">
|
||||
<target name="hello_world">
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
|
||||
</option>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="ewsgi_spec" location="..\..\ewsgi_specification-safe.ecf" readonly="false"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/>
|
||||
</target>
|
||||
<target name="hello_nino_world" extends="hello_world">
|
||||
<root class="HELLO_WORLD" feature="make_and_launch"/>
|
||||
<library name="default_nino" location="..\..\default\ewsgi_nino-safe.ecf" readonly="false"/>
|
||||
<library name="connector_nino" location="..\..\connectors\nino\nino-safe.ecf" readonly="false"/>
|
||||
<cluster name="src" location="src\" recursive="true"/>
|
||||
</target>
|
||||
<target name="hello_cgi_world" extends="hello_world">
|
||||
<root class="HELLO_WORLD" feature="make_and_launch"/>
|
||||
<library name="default_cgi" location="..\..\default\ewsgi_cgi-safe.ecf" readonly="false"/>
|
||||
<library name="connector_cgi" location="..\..\connectors\cgi\cgi-safe.ecf" readonly="false"/>
|
||||
<cluster name="src" location="src\" recursive="true"/>
|
||||
</target>
|
||||
|
||||
</system>
|
||||
@@ -0,0 +1,10 @@
|
||||
${NOTE_KEYWORD}
|
||||
copyright: "2011-${YEAR}, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
@@ -0,0 +1,225 @@
|
||||
note
|
||||
description: "[
|
||||
An EWSGI response. This may be used as is or specialized (subclassed)
|
||||
if a developer wishes to reimplement their own version of the feature
|
||||
'read_message_body_block' for supporting a block-based message body
|
||||
response.
|
||||
]"
|
||||
author: "Paul Cohen <paul.cohen@seibostudio.se>"
|
||||
status: "Draft"
|
||||
|
||||
class EWSGI_RESPONSE
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Create new response object
|
||||
do
|
||||
is_buffered := False
|
||||
ready_to_transmit := False
|
||||
end_of_blocks := False
|
||||
max_block_size := default_max_block_size
|
||||
current_block := ""
|
||||
create headers_table.make (10)
|
||||
end
|
||||
|
||||
feature {EWSGI_RESPONSE_APPLICATION} -- Response status
|
||||
|
||||
transmit_to (res: EWSGI_RESPONSE_STREAM)
|
||||
do
|
||||
res.set_status_code (status)
|
||||
res.write_string (headers)
|
||||
from
|
||||
read_block
|
||||
res.write_string (last_block)
|
||||
-- res.flush
|
||||
until
|
||||
end_of_blocks
|
||||
loop
|
||||
read_block
|
||||
res.write_string (last_block)
|
||||
-- res.flush
|
||||
end
|
||||
end
|
||||
|
||||
ready_to_transmit: BOOLEAN
|
||||
-- Is this response ready to be transmitted?
|
||||
|
||||
set_ready_to_transmit
|
||||
-- Set response to ready to transmit.
|
||||
do
|
||||
if is_buffered then
|
||||
set_header ("Content-Length", current_block.count.out)
|
||||
-- elseif tmp_file /= Void then
|
||||
-- if tmp_file.is_open_write then
|
||||
-- tmp_file.close
|
||||
-- set_header ("Content-Length", tmp_file.count.out)
|
||||
-- end
|
||||
end
|
||||
ready_to_transmit := True
|
||||
ensure
|
||||
ready_to_transmit
|
||||
end
|
||||
|
||||
feature {EWSGI_RESPONSE_APPLICATION} -- Message start line and status
|
||||
|
||||
status: INTEGER
|
||||
-- HTTP status code
|
||||
|
||||
set_status (s: INTEGER)
|
||||
-- Set 'status_code'.
|
||||
do
|
||||
status := s
|
||||
set_header ("Status", s.out)
|
||||
ensure
|
||||
status = s
|
||||
end
|
||||
|
||||
start_line: STRING
|
||||
-- HTTP message start-line
|
||||
do
|
||||
if attached status as st then
|
||||
Result := "HTTP/1.1 " + st.out + " " + status_text (st) + crlf
|
||||
else
|
||||
Result := "HTTP/1.1 200 " + status_text (200) + crlf
|
||||
end
|
||||
end
|
||||
|
||||
feature {EWSGI_RESPONSE_APPLICATION} -- Message headers
|
||||
|
||||
headers: STRING
|
||||
-- HTTP message headers including trailing empty line.
|
||||
local
|
||||
t: HASH_TABLE [STRING, STRING]
|
||||
do
|
||||
Result := ""
|
||||
t := headers_table
|
||||
from
|
||||
t.start
|
||||
until
|
||||
t.after
|
||||
loop
|
||||
Result.append (t.key_for_iteration + ": " + t.item_for_iteration + crlf)
|
||||
t.forth
|
||||
end
|
||||
Result.append (crlf)
|
||||
end
|
||||
|
||||
headers_table: HASH_TABLE [STRING, STRING]
|
||||
-- Hash table of HTTP headers
|
||||
|
||||
set_header (key, value: STRING)
|
||||
-- Set the HTTP header with the given 'key' to the given 'value'.
|
||||
do
|
||||
headers_table.put (value, key)
|
||||
ensure
|
||||
headers_table.has (key) and headers_table @ key = value
|
||||
end
|
||||
|
||||
feature {EWSGI_RESPONSE_APPLICATION} -- Message body
|
||||
|
||||
read_block
|
||||
-- Read a message body block.
|
||||
do
|
||||
if is_buffered then
|
||||
end_of_blocks := True
|
||||
-- else
|
||||
-- -- File based block-based output
|
||||
-- -- TBD!
|
||||
end
|
||||
ensure
|
||||
not is_buffered implies last_block.count <= max_block_size
|
||||
end
|
||||
|
||||
last_block: STRING
|
||||
-- Last message body block that has been read.
|
||||
do
|
||||
Result := current_block
|
||||
end
|
||||
|
||||
is_buffered: BOOLEAN
|
||||
-- Is the entire entity body buffered in memory (STRING)?
|
||||
|
||||
end_of_blocks: BOOLEAN
|
||||
-- Has the last of the entity body blocks been read?
|
||||
|
||||
set_message_body (s: STRING)
|
||||
-- Set the message body to 's'. Use this for when you want a memory
|
||||
-- buffered response.
|
||||
do
|
||||
current_block := s
|
||||
is_buffered := True
|
||||
set_ready_to_transmit
|
||||
ensure
|
||||
is_buffered
|
||||
ready_to_transmit
|
||||
last_block.is_equal (s)
|
||||
end
|
||||
|
||||
max_block_size: INTEGER
|
||||
-- Maximum block size returned by message body if not buffered
|
||||
|
||||
set_max_block_size (block_size: INTEGER)
|
||||
-- Set 'max_block_size'.
|
||||
do
|
||||
max_block_size := block_size
|
||||
ensure
|
||||
max_block_size = block_size
|
||||
end
|
||||
|
||||
-- write_message_block (s: STRING)
|
||||
-- -- Write message body block 's' to a temporary file. Us this when
|
||||
-- -- you want a non-buffered response.
|
||||
-- require
|
||||
-- not is_buffered
|
||||
-- do
|
||||
-- -- TBD!
|
||||
-- ensure
|
||||
-- not is_buffered
|
||||
-- not ready_to_transmit
|
||||
-- end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
-- tmp_file_name: STRING
|
||||
|
||||
-- tmp_file: detachable FILE
|
||||
-- -- Created with mktmp
|
||||
|
||||
-- position: INTEGER
|
||||
-- -- Current read position in tmp_file
|
||||
|
||||
current_block: STRING
|
||||
-- Current message body block
|
||||
|
||||
default_max_block_size: INTEGER = 65536
|
||||
-- Default value of 'max_block_size'
|
||||
|
||||
crlf: STRING = "%/13/%/10/"
|
||||
|
||||
status_text (code: INTEGER): STRING
|
||||
do
|
||||
inspect code
|
||||
when 500 then
|
||||
Result := "Internal Server Error"
|
||||
when 200 then
|
||||
Result := "OK"
|
||||
else
|
||||
Result := "Code " + code.out
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
@@ -0,0 +1,57 @@
|
||||
note
|
||||
description: "Summary description for {EWSGI_RESPONSE_APPLICATION} "
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
EWSGI_RESPONSE_APPLICATION
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_STREAM)
|
||||
-- Execute the request
|
||||
-- See `req.input' for input stream
|
||||
-- `req.environment' for the Gateway environment
|
||||
-- and `res.output' for output stream
|
||||
local
|
||||
rs: EWSGI_RESPONSE
|
||||
s: STRING
|
||||
do
|
||||
rs := response (req)
|
||||
if rs.ready_to_transmit then
|
||||
rs.transmit_to (res)
|
||||
else
|
||||
-- Report internal server error.
|
||||
-- Response not ready to transmit!
|
||||
-- Implementor of EWSGI_APPLICATION has not done his job!
|
||||
create rs.make
|
||||
rs.set_status (500)
|
||||
rs.set_header ("Content-Type", "text/plain")
|
||||
rs.set_message_body ("Incomplete server implementation: Response not ready to transmit.%NTell the programmer to finish his/her job!")
|
||||
rs.transmit_to (res)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Response
|
||||
|
||||
response (request: EWSGI_REQUEST): EWSGI_RESPONSE
|
||||
-- HTTP response for given 'request'.
|
||||
deferred
|
||||
ensure
|
||||
ready_to_transmit: Result.ready_to_transmit
|
||||
end
|
||||
|
||||
;note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
|
||||
end
|
||||
@@ -0,0 +1,36 @@
|
||||
note
|
||||
description : "Objects that ..."
|
||||
author : "$Author$"
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
class
|
||||
HELLO_WORLD
|
||||
|
||||
inherit
|
||||
EWSGI_RESPONSE_APPLICATION
|
||||
|
||||
DEFAULT_EWSGI_APPLICATION
|
||||
|
||||
create
|
||||
make_and_launch
|
||||
|
||||
feature -- Response
|
||||
|
||||
response (request: EWSGI_REQUEST): EWSGI_RESPONSE
|
||||
do
|
||||
create {HELLO_WORLD_RESPONSE} Result.make
|
||||
Result.set_status (200)
|
||||
Result.set_header ("Content-Type", "text/html; charset=utf-8")
|
||||
end
|
||||
note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
@@ -0,0 +1,67 @@
|
||||
note
|
||||
description: "A streaming (non-buffered) Hello World example."
|
||||
author: "Paul Cohen <paul.cohen@seibostudio.se>"
|
||||
status: "Draft"
|
||||
|
||||
class HELLO_WORLD_RESPONSE
|
||||
|
||||
inherit
|
||||
EWSGI_RESPONSE
|
||||
redefine
|
||||
make,
|
||||
read_block
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
precursor
|
||||
set_ready_to_transmit
|
||||
current_hello := 0
|
||||
end
|
||||
|
||||
feature {NONE} -- Entity body
|
||||
|
||||
read_block
|
||||
-- Reads a block of 100000 lines of "Hello World".
|
||||
local
|
||||
i: INTEGER
|
||||
do
|
||||
if current_hello >= 100000 then
|
||||
end_of_blocks := True
|
||||
else
|
||||
if current_hello = 0 then
|
||||
current_block := "<html><body>%N"
|
||||
end
|
||||
from
|
||||
i := 0
|
||||
until
|
||||
i = 10000
|
||||
loop
|
||||
current_block.append ("Hello World ("+ current_hello.out +","+ i.out +")<br/>%N")
|
||||
i := i + 1
|
||||
end
|
||||
current_hello := current_hello + i
|
||||
if current_hello = 100000 then
|
||||
current_block.append ("Bye bye..<br/></body></html>")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
current_hello: INTEGER
|
||||
|
||||
;note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
@@ -27,7 +27,7 @@ feature {NONE} -- Implementation
|
||||
|
||||
request_creator: FUNCTION [ANY, TUPLE [env: EWSGI_ENVIRONMENT; input: EWSGI_INPUT_STREAM], EWSGI_REQUEST]
|
||||
|
||||
response_creator: FUNCTION [ANY, TUPLE [req: EWSGI_REQUEST; output: EWSGI_OUTPUT_STREAM], EWSGI_RESPONSE]
|
||||
response_creator: FUNCTION [ANY, TUPLE [req: EWSGI_REQUEST; output: EWSGI_OUTPUT_STREAM], EWSGI_RESPONSE_STREAM]
|
||||
|
||||
callback: PROCEDURE [ANY, TUPLE [req: like new_request; res: like new_response]]
|
||||
-- Procedure called on `execute'
|
||||
@@ -45,7 +45,7 @@ feature -- Factory
|
||||
Result := request_creator.item ([env, a_input])
|
||||
end
|
||||
|
||||
new_response (req: EWSGI_REQUEST; a_output: EWSGI_OUTPUT_STREAM): EWSGI_RESPONSE
|
||||
new_response (req: EWSGI_REQUEST; a_output: EWSGI_OUTPUT_STREAM): EWSGI_RESPONSE_STREAM
|
||||
do
|
||||
Result := response_creator.item ([req, a_output])
|
||||
end
|
||||
|
||||
@@ -33,7 +33,7 @@ feature -- Process request
|
||||
|
||||
feature {NONE} -- Execution
|
||||
|
||||
execute (req: EWSGI_REQUEST; res: EWSGI_RESPONSE)
|
||||
execute (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_STREAM)
|
||||
-- Execute the request
|
||||
-- See `req.input' for input stream
|
||||
-- `req.environment' for the Gateway environment
|
||||
@@ -48,12 +48,12 @@ feature {NONE} -- Execution
|
||||
do
|
||||
end
|
||||
|
||||
post_execute (req: detachable EWSGI_REQUEST; res: detachable EWSGI_RESPONSE)
|
||||
post_execute (req: detachable EWSGI_REQUEST; res: detachable EWSGI_RESPONSE_STREAM)
|
||||
-- Operation processed after `execute', or after `rescue_execute'
|
||||
do
|
||||
end
|
||||
|
||||
rescue_execute (req: detachable EWSGI_REQUEST; res: detachable EWSGI_RESPONSE; a_exception: detachable EXCEPTION)
|
||||
rescue_execute (req: detachable EWSGI_REQUEST; res: detachable EWSGI_RESPONSE_STREAM; a_exception: detachable EXCEPTION)
|
||||
-- Operation processed on rescue of `execute'
|
||||
do
|
||||
post_execute (req, res)
|
||||
@@ -64,16 +64,16 @@ feature -- Factory
|
||||
new_request (env: EWSGI_ENVIRONMENT; a_input: EWSGI_INPUT_STREAM): EWSGI_REQUEST
|
||||
-- New Request context based on `env' and `a_input'
|
||||
--| note: you can redefine this function to create your own
|
||||
--| descendant of GW_REQUEST_CONTEXT , or even to reuse/recycle existing
|
||||
--| instance of GW_REQUEST_CONTEXT
|
||||
--| descendant of EWSGI_REQUEST , or even to reuse/recycle existing
|
||||
--| instance of EWSGI_REQUEST
|
||||
deferred
|
||||
end
|
||||
|
||||
new_response (req: EWSGI_REQUEST; a_output: EWSGI_OUTPUT_STREAM): EWSGI_RESPONSE
|
||||
new_response (req: EWSGI_REQUEST; a_output: EWSGI_OUTPUT_STREAM): EWSGI_RESPONSE_STREAM
|
||||
-- New Response based on `req' and `a_output'
|
||||
--| note: you can redefine this function to create your own
|
||||
--| descendant of GW_RESPONSE , or even to reuse/recycle existing
|
||||
--| instance of GW_RESPONSE
|
||||
--| descendant of EWSGI_RESPONSE_STREAM , or even to reuse/recycle existing
|
||||
--| instance of EWSGI_RESPONSE_STREAM
|
||||
deferred
|
||||
end
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
note
|
||||
description: "Summary description for {EWSGI_RESPONSE}."
|
||||
description: "Summary description for {EWSGI_RESPONSE_STREAM}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
EWSGI_RESPONSE
|
||||
EWSGI_RESPONSE_STREAM
|
||||
|
||||
feature {EWSGI_APPLICATION} -- Commit
|
||||
|
||||
@@ -29,7 +29,7 @@ feature -- Execution
|
||||
Precursor (env, a_input, a_output)
|
||||
end
|
||||
|
||||
rescue_execute (req: detachable EWSGI_REQUEST; res: detachable EWSGI_RESPONSE; a_exception: detachable EXCEPTION)
|
||||
rescue_execute (req: detachable EWSGI_REQUEST; res: detachable EWSGI_RESPONSE_STREAM; a_exception: detachable EXCEPTION)
|
||||
-- Operation processed on rescue of `execute'
|
||||
do
|
||||
if
|
||||
@@ -50,9 +50,9 @@ feature -- Factory
|
||||
Result.execution_variables.set_variable (request_count.out, "REQUEST_COUNT")
|
||||
end
|
||||
|
||||
new_response (req: EWSGI_REQUEST; a_output: EWSGI_OUTPUT_STREAM): EWSGI_RESPONSE
|
||||
new_response (req: EWSGI_REQUEST; a_output: EWSGI_OUTPUT_STREAM): EWSGI_RESPONSE_STREAM
|
||||
do
|
||||
create {GW_RESPONSE_IMP} Result.make (a_output)
|
||||
create {GW_RESPONSE_STREAM_IMP} Result.make (a_output)
|
||||
end
|
||||
|
||||
;note
|
||||
|
||||
@@ -8,7 +8,7 @@ class
|
||||
GW_BUFFERED_RESPONSE
|
||||
|
||||
inherit
|
||||
EWSGI_RESPONSE
|
||||
EWSGI_RESPONSE_STREAM
|
||||
|
||||
create {EWSGI_APPLICATION}
|
||||
make
|
||||
|
||||
@@ -8,7 +8,7 @@ class
|
||||
GW_IN_MEMORY_RESPONSE
|
||||
|
||||
inherit
|
||||
EWSGI_RESPONSE
|
||||
EWSGI_RESPONSE_STREAM
|
||||
redefine
|
||||
commit
|
||||
end
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
note
|
||||
description: "Summary description for {GW_RESPONSE_IMP}."
|
||||
description: "Summary description for {GW_RESPONSE_STREAM_IMP}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
GW_RESPONSE_IMP
|
||||
GW_RESPONSE_STREAM_IMP
|
||||
|
||||
inherit
|
||||
EWSGI_RESPONSE
|
||||
EWSGI_RESPONSE_STREAM
|
||||
|
||||
create {EWSGI_APPLICATION}
|
||||
make
|
||||
@@ -12,6 +12,14 @@ note
|
||||
class
|
||||
GW_HEADER
|
||||
|
||||
inherit
|
||||
ANY
|
||||
|
||||
HTTP_STATUS_CODE_MESSAGES
|
||||
export
|
||||
{NONE} all
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
@@ -84,6 +92,18 @@ feature -- Header change: general
|
||||
|
||||
feature -- Content related header
|
||||
|
||||
put_status (c: INTEGER)
|
||||
local
|
||||
s: STRING
|
||||
do
|
||||
create s.make_from_string (c.out)
|
||||
if attached http_status_code_message (c) as msg then
|
||||
s.append_character (' ')
|
||||
s.append (msg)
|
||||
end
|
||||
put_header_key_value ("Status", s)
|
||||
end
|
||||
|
||||
put_content_type (t: STRING)
|
||||
do
|
||||
put_header_key_value (name_content_type, t)
|
||||
|
||||
Reference in New Issue
Block a user