diff options
author | Jim Jagielski <jim@apache.org> | 2007-05-08 18:25:52 +0000 |
---|---|---|
committer | Jim Jagielski <jim@apache.org> | 2007-05-08 18:25:52 +0000 |
commit | 519fedd8123589206ac16576582cb79c5fdb06a9 (patch) | |
tree | 1031e36bec30146d40a71b747b796dc44c039251 | |
parent | 841a5d56cf3219cf49df598ac9208cb84b215733 (diff) | |
download | httpd-519fedd8123589206ac16576582cb79c5fdb06a9.tar.gz |
Merge r473278 from trunk:
Add alternate is_socket_connected by using APR functions.
Submitted by: mturk
Reviewed by: jim
Merge r535354 from trunk:
Abstract out (kinda) MSG_PEEK. This way when we
actually update APR and apr_socket_recvfrom()
to know about APR_MSG_OOB, APR_MSG_PEEK, etc...
this code won't need to be adjusted. Also,
make nicer for 2.2 backport.
Reviewed by: jim
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@536291 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | STATUS | 9 | ||||
-rw-r--r-- | modules/proxy/proxy_util.c | 51 |
2 files changed, 50 insertions, 10 deletions
@@ -105,15 +105,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK: (It also works for httpd-2.2.x). +1: jfclere, rpluem, wrowe - * proxy_util.c: Add alternate is_socket_connected() function - which uses APR calls. - Trunk version of patch: - http://svn.apache.org/viewvc?view=rev&rev=473278 - http://svn.apache.org/viewvc?view=rev&rev=535354 - 2.2.x version of patch: - Trunk version works - +1: rpluem, mturk, jim - PATCHES PROPOSED TO BACKPORT FROM TRUNK: * ApacheMonitor: Fix Windows Vista detection. diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index c9c6213900..fd0b7a84b8 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1881,7 +1881,7 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, * * TODO: Handle this much better... */ - if (!conn->hostname || !worker->is_address_reusable || + if (!conn->hostname || !worker->is_address_reusable || (r->connection->keepalives && (r->proxyreq == PROXYREQ_PROXY || r->proxyreq == PROXYREQ_REVERSE) && (strcasecmp(conn->hostname, uri->hostname) != 0) ) ) { @@ -1958,6 +1958,51 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, return OK; } +#define USE_ALTERNATE_IS_CONNECTED 1 + +#if !defined(APR_MSG_PEEK) && defined(MSG_PEEK) +#define APR_MSG_PEEK MSG_PEEK +#endif + +#if USE_ALTERNATE_IS_CONNECTED && defined(APR_MSG_PEEK) +static int is_socket_connected(apr_socket_t *socket) +{ + apr_pollfd_t pfds[1]; + apr_status_t status; + apr_int32_t nfds; + + pfds[0].reqevents = APR_POLLIN; + pfds[0].desc_type = APR_POLL_SOCKET; + pfds[0].desc.s = socket; + + do { + status = apr_poll(&pfds[0], 1, &nfds, 0); + } while (APR_STATUS_IS_EINTR(status)); + + if (status == APR_SUCCESS && nfds == 1 && + pfds[0].rtnevents == APR_POLLIN) { + apr_sockaddr_t unused; + apr_size_t len = 1; + char buf[1]; + /* The socket might be closed in which case + * the poll will return POLLIN. + * If there is no data available the socket + * is closed. + */ + status = apr_socket_recvfrom(&unused, socket, APR_MSG_PEEK, + &buf[0], &len); + if (status == APR_SUCCESS && len) + return 1; + else + return 0; + } + else if (APR_STATUS_IS_EAGAIN(status)) { + return 1; + } + return 0; + +} +#else static int is_socket_connected(apr_socket_t *sock) { @@ -1979,6 +2024,7 @@ static int is_socket_connected(apr_socket_t *sock) else return 1; } +#endif /* USE_ALTERNATE_IS_CONNECTED */ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, proxy_conn_rec *conn, @@ -2000,6 +2046,9 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, if (!(connected = is_socket_connected(conn->sock))) { apr_socket_close(conn->sock); conn->sock = NULL; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: %s: backend socket is disconnected.", + proxy_function); } } while (backend_addr && !connected) { |