Import HTTPD Eiffel
This commit is contained in:
177
http_protocol_handler.e
Normal file
177
http_protocol_handler.e
Normal file
@@ -0,0 +1,177 @@
|
||||
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
|
||||
Reference in New Issue
Block a user