Files
EWF/http_protocol_handler.e
2011-05-20 08:58:26 -03:00

178 lines
5.1 KiB
Plaintext

class HTTP_PROTOCOL_HANDLER
inherit
SHARED_HTTP_REQUEST_HANDLERS
HTTP_CONSTANTS
create
make
feature -- Initialization
make (socket: NETWORK_STREAM_SOCKET)
require
valid_socket: socket /= Void and then socket.is_bound
local
done: BOOLEAN
client_socket: detachable NETWORK_STREAM_SOCKET
do
from
done := False
until
done
loop
socket.accept
client_socket := socket.accepted
if client_socket = Void then
-- Some error occured, perhaps because of the timeout
-- We probably should provide some diagnostics here
io.put_string ("accept result = Void")
io.put_new_line
else
perform_client_communication (client_socket)
end
end
end
feature -- Access
method : STRING
uri : STRING
version : STRING
request_header_map : HASH_TABLE [STRING,STRING]
-- Containts key value of the header
feature -- Implementation
perform_client_communication (socket: NETWORK_STREAM_SOCKET)
require
socket_attached: socket /= Void
socket_valid: socket.is_open_read and then socket.is_open_write
local
done: BOOLEAN
l_address, l_peer_address: detachable NETWORK_SOCKET_ADDRESS
do
l_address := socket.address
l_peer_address := socket.peer_address
check
l_address_attached: l_address /= Void
l_peer_address_attached: l_peer_address /= Void
end
io.put_string ("Accepted client on the listen socket address = "+ l_address.host_address.host_address + " port = " + l_address.port.out +".")
io.put_new_line
io.put_string ("%T Accepted client address = " + l_peer_address.host_address.host_address + " , port = " + l_peer_address.port.out)
io.put_new_line
create request_header_map.make (20)
from
done := False
until
done
loop
if socket.socket_ok then
done := receive_message_and_send_replay (socket)
request_header_map.wipe_out
else
done := True
end
end
io.put_string ("Finished processing the client, address = "+ l_peer_address.host_address.host_address + " port = " + l_peer_address.port.out + ".")
io.put_new_line
end
receive_message_and_send_replay (client_socket: NETWORK_STREAM_SOCKET): BOOLEAN
require
socket_attached: client_socket /= Void
socket_valid: client_socket.is_open_read and then client_socket.is_open_write
local
message: detachable STRING
l_http_request : HTTP_REQUEST_HANDLER
do
parse_request_line (client_socket)
message := receive_message_internal (client_socket)
if method.is_equal (Get) then
create {GET_REQUEST_HANDLER} l_http_request
l_http_request.set_uri (uri)
l_http_request.process
send_message (client_socket, l_http_request.answer.reply_header + l_http_request.answer.reply_text)
elseif method.is_equal (Post) then
elseif method.is_equal (Put) then
elseif method.is_equal (Options) then
elseif method.is_equal (Head) then
elseif method.is_equal (Delete) then
elseif method.is_equal (Trace) then
elseif method.is_equal (Connect) then
else
debug
print ("Method not supported")
end
end
end
parse_request_line (socket: NETWORK_STREAM_SOCKET)
require
socket: socket /= Void and then not socket.is_closed
do
socket.read_line
parse_request_line_internal (socket.last_string)
end
receive_message_internal (socket: NETWORK_STREAM_SOCKET) : STRING
require
socket: socket /= Void and then not socket.is_closed
local
end_of_stream : BOOLEAN
pos : INTEGER
line : STRING
do
from
socket.read_line
Result := ""
until
end_of_stream
loop
line := socket.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))
Result.append(socket.last_string)
if not socket.last_string.is_equal("%R") and socket.socket_ok then
socket.read_line
else
end_of_stream := True
end
end
end
send_message (client_socket : NETWORK_STREAM_SOCKET ; a_msg: STRING)
local
a_package : PACKET
a_data : MANAGED_POINTER
c_string : C_STRING
do
create c_string.make (a_msg)
create a_data.make_from_pointer (c_string.item, a_msg.count + 1)
create a_package.make_from_managed_pointer (a_data)
client_socket.send (a_package, 0)
end
parse_request_line_internal (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
end