<tr><td>ping</td>
<td>0</td>
<td>Ping property tells the webserver to "test" the connection to
- the backend before forwarding the request. For AJP, it causes
+ the backend before forwarding the request. For negative values
+ the test is a simple socket check, for positive values it's
+ a more functional check, dependent upon the protocol. For AJP, it causes
<module>mod_proxy_ajp</module>to send a <code>CPING</code>
request on the ajp13 connection (implemented on Tomcat 3.3.2+, 4.1.28+
and 5.0.13+). For HTTP, it causes <module>mod_proxy_http</module>
*/
if (ap_timeout_parameter_parse(val, &timeout, "s") != APR_SUCCESS)
return "Ping/Pong timeout has wrong format";
- if (timeout < 1000)
+ if (timeout < 1000 && timeout >= 0)
return "Ping/Pong timeout must be at least one millisecond";
worker->s->ping_timeout = timeout;
worker->s->ping_timeout_set = 1;
APR_DECLARE_OPTIONAL_FN(int, ap_proxy_clear_connection,
(request_rec *r, apr_table_t *headers));
+
+/**
+ * @param socket socket to test
+ * @return TRUE if socket is connected/active
+ */
+PROXY_DECLARE(int) ap_proxy_is_socket_connected(apr_socket_t *socket);
+
#define PROXY_LBMETHOD "proxylbmethod"
/* The number of dynamic workers that can be added when reconfiguring.
/* Handle CPING/CPONG */
if (worker->s->ping_timeout_set) {
- status = ajp_handle_cping_cpong(backend->sock, r,
- worker->s->ping_timeout);
- /*
- * In case the CPING / CPONG failed for the first time we might be
- * just out of luck and got a faulty backend connection, but the
- * backend might be healthy nevertheless. So ensure that the backend
- * TCP connection gets closed and try it once again.
- */
- if (status != APR_SUCCESS) {
- backend->close = 1;
- ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00897)
- "cping/cpong failed to %pI (%s)",
- worker->cp->addr, worker->s->hostname);
- status = HTTP_SERVICE_UNAVAILABLE;
- retry++;
- continue;
+ if (worker->s->ping_timeout_set < 0) {
+ if (!ap_proxy_is_socket_connected(backend->sock)) {
+ backend->close = 1;
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO()
+ "socket check failed to %pI (%s)",
+ worker->cp->addr, worker->s->hostname);
+ status = HTTP_SERVICE_UNAVAILABLE;
+ retry++;
+ continue;
+ }
+ }
+ else {
+ status = ajp_handle_cping_cpong(backend->sock, r,
+ worker->s->ping_timeout);
+ /*
+ * In case the CPING / CPONG failed for the first time we might be
+ * just out of luck and got a faulty backend connection, but the
+ * backend might be healthy nevertheless. So ensure that the backend
+ * TCP connection gets closed and try it once again.
+ */
+ if (status != APR_SUCCESS) {
+ backend->close = 1;
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00897)
+ "cping/cpong failed to %pI (%s)",
+ worker->cp->addr, worker->s->hostname);
+ status = HTTP_SERVICE_UNAVAILABLE;
+ retry++;
+ continue;
+ }
}
}
/* Step Three: Process the Request */
}
}
+ /* Step Three-and-a-Half: See if the socket is still connected (if desired) */
+ if (worker->s->ping_timeout_set && worker->s->ping_timeout < 0 &&
+ !ap_proxy_is_socket_connected(backend->sock)) {
+ backend->close = 1;
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, status, r, APLOGNO()
+ "socket check failed to %pI (%s)",
+ worker->cp->addr, worker->s->hostname);
+ retry++;
+ continue;
+ }
+
/* Step Four: Send the Request
* On the off-chance that we forced a 100-Continue as a
* kinda HTTP ping test, allow for retries
*/
if ((status = ap_proxy_http_request(p, r, backend, worker,
conf, uri, locurl, server_portstr)) != OK) {
- if ((status == HTTP_SERVICE_UNAVAILABLE) && worker->s->ping_timeout_set) {
+ if ((status == HTTP_SERVICE_UNAVAILABLE) && worker->s->ping_timeout_set &&
+ worker->s->ping_timeout > 0) {
backend->close = 1;
ap_log_rerror(APLOG_MARK, APLOG_INFO, status, r, APLOGNO(01115)
"HTTP: 100-Continue failed to %pI (%s)",
#endif
#if USE_ALTERNATE_IS_CONNECTED && defined(APR_MSG_PEEK)
-static int is_socket_connected(apr_socket_t *socket)
+PROXY_DECLARE(int) ap_proxy_is_socket_connected(apr_socket_t *socket)
{
apr_pollfd_t pfds[1];
apr_status_t status;
}
#else
-static int is_socket_connected(apr_socket_t *sock)
+PROXY_DECLARE(int) ap_proxy_is_socket_connected(apr_socket_t *socket)
{
apr_size_t buffer_len = 1;
(proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
if (conn->sock) {
- if (!(connected = is_socket_connected(conn->sock))) {
+ if (!(connected = ap_proxy_is_socket_connected(conn->sock))) {
socket_cleanup(conn);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00951)
"%s: backend socket is disconnected.",