This commit is contained in:
Jocelyn Fiat
2011-10-07 14:40:04 +02:00

View File

@@ -1,185 +1,186 @@
note <<<<<<< HEAD
description: "Summary description for {HTTP_CONNECTION_HANDLER}." note
author: "" description: "Summary description for {HTTP_CONNECTION_HANDLER}."
date: "$Date$" author: ""
revision: "$Revision$" date: "$Date$"
revision: "$Revision$"
deferred class
HTTP_CONNECTION_HANDLER deferred class
HTTP_CONNECTION_HANDLER
inherit
HTTP_HANDLER inherit
redefine HTTP_HANDLER
make redefine
end make
end
feature {NONE} -- Initialization
feature {NONE} -- Initialization
make (a_main_server: like main_server; a_name: STRING)
-- Creates a {HTTP_CONNECTION_HANDLER}, assigns the main_server and sets the current_request_message to empty. make (a_main_server: like main_server; a_name: STRING)
-- -- Creates a {HTTP_CONNECTION_HANDLER}, assigns the main_server and sets the current_request_message to empty.
-- `a_main_server': The main server object --
-- `a_name': The name of this module -- `a_main_server': The main server object
do -- `a_name': The name of this module
Precursor (a_main_server, a_name) do
reset Precursor (a_main_server, a_name)
end reset
end
reset
do reset
create method.make_empty do
create uri.make_empty create method.make_empty
create request_header.make_empty create uri.make_empty
create request_header_map.make (10) create request_header.make_empty
remote_info := Void create request_header_map.make (10)
end remote_info := Void
end
feature -- Execution
feature -- Execution
receive_message_and_send_reply (client_socket: TCP_STREAM_SOCKET)
local receive_message_and_send_reply (client_socket: TCP_STREAM_SOCKET)
l_input: HTTP_INPUT_STREAM local
l_output: HTTP_OUTPUT_STREAM l_input: HTTP_INPUT_STREAM
l_remote_info: detachable like remote_info l_output: HTTP_OUTPUT_STREAM
do l_remote_info: detachable like remote_info
create l_input.make (client_socket) do
create l_output.make (client_socket) create l_input.make (client_socket)
create l_output.make (client_socket)
create l_remote_info
if attached client_socket.peer_address as l_addr then create l_remote_info
l_remote_info.addr := l_addr.host_address.host_address if attached client_socket.peer_address as l_addr then
l_remote_info.hostname := l_addr.host_address.host_name l_remote_info.addr := l_addr.host_address.host_address
l_remote_info.port := l_addr.port l_remote_info.hostname := l_addr.host_address.host_name
remote_info := l_remote_info l_remote_info.port := l_addr.port
end remote_info := l_remote_info
end
analyze_request_message (l_input)
process_request (Current, l_input, l_output) analyze_request_message (l_input)
reset process_request (Current, l_input, l_output)
end reset
end
feature -- Request processing
feature -- Request processing
process_request (a_handler: HTTP_CONNECTION_HANDLER; a_input: HTTP_INPUT_STREAM; a_output: HTTP_OUTPUT_STREAM)
-- Process request ... process_request (a_handler: HTTP_CONNECTION_HANDLER; a_input: HTTP_INPUT_STREAM; a_output: HTTP_OUTPUT_STREAM)
require -- Process request ...
a_handler_attached: a_handler /= Void require
a_uri_attached: a_handler.uri /= Void a_handler_attached: a_handler /= Void
a_method_attached: a_handler.method /= Void a_uri_attached: a_handler.uri /= Void
a_header_map_attached: a_handler.request_header_map /= Void a_method_attached: a_handler.method /= Void
a_header_text_attached: a_handler.request_header /= Void a_header_map_attached: a_handler.request_header_map /= Void
a_input_attached: a_input /= Void a_header_text_attached: a_handler.request_header /= Void
a_output_attached: a_output /= Void a_input_attached: a_input /= Void
deferred a_output_attached: a_output /= Void
end deferred
end
feature -- Access
feature -- Access
request_header: STRING
-- Header' source request_header: STRING
-- Header' source
request_header_map : HASH_TABLE [STRING,STRING]
-- Contains key:value of the header request_header_map : HASH_TABLE [STRING,STRING]
-- Contains key:value of the header
method: STRING
-- http verb method: STRING
-- http verb
uri: STRING
-- http endpoint uri: STRING
-- http endpoint
version: detachable STRING
-- http_version version: detachable STRING
--| unused for now -- http_version
--| unused for now
remote_info: detachable TUPLE [addr: STRING; hostname: STRING; port: INTEGER]
remote_info: detachable TUPLE [addr: STRING; hostname: STRING; port: INTEGER]
feature -- Parsing
feature -- Parsing
parse_http_request_line (line: STRING)
require parse_http_request_line (line: STRING)
line /= Void require
local line /= Void
pos, next_pos: INTEGER local
do pos, next_pos: INTEGER
print ("%N parse http request line:%N" + line) do
-- parse (this should be done by a lexer) print ("%N parse http request line:%N" + line)
pos := line.index_of (' ', 1) -- parse (this should be done by a lexer)
method := line.substring (1, pos - 1) pos := line.index_of (' ', 1)
next_pos := line.index_of (' ', pos+1) method := line.substring (1, pos - 1)
uri := line.substring (pos+1, next_pos-1) next_pos := line.index_of (' ', pos+1)
ensure uri := line.substring (pos+1, next_pos-1)
not_void_method: method /= Void ensure
end not_void_method: method /= Void
end
analyze_request_message (a_input: HTTP_INPUT_STREAM)
require analyze_request_message (a_input: HTTP_INPUT_STREAM)
input_readable: a_input /= Void and then a_input.is_readable require
local input_readable: a_input /= Void and then a_input.is_readable
end_of_stream : BOOLEAN local
pos,n : INTEGER end_of_stream : BOOLEAN
line : STRING pos,n : INTEGER
k, val: STRING line : STRING
txt: STRING k, val: STRING
do txt: STRING
create txt.make (64) do
a_input.read_line create txt.make (64)
line := a_input.last_string a_input.read_line
analyze_request_line (line) line := a_input.last_string
txt.append (line) analyze_request_line (line)
txt.append_character ('%N') txt.append (line)
txt.append_character ('%N')
request_header := txt
from request_header := txt
a_input.read_line from
until a_input.read_line
end_of_stream until
loop end_of_stream
line := a_input.last_string loop
n := line.count line := a_input.last_string
print ("%N" + line + "%N") n := line.count
pos := line.index_of (':',1) print ("%N" + line + "%N")
if pos > 0 then pos := line.index_of (':',1)
k := line.substring(1, pos-1) if pos > 0 then
if line[pos+1].is_space then k := line.substring(1, pos-1)
pos := pos + 1 if line[pos+1].is_space then
end pos := pos + 1
if line[n] = '%R' then end
n := n - 1 if line[n] = '%R' then
end n := n - 1
val := line.substring (pos + 1, n) end
request_header_map.put (val, k) val := line.substring (pos + 1, n)
end request_header_map.put (val, k)
txt.append (line) end
txt.append_character ('%N') txt.append (line)
if line.is_empty or else line[1] = '%R' then txt.append_character ('%N')
end_of_stream := True if line.is_empty or else line[1] = '%R' then
else end_of_stream := True
a_input.read_line else
end a_input.read_line
end end
end end
end
analyze_request_line (line: STRING)
require analyze_request_line (line: STRING)
line /= Void require
local line /= Void
pos, next_pos: INTEGER local
do pos, next_pos: INTEGER
print ("%N parse request line:%N" + line) do
pos := line.index_of (' ', 1) print ("%N parse request line:%N" + line)
method := line.substring (1, pos - 1) pos := line.index_of (' ', 1)
next_pos := line.index_of (' ', pos+1) method := line.substring (1, pos - 1)
uri := line.substring (pos+1, next_pos-1) next_pos := line.index_of (' ', pos+1)
version := line.substring (next_pos + 1, line.count) uri := line.substring (pos+1, next_pos-1)
ensure version := line.substring (next_pos + 1, line.count)
not_void_method: method /= Void ensure
end not_void_method: method /= Void
end
invariant
request_header_attached: request_header /= Void invariant
request_header_attached: request_header /= Void
note
copyright: "2011-2011, Javier Velilla and others" note
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" copyright: "2011-2011, Javier Velilla and others"
end license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end