Commit 6a3ac167 authored by Graham Leggett's avatar Graham Leggett
Browse files

More error checks to make sure the poll() loop dies when the connection

on either side is closed...
PR:
Obtained from:
Reviewed by:


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@88768 13f79535-47bb-0310-9956-ffa450edef68
parent 1e3f8bdf
Loading
Loading
Loading
Loading
+24 −21
Original line number Diff line number Diff line
@@ -324,66 +324,69 @@ int ap_proxy_connect_handler(request_rec *r, char *url,
            "proxy: CONNECT: error creating client apr_socket_t");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    apr_poll_socket_add(pollfd, client_sock, APR_POLLIN);
/*    apr_poll_socket_add(pollfd, client_sock, APR_POLLIN);*/
#endif
    apr_poll_socket_add(pollfd, r->connection->client_socket, APR_POLLIN);

    /* Add the server side to the poll */
    apr_poll_socket_add(pollfd, sock, APR_POLLIN);
    apr_poll_socket_add(pollfd, r->connection->client_socket, APR_POLLIN);

    while (1) { /* Infinite loop until error (one side closes the connection) */
        ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server, "proxy: CONNECT: going to sleep (poll)");
/*	ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server, "proxy: CONNECT: going to sleep (poll)");*/
        if (apr_poll(pollfd, &pollcnt, -1) != APR_SUCCESS)
        {
	    apr_socket_close(sock);
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "proxy: CONNECT: error apr_poll()");
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
                     "proxy: CONNECT: woke from select(), i=%d", pollcnt);
/*	ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
                     "proxy: CONNECT: woke from select(), i=%d", pollcnt);*/

        if (pollcnt) {
	    apr_poll_revents_get(&pollevent, sock, pollfd);
            if (pollevent & APR_POLLIN) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
                             "proxy: CONNECT: sock was set");
                nbytes = HUGE_STRING_LEN;
/*		ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
                             "proxy: CONNECT: sock was set");*/
                nbytes = sizeof(buffer);
                if (apr_recv(sock, buffer, &nbytes) == APR_SUCCESS) {
                    int o = 0;
                    while(nbytes)
                    {
                        i = nbytes;
                        apr_send(r->connection->client_socket, buffer + o, &i);
			if (apr_send(r->connection->client_socket, buffer + o, &i) != APR_SUCCESS)
			    break;
                        o += i;
                        nbytes -= i;
                    }
                    ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
				 "proxy: CONNECT: wrote %d bytes to client", nbytes);
                }
                else
                    break;
            }
            else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP))
		break;


            apr_poll_revents_get(&pollevent, r->connection->client_socket, pollfd);
            if (pollevent & APR_POLLIN) {
                ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
                             "proxy: CONNECT: client was set");
                nbytes = HUGE_STRING_LEN;
/*		ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
                             "proxy: CONNECT: client was set");*/
                nbytes = sizeof(buffer);
                if (apr_recv(r->connection->client_socket, buffer, &nbytes) == APR_SUCCESS) {
                    int o = 0;
                    while(nbytes)
                    {
                        i = nbytes;
                        apr_send(sock, buffer + o, &i);
			if (apr_send(sock, buffer + o, &i) != APR_SUCCESS)
			    break;
                        o += i;
                        nbytes -= i;
                    }
                    ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
                        r->server, "proxy: CONNECT: wrote %d bytes to server", nbytes);
                }
                else
                    break;
            }
            else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP))
		break;
        }
        else
            break;