From 71a98f3c28655cfbb0351b5521d87299d458f84e Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Wed, 5 Oct 2016 10:45:57 +0200 Subject: [PATCH] Make EiffelWeb standalone easier to debug by using in some locations error instead of exception for network error. - Added C external to use C `recv` feature with error (as opposed to have exception raised on network error). --- .../lib/httpd/httpd_request_handler_i.e | 23 ++++++++++++++----- .../lib/httpd/network/tcp_stream_socket.e | 15 +++++++++++- .../until_16_05/tcp_stream_socket_ext.e | 9 -------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/httpd_request_handler_i.e b/library/server/ewsgi/connectors/standalone/lib/httpd/httpd_request_handler_i.e index 43ddd952..5823c07f 100644 --- a/library/server/ewsgi/connectors/standalone/lib/httpd/httpd_request_handler_i.e +++ b/library/server/ewsgi/connectors/standalone/lib/httpd/httpd_request_handler_i.e @@ -279,8 +279,7 @@ feature -- Execution if a_is_reusing_connection then --| set by default 5 seconds. l_socket.set_recv_timeout (keep_alive_timeout) -- in seconds! - -- FIXME: check if both are really needed. - l_is_ready := l_socket.ready_for_reading and then l_socket.has_incoming_data + l_is_ready := socket_has_incoming_data (l_socket) else l_is_ready := True end @@ -396,9 +395,6 @@ feature -- Parsing not has_error and then a_socket.readable then - if not a_socket.has_incoming_data then - dbglog ("analyze_request_message: NO INCOMING DATA !!!") - end if attached next_line (a_socket) as l_request_line and then not l_request_line.is_empty @@ -501,7 +497,11 @@ feature -- Parsing if retried then report_error ("Rescue in next_line") Result := Void - elseif a_socket.readable then + elseif + a_socket.readable and then + socket_has_incoming_data (a_socket) + then + a_socket.read_line_thread_aware Result := a_socket.last_string -- Do no check `socket_ok' before socket operation, @@ -550,6 +550,17 @@ feature -- Output end end +feature {NONE} -- Helpers + + socket_has_incoming_data (a_socket: HTTPD_STREAM_SOCKET): BOOLEAN + -- Is there any data to read on `a_socket' ? + require + a_socket.readable + do + -- FIXME: check if both are really needed. + Result := a_socket.ready_for_reading and then a_socket.has_incoming_data + end + invariant request_header_attached: request_header /= Void diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/network/tcp_stream_socket.e b/library/server/ewsgi/connectors/standalone/lib/httpd/network/tcp_stream_socket.e index 4557ab60..0a5cb44b 100644 --- a/library/server/ewsgi/connectors/standalone/lib/httpd/network/tcp_stream_socket.e +++ b/library/server/ewsgi/connectors/standalone/lib/httpd/network/tcp_stream_socket.e @@ -67,7 +67,7 @@ feature -- Basic operation l: like last_string do create ext.make_empty (nb_char + 1) - retval := c_receive (descriptor, ext.item, nb_char, c_peekmsg) + retval := clib_recv (descriptor, ext.item, nb_char, c_peekmsg) if retval = 0 then last_string.wipe_out socket_error := Void @@ -124,6 +124,19 @@ feature -- Status report Result := (retval > 0) end +feature {NONE} -- C implementation + + clib_recv (a_fd: INTEGER; buf: POINTER; len: INTEGER; flags: INTEGER): INTEGER + -- External routine to receive at most `len' number of + -- bytes into buffer `buf' from socket `fd' with `flags' options. + external + "C inline" + alias + "[ + return (EIF_INTEGER) recv ((int) $a_fd, (char *) $buf, (int) $len, (int) $flags); + ]" + end + note copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/network/until_16_05/tcp_stream_socket_ext.e b/library/server/ewsgi/connectors/standalone/lib/httpd/network/until_16_05/tcp_stream_socket_ext.e index 73480ca3..22ebf01d 100644 --- a/library/server/ewsgi/connectors/standalone/lib/httpd/network/until_16_05/tcp_stream_socket_ext.e +++ b/library/server/ewsgi/connectors/standalone/lib/httpd/network/until_16_05/tcp_stream_socket_ext.e @@ -56,15 +56,6 @@ feature {NONE} -- Externals deferred end --- set_so_rcvtimeo (a_timeout_seconds: INTEGER) --- -- Set the receive timeout in seconds on Current socket. --- -- if `0' the related operations will never timeout. --- require --- positive_timeout: a_timeout_seconds >= 0 --- do --- c_set_sock_recv_timeout (descriptor, level_sol_socket, a_timeout_seconds) --- end - c_set_sock_recv_timeout (a_fd, a_level: INTEGER; a_timeout_seconds: INTEGER) -- C routine to set socket option `SO_RCVTIMEO' with `a_timeout_seconds' seconds. external