Skip to content

Commit d9cbc72

Browse files
committed
Better support for HTTP/1.0 and also related to persistent connection.
1 parent 7e057b2 commit d9cbc72

File tree

5 files changed

+111
-24
lines changed

5 files changed

+111
-24
lines changed

library/server/ewsgi/connectors/standalone/src/httpd/httpd_request_handler_i.e

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ feature {NONE} -- Initialization
3939
create request_header.make_empty
4040
create request_header_map.make (10)
4141

42-
keep_alive_enabled := False
42+
keep_alive_requested := False
4343
end
4444

4545
feature -- Status report
@@ -85,8 +85,10 @@ feature -- Access
8585
remote_info: detachable TUPLE [addr: STRING; hostname: STRING; port: INTEGER]
8686
-- Information related to remote client
8787

88-
keep_alive_enabled: BOOLEAN
89-
-- Inside a persistent connection?
88+
keep_alive_requested: BOOLEAN
89+
-- Persistent connection requested?
90+
-- either has "Connection: Keep-Alive" header,
91+
-- or is HTTP/1.1 and no header "Connection: close".
9092

9193
is_http_version_1_0: BOOLEAN
9294
do
@@ -117,7 +119,6 @@ feature -- Change
117119
set_is_verbose (b: BOOLEAN)
118120
do
119121
is_verbose := b
120-
print ("set_is_verbose " + b.out + "%N")
121122
end
122123

123124
feature -- Execution
@@ -164,7 +165,9 @@ feature -- Execution
164165
n := n + 1
165166
-- FIXME: it seems to be called one more time, mostly to see this is done.
166167
execute_request
167-
l_exit := has_error or l_socket.is_closed or not l_socket.is_open_read or not keep_alive_enabled
168+
l_exit := not {HTTPD_SERVER}.is_persistent_connection_supported
169+
or has_error or l_socket.is_closed or not l_socket.is_open_read
170+
or not keep_alive_requested
168171
reset_request
169172
end
170173
end
@@ -297,20 +300,19 @@ feature -- Parsing
297300
line := next_line (a_socket)
298301
end
299302
end
300-
if not {HTTPD_SERVER}.is_persistent_connection_supported then
301-
keep_alive_enabled := False
302-
elseif is_http_version_1_0 then
303-
keep_alive_enabled := attached request_header_map.item ("Connection") as l_connection and then
303+
-- Except for HTTP/1.0, persistent connection is the default.
304+
keep_alive_requested := True
305+
if is_http_version_1_0 then
306+
keep_alive_requested := attached request_header_map.item ("Connection") as l_connection and then
304307
l_connection.is_case_insensitive_equal_general ("keep-alive")
305308
else
306309
-- By default HTTP:1/1 support persistent connection.
307310
if attached request_header_map.item ("Connection") as l_connection then
308-
print ("Connection -> " + l_connection + "%N")
309311
if l_connection.is_case_insensitive_equal_general ("close") then
310-
keep_alive_enabled := False
312+
keep_alive_requested := False
311313
end
312314
else
313-
keep_alive_enabled := True
315+
keep_alive_requested := True
314316
end
315317
end
316318
end

library/server/ewsgi/connectors/standalone/src/implementation/wgi_httpd_request_handler.e

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ feature -- Request processing
7676

7777
create req.make (httpd_environment (a_socket), l_input, connector)
7878
create res.make (l_output, l_error)
79+
if is_http_version_1_0 then
80+
l_output.set_http_version ({HTTP_CONSTANTS}.http_version_1_0)
81+
res.set_http_version_1_0
82+
else
83+
l_output.set_http_version (version)
84+
end
85+
res.set_is_persistent_connection_requested (keep_alive_requested)
7986

8087
req.set_meta_string_variable ("RAW_HEADER_DATA", request_header)
8188

library/server/ewsgi/connectors/standalone/src/wgi_standalone_output_stream.e

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,12 @@ feature -- Status writing
5050
m: detachable READABLE_STRING_8
5151
do
5252
create s.make (16)
53-
s.append ({HTTP_CONSTANTS}.http_version_1_1)
53+
if attached http_version as v then
54+
s.append (v)
55+
else
56+
-- Default to 1.1
57+
s.append ({HTTP_CONSTANTS}.http_version_1_1)
58+
end
5459
s.append_character (' ')
5560
s.append_integer (a_code)
5661
m := a_reason_phrase

library/server/ewsgi/connectors/standalone/src/wgi_standalone_response_stream.e

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,28 @@ inherit
1818
create
1919
make
2020

21+
feature -- Settings
22+
23+
is_http_version_1_0: BOOLEAN
24+
-- Is associated request using HTTP/1.0 ?
25+
26+
is_persistent_connection_requested: BOOLEAN
27+
-- Is persistent connection requested?
28+
29+
feature -- Settings change
30+
31+
set_http_version_1_0
32+
-- Set associated request is using HTTP/1.0.
33+
do
34+
is_http_version_1_0 := True
35+
end
36+
37+
set_is_persistent_connection_requested (b: BOOLEAN)
38+
-- Set `is_persistent_connection_requested' to `b'.
39+
do
40+
is_persistent_connection_requested := b
41+
end
42+
2143
feature -- Header output operation
2244

2345
put_header_text (a_text: READABLE_STRING_8)
@@ -30,26 +52,64 @@ feature -- Header output operation
3052
o := output
3153
create s.make_from_string (a_text)
3254

33-
-- FIXME: check if HTTP versions 1.0 or else.
34-
3555
i := s.substring_index ("%NConnection:", 1)
36-
if i > 0 then
37-
j := s.index_of ('%R', i + 12)
38-
end
3956
if {HTTPD_SERVER}.is_persistent_connection_supported then
40-
if i = 0 then
41-
s.append ("Connection: Keep-Alive")
42-
s.append (o.crlf)
57+
-- Current standalone support persistent connection.
58+
-- If HTTP/1.1:
59+
-- by default all connection are persistent
60+
-- then no need to return "Connection:" header
61+
-- unless header has "Connection: close"
62+
-- then return "Connection: close"
63+
-- If HTTP/1.0:
64+
-- by default, connection is not persistent
65+
-- unless header has "Connection: Keep-Alive"
66+
-- then return "Connection: Keep-Alive"
67+
-- if header has "Connection: Close"
68+
-- then return "Connection: close"
69+
if is_persistent_connection_requested then
70+
if is_http_version_1_0 then
71+
if i = 0 then
72+
-- Existing response header does not has "Connection: " header.
73+
s.append ("Connection: Keep-Alive")
74+
s.append (o.crlf)
75+
else
76+
-- Do not override the application decision.
77+
end
78+
end
79+
else
80+
-- If HTTP/1.1 and persistent connection is not requested,
81+
-- then return "close"
82+
if i = 0 and not is_http_version_1_0 then
83+
-- Existing response header does not has "Connection: " header.
84+
s.append ("Connection: close")
85+
s.append (o.crlf)
86+
else
87+
-- Do not override the application decision.
88+
end
4389
end
4490
else
45-
-- standalone does not support persistent connection for now
91+
-- persistent connection support is disabled.
92+
-- Return "Connection: close" in any case.
93+
-- Except for HTTP/1.0 since not required.
94+
if i > 0 then
95+
j := s.index_of ('%R', i + 12)
96+
end
4697
if j > 0 then
98+
-- Replace existing "Connection:" header with "Connection: close"
4799
l_connection := s.substring (i + 12, j - 1)
48100
l_connection.adjust
49-
if not l_connection.is_case_insensitive_equal_general ("close") then
101+
if
102+
not is_http_version_1_0 and
103+
not l_connection.is_case_insensitive_equal_general ("close")
104+
then
50105
s.replace_substring ("Connection: close", i + 1, j - 1)
51106
end
52-
else
107+
elseif not is_http_version_1_0 then
108+
-- HTTP/1.1: always return "close" since persistent connection is not supported.
109+
s.append ("Connection: close")
110+
s.append (o.crlf)
111+
elseif is_persistent_connection_requested then
112+
-- For HTTP/1.0, return "Connection: close", only if client sent a "Connection: Keep-Alive"
53113
s.append ("Connection: close")
54114
s.append (o.crlf)
55115
end

library/server/ewsgi/specification/stream/wgi_output_stream.e

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ feature -- Status writing
7474

7575
feature -- Status report
7676

77+
http_version: detachable READABLE_STRING_8
78+
-- Optional HTTP version.
79+
7780
is_available: BOOLEAN
7881
-- Is output available?
7982
--| i.e: no issue with associated output stream, like closed socket, or related?
@@ -85,6 +88,16 @@ feature -- Status report
8588
deferred
8689
end
8790

91+
feature -- Element change
92+
93+
set_http_version (v: like http_version)
94+
-- Set `http_version' to `v'.
95+
require
96+
valid_version: v /= Void implies v.starts_with ("HTTP/")
97+
do
98+
http_version := v
99+
end
100+
88101
feature -- Basic operations
89102

90103
flush

0 commit comments

Comments
 (0)