Skip site navigation (1)Skip section navigation (2)
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>