Index: CHANGES =================================================================== --- CHANGES (revision 465632) +++ CHANGES (working copy) @@ -1,6 +1,12 @@ -*- coding: utf-8 -*- Changes with Apache 2.2.4 + *) mod_proxy_ajp: Added cping/cpong support for the AJP protocol. + A new worker directive ping=timeout will cause CPING packet + to be send expecting CPONG packet within defined timeout. + In case the backend is too busy this will fail instead + sending the full header. [Mladen Turk] + *) mod_disk_cache: Make sure that only positive integers are accepted for the CacheMaxFileSize and CacheMinFileSize parameters in the config file. PR39380 [Niklas Edmundsson ] Index: modules/proxy/config.m4 =================================================================== --- modules/proxy/config.m4 (revision 465632) +++ modules/proxy/config.m4 (working copy) @@ -16,7 +16,7 @@ proxy_connect_objs="mod_proxy_connect.lo" proxy_ftp_objs="mod_proxy_ftp.lo" proxy_http_objs="mod_proxy_http.lo" -proxy_ajp_objs="mod_proxy_ajp.lo ajp_header.lo ajp_link.lo ajp_msg.lo" +proxy_ajp_objs="mod_proxy_ajp.lo ajp_header.lo ajp_link.lo ajp_msg.lo ajp_utils.lo" proxy_balancer_objs="mod_proxy_balancer.lo" case "$host" in Index: modules/proxy/NWGNUproxyajp =================================================================== --- modules/proxy/NWGNUproxyajp (revision 465632) +++ modules/proxy/NWGNUproxyajp (working copy) @@ -171,6 +171,7 @@ $(OBJDIR)/ajp_header.o \ $(OBJDIR)/ajp_msg.o \ $(OBJDIR)/ajp_link.o \ + $(OBJDIR)/ajp_utils.o \ $(OBJDIR)/libprews.o \ $(EOLIST) Index: modules/proxy/mod_proxy_ajp.c =================================================================== --- modules/proxy/mod_proxy_ajp.c (revision 465632) +++ modules/proxy/mod_proxy_ajp.c (working copy) @@ -532,6 +532,20 @@ goto cleanup; } + /* Handle CPING/CPONG */ + if (worker->ping_timeout_set) { + status = ajp_handle_cping_cpong(backend->sock, r, + worker->ping_timeout); + if (status != APR_SUCCESS) { + backend->close++; + ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, + "proxy: AJP: cping/cpong failed to %pI (%s)", + worker->cp->addr, + worker->hostname); + status = HTTP_SERVICE_UNAVAILABLE; + goto cleanup; + } + } /* Step Three: Process the Request */ status = ap_proxy_ajp_request(p, r, backend, origin, dconf, uri, url, server_portstr); Index: modules/proxy/mod_proxy_ajp.dsp =================================================================== --- modules/proxy/mod_proxy_ajp.dsp (revision 465632) +++ modules/proxy/mod_proxy_ajp.dsp (working copy) @@ -126,6 +126,10 @@ SOURCE=.\ajp_msg.c # End Source File +# Begin Source File + +SOURCE=.\ajp_utils.c +# End Source File # End Group # Begin Source File Index: modules/proxy/mod_proxy.c =================================================================== --- modules/proxy/mod_proxy.c (revision 465632) +++ modules/proxy/mod_proxy.c (working copy) @@ -250,6 +250,15 @@ return "lbset must be between 0 and 99"; worker->lbset = ival; } + else if (!strcasecmp(key, "ping")) { + /* Ping/Pong timeout in seconds. + */ + ival = atoi(val); + if (ival < 1) + return "Ping/Pong timeout must be at least one second"; + worker->ping_timeout = apr_time_from_sec(ival); + worker->ping_timeout_set = 1; + } else { return "unknown Worker parameter"; } Index: modules/proxy/mod_proxy.h =================================================================== --- modules/proxy/mod_proxy.h (revision 465632) +++ modules/proxy/mod_proxy.h (working copy) @@ -325,6 +325,8 @@ } flush_packets; /* control AJP flushing */ int flush_wait; /* poll wait time in microseconds if flush_auto */ int lbset; /* load balancer cluster set */ + apr_interval_time_t ping_timeout; + char ping_timeout_set; }; /* --- /dev/null 2006-10-19 10:15:43.000000000 -0400 +++ modules/proxy/ajp_utils.c 2006-10-19 10:15:35.000000000 -0400 @@ -0,0 +1,105 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ajp.h" + +/* + * Handle the CPING/CPONG + */ +apr_status_t ajp_handle_cping_cpong(apr_socket_t *sock, + request_rec *r, + apr_interval_time_t timeout) +{ + ajp_msg_t *msg; + apr_status_t rc, rv; + apr_interval_time_t org; + apr_byte_t result; + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "Into ajp_handle_cping_cpong"); + + rc = ajp_msg_create(r->pool, &msg); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_handle_cping_cpong: ajp_msg_create failed"); + return rc; + } + + rc = ajp_msg_serialize_cping(msg); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_handle_cping_cpong: ajp_marshal_into_msgb failed"); + return rc; + } + + rc = ajp_ilink_send(sock, msg); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_handle_cping_cpong: ajp_ilink_send failed"); + return rc; + } + + rc = apr_socket_timeout_get(sock, &org); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_handle_cping_cpong: apr_socket_timeout_get failed"); + return rc; + } + + /* Set CPING/CPONG response timeout */ + rc = apr_socket_timeout_set(sock, timeout); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_handle_cping_cpong: apr_socket_timeout_set failed"); + return rc; + } + ajp_msg_reuse(msg); + + /* Read CPONG reply */ + rv = ajp_ilink_receive(sock, msg); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_handle_cping_cpong: ajp_ilink_receive failed"); + goto cleanup; + } + + rv = ajp_msg_get_uint8(msg, &result); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_handle_cping_cpong: invalid CPONG message"); + goto cleanup; + } + if (result != CMD_AJP13_CPONG) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_handle_cping_cpong: awaited CPONG, received %d ", + result); + rv = APR_EGENERAL; + goto cleanup; + } + +cleanup: + /* Restore original socket timeout */ + rc = apr_socket_timeout_set(sock, org); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "ajp_handle_cping_cpong: apr_socket_timeout_set failed"); + return rc; + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "ajp_handle_cping_cpong: Done"); + return rv; +}