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)
151 lines
3.9 KiB
Plaintext
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
|