Files
EWF/server/http_connection_handler.e
Jocelyn Fiat c553bd1e1e abstracted the HTTP_HANDLER
to let the user integrate at the level of its choice
(either very early so handle itself the header handling, or later to reuse existing code)
2011-05-27 13:07:06 +02:00

151 lines
3.9 KiB
Plaintext

note
description: "Summary description for {HTTP_CONNECTION_HANDLER}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
HTTP_CONNECTION_HANDLER
inherit
HTTP_HANDLER
redefine
make
end
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.
--
-- `a_main_server': The main server object
-- `a_name': The name of this module
do
Precursor (a_main_server, a_name)
create method.make_empty
create uri.make_empty
create request_header.make_empty
create request_header_map.make (10)
end
feature -- Execution
receive_message_and_send_reply (client_socket: TCP_STREAM_SOCKET)
local
l_input: HTTP_INPUT_STREAM
l_output: HTTP_OUTPUT_STREAM
do
create l_input.make (client_socket)
create l_output.make (client_socket)
analyze_request_message (l_input)
process_request (uri, method, request_header_map, request_header, l_input, l_output)
end
feature -- Request processing
process_request (a_uri: STRING; a_method: STRING; a_headers_map: HASH_TABLE [STRING, STRING]; a_headers_text: STRING; a_input: HTTP_INPUT_STREAM; a_output: HTTP_OUTPUT_STREAM)
-- Process request ...
require
a_uri_attached: a_uri /= Void
a_method_attached: a_method /= Void
a_headers_text_attached: a_headers_text /= Void
a_input_attached: a_input /= Void
a_output_attached: a_output /= Void
deferred
end
feature {NONE} -- Access
request_header: STRING
-- Header' source
request_header_map : HASH_TABLE [STRING,STRING]
-- Contains key:value of the header
method: STRING
-- http verb
uri: STRING
-- http endpoint
version: detachable STRING
-- http_version
--| unused for now
feature -- Parsing
parse_http_request_line (line: STRING)
require
line /= Void
local
pos, next_pos: INTEGER
do
print ("%N parse http request line:%N" + line)
-- parse (this should be done by a lexer)
pos := line.index_of (' ', 1)
method := line.substring (1, pos - 1)
next_pos := line.index_of (' ', pos+1)
uri := line.substring (pos+1, next_pos-1)
ensure
not_void_method: method /= Void
end
analyze_request_message (a_input: HTTP_INPUT_STREAM)
require
input_redable: a_input /= Void and then not a_input.is_readable
local
end_of_stream : BOOLEAN
pos : INTEGER
line : STRING
txt: STRING
do
create txt.make (64)
a_input.read_line
line := a_input.last_string
analyze_request_line (line)
txt.append (line)
txt.append_character ('%N')
request_header := txt
from
a_input.read_line
until
end_of_stream
loop
line := a_input.last_string
print ("%N" +line+ "%N")
pos := line.index_of (':',1)
request_header_map.put (line.substring (pos + 1, line.count), line.substring (1,pos-1))
txt.append (line)
txt.append_character ('%N')
if line.is_empty or else line[1] = '%R' then
end_of_stream := True
else
a_input.read_line
end
end
end
analyze_request_line (line: STRING)
require
line /= Void
local
pos, next_pos: INTEGER
do
print ("%N parse request line:%N" + line)
pos := line.index_of (' ', 1)
method := line.substring (1, pos - 1)
next_pos := line.index_of (' ', pos+1)
uri := line.substring (pos+1, next_pos-1)
version := line.substring (next_pos + 1, line.count)
ensure
not_void_method: method /= Void
end
invariant
request_header_attached: request_header /= Void
end