diff --git a/library/http_connection_handler.e b/library/http_connection_handler.e index ff7c3849..84e6d38b 100644 --- a/library/http_connection_handler.e +++ b/library/http_connection_handler.e @@ -26,6 +26,7 @@ feature {NONE} -- Initialization reset do + has_error := False create method.make_empty create uri.make_empty create request_header.make_empty @@ -48,7 +49,14 @@ feature -- Execution end analyze_request_message (client_socket) - process_request (Current, client_socket) + if has_error then + check catch_bad_incoming_connection: False end + if is_verbose then + log ("ERROR: invalid HTTP incoming request") + end + else + process_request (Current, client_socket) + end reset end @@ -57,6 +65,7 @@ feature -- Request processing process_request (a_handler: HTTP_CONNECTION_HANDLER; a_socket: TCP_STREAM_SOCKET) -- Process request ... require + no_error: not has_error a_handler_attached: a_handler /= Void a_uri_attached: a_handler.uri /= Void a_method_attached: a_handler.method /= Void @@ -74,6 +83,9 @@ feature -- Access request_header_map : HASH_TABLE [STRING,STRING] -- Contains key:value of the header + has_error: BOOLEAN + -- Error occurred during `analyze_request_message' + method: STRING -- http verb @@ -85,10 +97,12 @@ feature -- Access --| unused for now remote_info: detachable TUPLE [addr: STRING; hostname: STRING; port: INTEGER] + -- Information related to remote client feature -- Parsing analyze_request_message (a_socket: TCP_STREAM_SOCKET) + -- Analyze message extracted from `a_socket' as HTTP request require input_readable: a_socket /= Void and then a_socket.is_open_read local @@ -97,23 +111,31 @@ feature -- Parsing line : detachable STRING k, val: STRING txt: STRING + l_is_verbose: BOOLEAN do create txt.make (64) - line := next_line (a_socket) - if line /= Void then - analyze_request_line (line) - txt.append (line) - txt.append_character ('%N') + request_header := txt - request_header := txt + if attached next_line (a_socket) as l_request_line and then not l_request_line.is_empty then + txt.append (l_request_line) + txt.append_character ('%N') + analyze_request_line (l_request_line) + else + has_error := True + end + + l_is_verbose := is_verbose + + if not has_error or l_is_verbose then + -- if `is_verbose' we can try to print the request, even if it is a bad HTTP request from line := next_line (a_socket) until line = Void or end_of_stream loop n := line.count - if is_verbose then - print ("%N" + line) + if l_is_verbose then + log (line) end pos := line.index_of (':',1) if pos > 0 then @@ -139,26 +161,26 @@ feature -- Parsing end analyze_request_line (line: STRING) + -- Analyze `line' as a HTTP request line require - line /= Void + valid_line: line /= Void and then not line.is_empty local pos, next_pos: INTEGER do if is_verbose then - print ("%N## Parse HTTP request line ##") - print ("%N") - print (line) + log ("%N## Parse HTTP request line ##") + log (line) end 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 + has_error := method.is_empty end next_line (a_socket: TCP_STREAM_SOCKET): detachable STRING + -- Next line fetched from `a_socket' is available. require is_readable: a_socket.is_open_read do diff --git a/library/http_handler.e b/library/http_handler.e index 5ab070d5..20602184 100644 --- a/library/http_handler.e +++ b/library/http_handler.e @@ -32,6 +32,7 @@ feature -- Output -- Log `a_message' do io.put_string (a_message) + io.put_new_line end feature -- Inherited Features @@ -50,14 +51,14 @@ feature -- Inherited Features create l_listening_socket.make_server_by_port (l_http_port) if not l_listening_socket.is_bound then if is_verbose then - log ("Socket could not be bound on port " + l_http_port.out ) + log ("Socket could not be bound on port " + l_http_port.out) end else l_http_port := l_listening_socket.port from l_listening_socket.listen (max_tcp_clients) if is_verbose then - log ("%NHTTP Connection Server ready on port " + l_http_port.out +" : http://localhost:" + l_http_port.out + "/%N") + log ("%NHTTP Connection Server ready on port " + l_http_port.out +" : http://localhost:" + l_http_port.out + "/") end on_launched (l_http_port) until @@ -102,12 +103,15 @@ feature -- Inherited Features -- Process incoming connection do if is_verbose then - log ("Incoming connection...%N") + log ("Incoming connection...(socket:" + a_socket.descriptor.out + ")") end --| FIXME jfiat [2011/11/03] : should use a Pool of Threads/Handler to process this connection --| also handle permanent connection...? receive_message_and_send_reply (a_socket) a_socket.cleanup + if is_verbose then + log ("connection completed...") + end ensure socket_closed: a_socket.is_closed end diff --git a/library/http_server.e b/library/http_server.e index 66f61089..26fb0df0 100644 --- a/library/http_server.e +++ b/library/http_server.e @@ -22,8 +22,8 @@ feature -- Initialization a_http_handler_valid: a_http_handler /= Void do if configuration.is_verbose then - print("%N%N%N") - print ("Starting Web Application Server (port="+ configuration.http_server_port.out +"):%N") + log ("%N%N%N") + log ("Starting Web Application Server (port="+ configuration.http_server_port.out +"):%N") end stop_requested := False a_http_handler.execute @@ -42,6 +42,14 @@ feature -- Access stop_requested: BOOLEAN -- Stops the server +feature -- Output + + log (a_message: READABLE_STRING_8) + -- Log `a_message' + do + io.put_string (a_message) + end + ;note copyright: "2011-2011, Javier Velilla and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"