178 lines
5.1 KiB
Plaintext
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
|