Date: Sun, 7 May 2006 22:19:35 +0800 (CST) From: Yuan-Chung Hsiao <ychsiao@ychsiao.org> To: FreeBSD-gnats-submit@FreeBSD.org Subject: ports/96917: [PATCH] www/mod_limitipconn: patch the dangling browser connections counting problem Message-ID: <20060507141935.52FA767826@FreeBSD.stu.edu.tw> Resent-Message-ID: <200605071420.k47EKNGr065069@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 96917 >Category: ports >Synopsis: [PATCH] www/mod_limitipconn: patch the dangling browser connections counting problem >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: maintainer-update >Submitter-Id: current-users >Arrival-Date: Sun May 07 14:20:22 GMT 2006 >Closed-Date: >Last-Modified: >Originator: Yuan-Chung Hsiao >Release: FreeBSD 6.1-RC2 i386 >Organization: Computer Center, Shu-Te University >Environment: System: FreeBSD FreeBSD.stu.edu.tw 6.1-RC2 FreeBSD 6.1-RC2 #0: Thu May 4 15:32:31 CST >Description: Add Scott Barta contributed code. Partially fixes the problem of dangling browser connections counting towards the download limit. Added file(s): - files/fixcounting.patch Generated with FreeBSD Port Tools 0.76 >How-To-Repeat: >Fix: --- mod_limitipconn-0.04_1.patch begins here --- diff -ruN --exclude=CVS /usr/ports/www/mod_limitipconn/Makefile /home/ychsiao/project/bsd/mod_limitipconn/Makefile --- /usr/ports/www/mod_limitipconn/Makefile Mon Jan 24 13:19:02 2005 +++ /home/ychsiao/project/bsd/mod_limitipconn/Makefile Sun May 7 21:59:03 2006 @@ -16,9 +16,18 @@ PLIST_FILES= libexec/apache/mod_limitipconn.so USE_APACHE= yes -USE_REINPLACE= yes +APACHEMODDIR= libexec/apache +PLIST_SUB+= APACHEMODDIR="${APACHEMODDIR}" + +OPTIONS= FIXCOUNT "Patch dangling browser connections counting" Off + +.include <bsd.port.pre.mk> + +.if defined(WITH_FIXCOUNT) +EXTRA_PATCHES+= ${PATCHDIR}/fixcounting.patch +.endif post-patch: ${REINPLACE_CMD} -e 's,^APXS = .*,APXS = ${APXS},' ${WRKSRC}/Makefile -.include <bsd.port.mk> +.include <bsd.port.post.mk> diff -ruN --exclude=CVS /usr/ports/www/mod_limitipconn/files/fixcounting.patch /home/ychsiao/project/bsd/mod_limitipconn/files/fixcounting.patch --- /usr/ports/www/mod_limitipconn/files/fixcounting.patch Thu Jan 1 08:00:00 1970 +++ /home/ychsiao/project/bsd/mod_limitipconn/files/fixcounting.patch Sun May 7 21:59:04 2006 @@ -0,0 +1,184 @@ +--- mod_limitipconn.c Fri Apr 12 13:54:49 2002 ++++ ../../files/mod_limitipconn.c Thu Jun 5 17:39:10 2003 +@@ -34,7 +34,7 @@ + #include "scoreboard.h" + + #define MODULE_NAME "mod_limitipconn" +-#define MODULE_VERSION "0.04" ++#define MODULE_VERSION "0.05" + + module MODULE_VAR_EXPORT limitipconn_module; + +@@ -59,62 +59,34 @@ + return (void *) cfg; + } + +-static int limitipconn_handler(request_rec *r) ++static int is_limitable(limitipconn_dir_config *cfg, request_rec *r, char *uri) + { +- /* get configuration information */ +- limitipconn_dir_config *cfg = (limitipconn_dir_config *) +- ap_get_module_config(r->per_dir_config, &limitipconn_module); ++ /* Content-type of the current request */ ++ const char *content_type; + + /* convert Apache arrays to normal C arrays */ + char **nolim = (char **) cfg->no_limit->elts; + char **exlim = (char **) cfg->excl_limit->elts; + +- const char *address; +- + /* loop index variable */ + int i; + +- /* running count of number of connections from this address */ +- int ip_count = 0; +- +- /* Content-type of the current request */ +- const char *content_type; +- +- /* scoreboard data structure */ +- short_score score_record; +- +- /* We decline to handle subrequests: otherwise, in the next step we +- * could get into an infinite loop. */ +- if (!ap_is_initial_req(r)) { +- return DECLINED; +- } +- + /* Look up the Content-type of this request. We need a subrequest + * here since this module might be called before the URI has been + * translated into a MIME type. */ +- content_type = ap_sub_req_lookup_uri(r->uri, r)->content_type; ++ content_type = ap_sub_req_lookup_uri(uri, r)->content_type; + + /* If there's no Content-type, use the default. */ + if (!content_type) { + content_type = ap_default_type(r); + } + +-#ifdef RECORD_FORWARD +- if ((address = ap_table_get(r->headers_in, "X-Forwarded-For")) == NULL) +-#endif +- address = r->connection->remote_ip; +- +- /* A limit value of 0 by convention means no limit. */ +- if (cfg->limit == 0) { +- return OK; +- } +- + /* Cycle through the exempt list; if our content_type is exempt, +- * return OK */ ++ * return 0 */ + for (i = 0; i < cfg->no_limit->nelts; i++) { + if ((ap_strcasecmp_match(content_type, nolim[i]) == 0) + || (strncmp(nolim[i], content_type, strlen(nolim[i])) == 0)) { +- return OK; ++ return 0; + } + } + +@@ -129,9 +101,49 @@ + } + } + if (excused) { +- return OK; ++ return 0; + } + } ++ return 1; ++} ++ ++static int limitipconn_handler(request_rec *r) ++{ ++ /* get configuration information */ ++ limitipconn_dir_config *cfg = (limitipconn_dir_config *) ++ ap_get_module_config(r->per_dir_config, &limitipconn_module); ++ ++ const char *address; ++ ++ /* loop index variable */ ++ int i; ++ ++ /* running count of number of connections from this address */ ++ int ip_count = 0; ++ ++ /* scoreboard data structure */ ++ short_score score_record; ++ ++ /* We decline to handle subrequests: otherwise, in the next step we ++ * could get into an infinite loop. */ ++ if (!ap_is_initial_req(r)) { ++ return DECLINED; ++ } ++ ++#ifdef RECORD_FORWARD ++ if ((address = ap_table_get(r->headers_in, "X-Forwarded-For")) == NULL) ++#endif ++ address = r->connection->remote_ip; ++ ++ /* A limit value of 0 by convention means no limit. */ ++ if (cfg->limit == 0) { ++ return OK; ++ } ++ ++ /* If the content-type isn't limitable, return OK */ ++ if (!is_limitable(cfg, r, r->uri)) { ++ return OK; ++ } + + /* Count up the number of connections we are handling right now from + * this IP address */ +@@ -153,7 +165,51 @@ + || (strcmp(address, score_record.fwdclient) == 0) + #endif + ) { +- ip_count++; ++ /* Try to determine the URI from what's stored of the request in the ++ scoreboard. Hopefully we'll get enough of it to be able to determine ++ the content-type. */ ++ ++ /* A copy of the HTTP request from the scoreboard */ ++ char request[64]; ++ ++ /* The request's URI */ ++ char *uri; ++ ++ /* A temporary pointer used to find the end of the URI */ ++ char *c; ++ ++ /* One if we were unable to find a full URI in the request, zero otherwise */ ++ int full_request = 0; ++ ++ /* Get a copy of the request line from the scoreboard */ ++ strncpy(request, score_record.request, 64); ++ request[63] = 0; ++ ++ /* Separate out the method */ ++ for (uri = request; *uri; uri++) { ++ if (*uri == ' ') { ++ uri++; ++ break; ++ } ++ } ++ ++ /* Find the space which separates the URI from the HTTP version */ ++ for (c = uri; *c; c++) { ++ if (*c == ' ') { ++ *c = 0; ++ full_request = 1; ++ break; ++ } ++ } ++ ++ /* If we don't see the full request string, then be stringy ++ and assume that the request is limitable. This was the ++ behavior before the module was modified to try to be ++ smarter. */ ++ ++ if (*uri && !full_request || is_limitable(cfg, r, uri)) { ++ ip_count++; ++ } + } + break; + case >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060507141935.52FA767826>