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:
Jocelyn Fiat
2011-07-27 18:34:06 +02:00
parent 73284575d4
commit 436f2afd00
22 changed files with 579 additions and 25 deletions

View File

@@ -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"/>

View File

@@ -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"/>

View 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

View 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>

View 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>

View 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
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

View File

@@ -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,

View File

@@ -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")

View File

@@ -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>

View File

@@ -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
]"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -8,7 +8,7 @@ class
GW_BUFFERED_RESPONSE
inherit
EWSGI_RESPONSE
EWSGI_RESPONSE_STREAM
create {EWSGI_APPLICATION}
make

View File

@@ -8,7 +8,7 @@ class
GW_IN_MEMORY_RESPONSE
inherit
EWSGI_RESPONSE
EWSGI_RESPONSE_STREAM
redefine
commit
end

View File

@@ -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

View File

@@ -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)