1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-08 15:02:10 +03:00

Add support for arbitrary extension methods for the Allow

response header field, and an API routine for modifying the
	allowed list in a unified manner for both known and extension
	methods.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@86043 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Ken Coar
2000-08-10 11:22:57 +00:00
parent a5121d5061
commit 702dd42deb
4 changed files with 99 additions and 18 deletions

View File

@@ -106,7 +106,23 @@ API_EXPORT(void) ap_internal_redirect_handler(const char *new_uri, request_rec *
API_EXPORT(int) ap_some_auth_required(request_rec *r); API_EXPORT(int) ap_some_auth_required(request_rec *r);
API_EXPORT(int) ap_is_initial_req(request_rec *r); API_EXPORT(int) ap_is_initial_req(request_rec *r);
API_EXPORT(void) ap_update_mtime(request_rec *r, apr_time_t dependency_mtime); API_EXPORT(void) ap_update_mtime(request_rec *r, apr_time_t dependency_mtime);
/**
* Add one or more methods to the list permitted to access the resource.
* Usually executed by the content handler before the response header is
* sent, but sometimes invoked at an earlier phase if a module knows it
* can set the list authoritatively. Note that the methods are ADDED
* to any already permitted unless the reset flag is non-zero. The
* list is used to generate the Allow response header field when it
* is needed.
* @param r The pointer to the request identifying the resource.
* @param reset Boolean flag indicating whether this list should
* completely replace any current settings.
* @param ... A NULL-terminated list of strings, each identifying a
* method name to add.
* @return None.
* @deffunc void ap_allow_methods(request_rec *r, int reset, ...)
*/
API_EXPORT(void) ap_allow_methods(request_rec *r, int reset, ...);
#ifdef CORE_PRIVATE #ifdef CORE_PRIVATE
/* Function called by main.c to handle first-level request */ /* Function called by main.c to handle first-level request */
void ap_process_request(request_rec *); void ap_process_request(request_rec *);

View File

@@ -666,6 +666,7 @@ struct request_rec {
* handler can't be installed by mod_actions. </PRE> * handler can't be installed by mod_actions. </PRE>
*/ */
int allowed; /* Allowed methods - for 405, OPTIONS, etc */ int allowed; /* Allowed methods - for 405, OPTIONS, etc */
apr_array_header_t *allowed_xmethods; /* Array of extension methods */
/** byte count in stream is for body */ /** byte count in stream is for body */
int sent_bodyct; int sent_bodyct;

View File

@@ -1572,23 +1572,41 @@ static void terminate_header(request_rec *r)
*/ */
static char *make_allow(request_rec *r) static char *make_allow(request_rec *r)
{ {
return 2 + apr_pstrcat(r->pool, char *list;
(r->allowed & (1 << M_GET)) ? ", GET, HEAD" : "",
(r->allowed & (1 << M_POST)) ? ", POST" : "", list = apr_pstrcat(r->pool,
(r->allowed & (1 << M_PUT)) ? ", PUT" : "", (r->allowed & (1 << M_GET)) ? ", GET, HEAD" : "",
(r->allowed & (1 << M_DELETE)) ? ", DELETE" : "", (r->allowed & (1 << M_POST)) ? ", POST" : "",
(r->allowed & (1 << M_CONNECT)) ? ", CONNECT" : "", (r->allowed & (1 << M_PUT)) ? ", PUT" : "",
(r->allowed & (1 << M_OPTIONS)) ? ", OPTIONS" : "", (r->allowed & (1 << M_DELETE)) ? ", DELETE" : "",
(r->allowed & (1 << M_PATCH)) ? ", PATCH" : "", (r->allowed & (1 << M_CONNECT)) ? ", CONNECT" : "",
(r->allowed & (1 << M_PROPFIND)) ? ", PROPFIND" : "", (r->allowed & (1 << M_OPTIONS)) ? ", OPTIONS" : "",
(r->allowed & (1 << M_PROPPATCH)) ? ", PROPPATCH" : "", (r->allowed & (1 << M_PATCH)) ? ", PATCH" : "",
(r->allowed & (1 << M_MKCOL)) ? ", MKCOL" : "", (r->allowed & (1 << M_PROPFIND)) ? ", PROPFIND" : "",
(r->allowed & (1 << M_COPY)) ? ", COPY" : "", (r->allowed & (1 << M_PROPPATCH)) ? ", PROPPATCH" : "",
(r->allowed & (1 << M_MOVE)) ? ", MOVE" : "", (r->allowed & (1 << M_MKCOL)) ? ", MKCOL" : "",
(r->allowed & (1 << M_LOCK)) ? ", LOCK" : "", (r->allowed & (1 << M_COPY)) ? ", COPY" : "",
(r->allowed & (1 << M_UNLOCK)) ? ", UNLOCK" : "", (r->allowed & (1 << M_MOVE)) ? ", MOVE" : "",
", TRACE", (r->allowed & (1 << M_LOCK)) ? ", LOCK" : "",
NULL); (r->allowed & (1 << M_UNLOCK)) ? ", UNLOCK" : "",
", TRACE",
NULL);
if ((r->allowed & (1 << M_INVALID)) && (r->allowed_xmethods->nelts)) {
int i;
char **xmethod = (char **) r->allowed_xmethods->elts;
/*
* Append all of the elements of r->allowed_xmethods
*/
for (i = 0; i < r->allowed_xmethods->nelts; ++i) {
list = ap_pstrcat(r->pool, list, ", ", xmethod[i], NULL);
}
}
/*
* Space past the leading ", ". Wastes two bytes, but that's better
* than futzing around to find the actual length.
*/
return list + 2;
} }
API_EXPORT(int) ap_send_http_trace(request_rec *r) API_EXPORT(int) ap_send_http_trace(request_rec *r)

View File

@@ -79,6 +79,9 @@
#include "apr_strings.h" #include "apr_strings.h"
#include "apr_file_io.h" #include "apr_file_io.h"
#include "apr_fnmatch.h" #include "apr_fnmatch.h"
#ifdef APR_HAVE_STDARG_H
#include <stdarg.h>
#endif
AP_HOOK_STRUCT( AP_HOOK_STRUCT(
AP_HOOK_LINK(translate_name) AP_HOOK_LINK(translate_name)
@@ -1425,3 +1428,46 @@ API_EXPORT(void) ap_update_mtime(request_rec *r, apr_time_t dependency_mtime)
r->mtime = dependency_mtime; r->mtime = dependency_mtime;
} }
} }
API_EXPORT(void) ap_allow_methods(request_rec *r, int reset, ...) {
int mnum;
const char *method;
const char **xmethod;
va_list methods;
/*
* Get rid of any current settings if requested; not just the
* well-known methods but any extensions as well.
*/
if (reset) {
r->allowed = 0;
if (r->allowed_xmethods != NULL) {
r->allowed_xmethods->nelts = 0;
}
}
va_start(methods, reset);
while ((method = va_arg(methods, const char *)) != NULL) {
/*
* Look up our internal number for this particular method.
* Even if it isn't one of the ones we know about, the return
* value is used in the same way.
*/
mnum = ap_method_number_of(method);
r->allowed |= (1 << mnum);
/*
* Now, if we don't know about it, we regard it as an
* extension method. Add it to our array of such. This means
* that anything that checks for M_INVALID needs to make an
* additional check of this array if it *is* invalid.
*/
if (mnum == M_INVALID) {
if (r->allowed_xmethods == NULL) {
r->allowed_xmethods = apr_make_array(r->pool, 2,
sizeof(char *));
}
xmethod = (const char **) apr_push_array(r->allowed_xmethods);
*xmethod = method;
}
}
}