summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Jagielski <jim@apache.org>2007-05-08 18:25:52 +0000
committerJim Jagielski <jim@apache.org>2007-05-08 18:25:52 +0000
commit519fedd8123589206ac16576582cb79c5fdb06a9 (patch)
tree1031e36bec30146d40a71b747b796dc44c039251
parent841a5d56cf3219cf49df598ac9208cb84b215733 (diff)
downloadhttpd-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--STATUS9
-rw-r--r--modules/proxy/proxy_util.c51
2 files changed, 50 insertions, 10 deletions
diff --git a/STATUS b/STATUS
index 6919407a9a..eda107eaff 100644
--- a/STATUS
+++ b/STATUS
@@ -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) {