You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by rb...@apache.org on 2001/08/02 06:25:20 UTC
cvs commit: httpd-2.0/server config.c core.c protocol.c
rbb 01/08/01 21:25:20
Modified: . CHANGES
include http_config.h http_core.h http_protocol.h httpd.h
modules/aaa mod_access.c
modules/http http_protocol.c
server config.c core.c protocol.c
Log:
Add the ability to extend the methods that Apache understands
and have those methods <limit>able in the httpd.conf. It uses
the same bit mask/shifted offset as the original HTTP methods
such as M_GET or M_POST, but expands the total bits from an int to
an ap_int64_t to handle more bits for new request methods than
an int provides.
Submitted by: Cody Sherr <cs...@covalent.net>
Revision Changes Path
1.270 +7 -0 httpd-2.0/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/httpd-2.0/CHANGES,v
retrieving revision 1.269
retrieving revision 1.270
diff -u -r1.269 -r1.270
--- CHANGES 2001/08/01 23:33:07 1.269
+++ CHANGES 2001/08/02 04:25:19 1.270
@@ -1,5 +1,12 @@
Changes with Apache 2.0.23-dev
+ *) Add the ability to extend the methods that Apache understands
+ and have those methods <limit>able in the httpd.conf. It uses
+ the same bit mask/shifted offset as the original HTTP methods
+ such as M_GET or M_POST, but expands the total bits from an int to
+ an ap_int64_t to handle more bits for new request methods than
+ an int provides. [Cody Sherr <cs...@covalent.net>]
+
*) Fix broken mod_mime behavior in merging its arguments. Possible
cause of unexplicable crashes introduced in 2.0.20. [William Rowe]
1.83 +1 -1 httpd-2.0/include/http_config.h
Index: http_config.h
===================================================================
RCS file: /home/cvs/httpd-2.0/include/http_config.h,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -r1.82 -r1.83
--- http_config.h 2001/05/28 15:32:50 1.82
+++ http_config.h 2001/08/02 04:25:19 1.83
@@ -260,7 +260,7 @@
/** Which allow-override bits are set */
int override;
/** Which methods are <Limit>ed */
- int limited;
+ apr_int64_t limited;
apr_array_header_t *limited_xmethods;
ap_method_list_t *xlimited;
1.47 +1 -1 httpd-2.0/include/http_core.h
Index: http_core.h
===================================================================
RCS file: /home/cvs/httpd-2.0/include/http_core.h,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -r1.46 -r1.47
--- http_core.h 2001/07/30 18:51:57 1.46
+++ http_core.h 2001/08/02 04:25:19 1.47
@@ -277,7 +277,7 @@
/** A structure to keep track of authorization requirements */
struct require_line {
/** Where the require line is in the config file. */
- int method_mask;
+ apr_int64_t method_mask;
/** The complete string from the command line */
char *requirement;
};
1.61 +34 -0 httpd-2.0/include/http_protocol.h
Index: http_protocol.h
===================================================================
RCS file: /home/cvs/httpd-2.0/include/http_protocol.h,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -r1.60 -r1.61
--- http_protocol.h 2001/07/27 21:01:16 1.60
+++ http_protocol.h 2001/08/02 04:25:19 1.61
@@ -227,6 +227,40 @@
size_t length);
#endif
+/* The index of the first bit field that is used to index into a limit
+ * bitmask. M_INVALID + 1 to METHOD_NUMBER_LAST.
+ */
+#define METHOD_NUMBER_FIRST M_INVALID + 1
+
+/* The max method number. Method numbers are used to shift bitmasks,
+ * so this cannot exceed 63, and all bits high is equal to -1, which is a
+ * special flag, so the last bit used has index 62.
+ */
+#define METHOD_NUMBER_LAST 62
+
+/**
+ * Register a new request method, and return the offset that will be
+ * associated with that method.
+ *
+ * @param p The pool to create registered method numbers from.
+ * @param methname The name of the new method to register.
+ * @return Ab int value representing an offset into a bitmask.
+ */
+AP_DECLARE(int) ap_method_register(apr_pool_t *p, char *methname);
+
+/**
+ * Initialize the method_registry and allocate memory for it.
+ *
+ * @param p Pool to allocate memory for the registry from.
+ */
+AP_DECLARE(void) ap_method_registry_init(apr_pool_t *p);
+
+/*
+ * This is a convenience macro to ease with checking a mask
+ * against a method name.
+ */
+#define AP_METHOD_CHECK_ALLOWED(mask, methname) ((mask) & (1 << ap_method_number_of((methname))))
+
/**
* Create a new method list with the specified number of preallocated
* slots for extension methods.
1.157 +7 -4 httpd-2.0/include/httpd.h
Index: httpd.h
===================================================================
RCS file: /home/cvs/httpd-2.0/include/httpd.h,v
retrieving revision 1.156
retrieving revision 1.157
diff -u -r1.156 -r1.157
--- httpd.h 2001/07/26 15:53:15 1.156
+++ httpd.h 2001/08/02 04:25:19 1.157
@@ -498,7 +498,10 @@
#define M_UNLOCK 14
#define M_INVALID 15
-#define METHODS 16
+/* METHODS needs to be equal to the number of bits
+ * we are using for limit masks.
+ */
+#define METHODS 64
typedef struct ap_method_list_t ap_method_list_t;
/**
@@ -508,8 +511,8 @@
*/
struct ap_method_list_t {
/* The bitmask used for known methods */
- int method_mask;
- /* The array used for extension methods */
+ apr_int64_t method_mask;
+ /* the array used for extension methods */
apr_array_header_t *method_list;
};
@@ -679,7 +682,7 @@
* HTTP_METHOD_NOT_ALLOWED. Unfortunately this means that a Script GET
* handler can't be installed by mod_actions.
*/
- int allowed;
+ apr_int64_t allowed;
/** Array of extension methods */
apr_array_header_t *allowed_xmethods;
/** List of allowed methods */
1.33 +3 -2 httpd-2.0/modules/aaa/mod_access.c
Index: mod_access.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/aaa/mod_access.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -r1.32 -r1.33
--- mod_access.c 2001/04/12 13:35:39 1.32
+++ mod_access.c 2001/08/02 04:25:19 1.33
@@ -91,7 +91,7 @@
};
typedef struct {
- int limited;
+ apr_int64_t limited;
union {
char *from;
apr_ipsubnet_t *ip;
@@ -237,8 +237,9 @@
static int find_allowdeny(request_rec *r, apr_array_header_t *a, int method)
{
+
allowdeny *ap = (allowdeny *) a->elts;
- int mmask = (1 << method);
+ apr_int64_t mmask = (1 << method);
int i;
int gothost = 0;
const char *remotehost = NULL;
1.340 +73 -3 httpd-2.0/modules/http/http_protocol.c
Index: http_protocol.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/http/http_protocol.c,v
retrieving revision 1.339
retrieving revision 1.340
diff -u -r1.339 -r1.340
--- http_protocol.c 2001/08/01 04:08:36 1.339
+++ http_protocol.c 2001/08/02 04:25:20 1.340
@@ -299,6 +299,64 @@
return OK;
}
+/**
+ * Singleton registry of additional methods. This maps new method names
+ * such as "MYGET" to methnums, which are int offsets into bitmasks.
+ *
+ * This follows the same technique as standard M_GET, M_POST, etc. These
+ * are dynamically assigned when modules are loaded and <Limit GET MYGET>
+ * directives are processed.
+ */
+static apr_hash_t *methods_registry=NULL;
+static int cur_method_number = METHOD_NUMBER_FIRST;
+
+/* This internal function is used to clear the method registry
+ * and reset the cur_method_number counter.
+ */
+static apr_status_t ap_method_registry_destroy(void *notused)
+{
+ methods_registry = NULL;
+ cur_method_number = METHOD_NUMBER_FIRST;
+ return APR_SUCCESS;
+}
+
+AP_DECLARE(void) ap_method_registry_init(apr_pool_t *p)
+{
+ methods_registry = apr_hash_make(p);
+ apr_pool_cleanup_register(p, NULL,
+ ap_method_registry_destroy,
+ apr_pool_cleanup_null);
+}
+
+AP_DECLARE(int) ap_method_register(apr_pool_t *p, char *methname)
+{
+ int *newmethnum;
+
+ if (methods_registry == NULL) {
+ ap_method_registry_init(p);
+ }
+
+ if (methname == NULL) {
+ return M_INVALID;
+ }
+
+ if (cur_method_number > METHOD_NUMBER_LAST) {
+ /* The method registry has run out of dynamically
+ * assignable method numbers. Log this and return M_INVALID.
+ */
+ ap_log_perror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, p,
+ "Maximum new request methods %d reached while registering method %s.",
+ METHOD_NUMBER_LAST, methname);
+ return M_INVALID;
+ }
+
+ newmethnum = (int*)apr_palloc(p,sizeof(int));
+ *newmethnum = cur_method_number++;
+ apr_hash_set(methods_registry, methname, APR_HASH_KEY_STRING, newmethnum);
+
+ return *newmethnum;
+}
+
/* Get the method number associated with the given string, assumed to
* contain an HTTP method. Returns M_INVALID if not recognized.
*
@@ -308,6 +366,8 @@
*/
AP_DECLARE(int) ap_method_number_of(const char *method)
{
+ int *methnum = NULL;
+
switch (*method) {
case 'H':
if (strcmp(method, "HEAD") == 0)
@@ -362,6 +422,16 @@
return M_UNLOCK;
break;
}
+
+ /* check if the method has been dynamically registered */
+ if (methods_registry != NULL) {
+ methnum = (int*)apr_hash_get(methods_registry,
+ method,
+ APR_HASH_KEY_STRING);
+ if (methnum != NULL)
+ return *methnum;
+ }
+
return M_INVALID;
}
@@ -904,7 +974,7 @@
static char *make_allow(request_rec *r)
{
char *list;
- int mask;
+ apr_int64_t mask;
mask = r->allowed_methods->method_mask;
list = apr_pstrcat(r->pool,
@@ -2073,8 +2143,8 @@
char **methods;
/*
- * If it's one of our known methods, use the shortcut and use the
- * bitmask.
+ * If it's a known methods, either builtin or registered
+ * by a module, use the bitmask.
*/
methnum = ap_method_number_of(method);
l->method_mask |= ~(1 << methnum);
1.131 +6 -18 httpd-2.0/server/config.c
Index: config.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/config.c,v
retrieving revision 1.130
retrieving revision 1.131
diff -u -r1.130 -r1.131
--- config.c 2001/07/04 03:16:33 1.130
+++ config.c 2001/08/02 04:25:20 1.131
@@ -354,30 +354,18 @@
AP_DECLARE(int) ap_method_is_limited(cmd_parms *cmd, const char *method) {
int methnum;
- int i;
- char **xmethod;
methnum = ap_method_number_of(method);
+
/*
- * The simple case: a method hard-coded into Apache.
+ * A method number either hardcoded into apache or
+ * added by a module and registered.
*/
if (methnum != M_INVALID) {
- return (methnum & cmd->limited);
- }
- /*
- * Some extension method we don't know implicitly.
- */
- if ((cmd->limited_xmethods == NULL)
- || (cmd->limited_xmethods->nelts == 0)) {
- return 0;
- }
- xmethod = (char **) cmd->limited_xmethods->elts;
- for (i = 0; i < cmd->limited_xmethods->nelts; ++i) {
- if (strcmp(method, xmethod[i]) == 0) {
- return 1;
- }
+ return (cmd->limited & (1<<methnum));
}
- return 0;
+
+ return 0; /* not found */
}
AP_DECLARE(void) ap_register_hooks(module *m, apr_pool_t *p)
1.33 +10 -35 httpd-2.0/server/core.c
Index: core.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/core.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -r1.32 -r1.33
--- core.c 2001/08/01 19:15:22 1.32
+++ core.c 2001/08/02 04:25:20 1.33
@@ -1466,7 +1466,7 @@
const char *arg) {
const char *limited_methods = ap_getword(cmd->pool, &arg, '>');
void *tog = cmd->cmd->cmd_data;
- int limited = 0;
+ apr_int64_t limited = 0;
const char *errmsg;
const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT);
@@ -1476,46 +1476,21 @@
while (limited_methods[0]) {
char *method = ap_getword_conf(cmd->pool, &limited_methods);
- int methnum = ap_method_number_of(method);
+ int methnum;
+ /* check for builtin or module registered method number */
+ methnum = ap_method_number_of(method);
+
if (methnum == M_TRACE && !tog) {
return "TRACE cannot be controlled by <Limit>";
}
else if (methnum == M_INVALID) {
- char **xmethod;
- register int i, j, k;
-
- /*
- * Deal with <Limit> by adding the method to the list.
- */
- if (!tog) {
- if (cmd->limited_xmethods == NULL) {
- cmd->limited_xmethods = apr_array_make(cmd->pool, 2,
- sizeof(char *));
- }
- xmethod = (char **) apr_array_push(cmd->limited_xmethods);
- *xmethod = apr_pstrdup(cmd->pool, method);
- }
- /*
- * <LimitExcept>, so remove any/all occurrences of the method
- * in the extension array.
- */
- else if ((cmd->limited_xmethods != NULL)
- && (cmd->limited_xmethods->nelts != 0)) {
- xmethod = (char **) cmd->limited_xmethods->elts;
- for (i = 0; i < cmd->limited_xmethods->nelts; i++) {
- if (strcmp(xmethod[i], method) == 0) {
- for (j = i, k = i + 1;
- k < cmd->limited_xmethods->nelts;
- ++j, ++k) {
- xmethod[j] = xmethod[k];
- }
- cmd->limited_xmethods->nelts--;
- }
- }
- }
+ /* method has not been registered yet, but resorce restriction
+ * is always checked before method handling, so register it.
+ */
+ methnum = ap_method_register(cmd->pool, method);
}
- limited |= (1 << methnum);
+ limited |= (1 << methnum);
}
/* Killing two features with one function,
1.36 +20 -3 httpd-2.0/server/protocol.c
Index: protocol.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/protocol.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- protocol.c 2001/07/30 04:38:02 1.35
+++ protocol.c 2001/08/02 04:25:20 1.36
@@ -1135,14 +1135,31 @@
AP_DECLARE(int) ap_vrprintf(request_rec *r, const char *fmt, va_list va)
{
- char buf[4096];
+ char *buf;
+ int buf_size = 4096; /* start with a 4k buffer */
apr_size_t written;
if (r->connection->aborted)
return -1;
- /* ### fix this mechanism to allow more than 4K of output */
- written = apr_vsnprintf(buf, sizeof(buf), fmt, va);
+ buf = apr_palloc(r->pool, buf_size);
+ while (1) {
+ written = apr_vsnprintf(buf, buf_size, fmt, va);
+
+ /*
+ * Per the apr_vsnprintf comments, in no event does apr_snprintf return a negative number.
+ * Therefore, it's not possible to distinguish between an output which was truncated,
+ * and an output which exactly filled the buffer.
+ */
+ if (written == buf_size) {
+ buf_size *= 2;
+ buf = apr_palloc(r->pool, buf_size); /* want realloc */
+ }
+ else {
+ break;
+ }
+ }
+
if (buffer_output(r, buf, written) != APR_SUCCESS)
return -1;
Re: cvs commit: httpd-2.0/server config.c core.c protocol.c
Posted by Ryan Bloom <rb...@covalent.net>.
On Wednesday 01 August 2001 21:25, rbb@apache.org wrote:
> rbb 01/08/01 21:25:20
>
> Modified: . CHANGES
> include http_config.h http_core.h http_protocol.h httpd.h
> modules/aaa mod_access.c
> modules/http http_protocol.c
> server config.c core.c protocol.c
> Log:
> Add the ability to extend the methods that Apache understands
> and have those methods <limit>able in the httpd.conf. It uses
> the same bit mask/shifted offset as the original HTTP methods
> such as M_GET or M_POST, but expands the total bits from an int to
> an ap_int64_t to handle more bits for new request methods than
> an int provides.
> Submitted by: Cody Sherr <cs...@covalent.net>
Okay, now can we remove the ap_method_list_* functions?
Ryan
_____________________________________________________________________________
Ryan Bloom rbb@apache.org
Covalent Technologies rbb@covalent.net
-----------------------------------------------------------------------------
Re: cvs commit: httpd-2.0/server config.c core.c protocol.c
Posted by Ryan Morgan <rm...@covalent.net>.
On Thu, Aug 02, 2001 at 04:25:20AM -0000, rbb@apache.org wrote:
> rbb 01/08/01 21:25:20
>
> Modified: . CHANGES
> include http_config.h http_core.h http_protocol.h httpd.h
> modules/aaa mod_access.c
> modules/http http_protocol.c
> server config.c core.c protocol.c
> Log:
> Add the ability to extend the methods that Apache understands
> and have those methods <limit>able in the httpd.conf. It uses
> the same bit mask/shifted offset as the original HTTP methods
> such as M_GET or M_POST, but expands the total bits from an int to
> an ap_int64_t to handle more bits for new request methods than
> an int provides.
> Submitted by: Cody Sherr <cs...@covalent.net>
>
<snip>
>
> static int find_allowdeny(request_rec *r, apr_array_header_t *a, int method)
> {
> +
> allowdeny *ap = (allowdeny *) a->elts;
> - int mmask = (1 << method);
> + apr_int64_t mmask = (1 << method);
> int i;
> int gothost = 0;
> const char *remotehost = NULL;
>
There are a lot of places that do bit shifts like this, but they will not
work for method numbers > 32 since most compilers will treat the 1 as an
integer. Casting the 1 to apr_int64_t fixes the problem. I can put
together a patch, or someone with commit access can just go in and fix it.
-Ryan
Re: cvs commit: httpd-2.0/server config.c core.c protocol.c
Posted by Ryan Bloom <rb...@covalent.net>.
On Wednesday 01 August 2001 21:25, rbb@apache.org wrote:
> rbb 01/08/01 21:25:20
>
> Modified: . CHANGES
> include http_config.h http_core.h http_protocol.h httpd.h
> modules/aaa mod_access.c
> modules/http http_protocol.c
> server config.c core.c protocol.c
> Log:
> Add the ability to extend the methods that Apache understands
> and have those methods <limit>able in the httpd.conf. It uses
> the same bit mask/shifted offset as the original HTTP methods
> such as M_GET or M_POST, but expands the total bits from an int to
> an ap_int64_t to handle more bits for new request methods than
> an int provides.
> Submitted by: Cody Sherr <cs...@covalent.net>
Okay, now can we remove the ap_method_list_* functions?
Ryan
_____________________________________________________________________________
Ryan Bloom rbb@apache.org
Covalent Technologies rbb@covalent.net
-----------------------------------------------------------------------------