API_EXPORT(int) ap_some_auth_required(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);
-
+/**
+ * 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
/* Function called by main.c to handle first-level request */
void ap_process_request(request_rec *);
*/
static char *make_allow(request_rec *r)
{
- return 2 + apr_pstrcat(r->pool,
- (r->allowed & (1 << M_GET)) ? ", GET, HEAD" : "",
- (r->allowed & (1 << M_POST)) ? ", POST" : "",
- (r->allowed & (1 << M_PUT)) ? ", PUT" : "",
- (r->allowed & (1 << M_DELETE)) ? ", DELETE" : "",
- (r->allowed & (1 << M_CONNECT)) ? ", CONNECT" : "",
- (r->allowed & (1 << M_OPTIONS)) ? ", OPTIONS" : "",
- (r->allowed & (1 << M_PATCH)) ? ", PATCH" : "",
- (r->allowed & (1 << M_PROPFIND)) ? ", PROPFIND" : "",
- (r->allowed & (1 << M_PROPPATCH)) ? ", PROPPATCH" : "",
- (r->allowed & (1 << M_MKCOL)) ? ", MKCOL" : "",
- (r->allowed & (1 << M_COPY)) ? ", COPY" : "",
- (r->allowed & (1 << M_MOVE)) ? ", MOVE" : "",
- (r->allowed & (1 << M_LOCK)) ? ", LOCK" : "",
- (r->allowed & (1 << M_UNLOCK)) ? ", UNLOCK" : "",
- ", TRACE",
- NULL);
+ char *list;
+
+ list = apr_pstrcat(r->pool,
+ (r->allowed & (1 << M_GET)) ? ", GET, HEAD" : "",
+ (r->allowed & (1 << M_POST)) ? ", POST" : "",
+ (r->allowed & (1 << M_PUT)) ? ", PUT" : "",
+ (r->allowed & (1 << M_DELETE)) ? ", DELETE" : "",
+ (r->allowed & (1 << M_CONNECT)) ? ", CONNECT" : "",
+ (r->allowed & (1 << M_OPTIONS)) ? ", OPTIONS" : "",
+ (r->allowed & (1 << M_PATCH)) ? ", PATCH" : "",
+ (r->allowed & (1 << M_PROPFIND)) ? ", PROPFIND" : "",
+ (r->allowed & (1 << M_PROPPATCH)) ? ", PROPPATCH" : "",
+ (r->allowed & (1 << M_MKCOL)) ? ", MKCOL" : "",
+ (r->allowed & (1 << M_COPY)) ? ", COPY" : "",
+ (r->allowed & (1 << M_MOVE)) ? ", MOVE" : "",
+ (r->allowed & (1 << M_LOCK)) ? ", LOCK" : "",
+ (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)
#include "apr_strings.h"
#include "apr_file_io.h"
#include "apr_fnmatch.h"
+#ifdef APR_HAVE_STDARG_H
+#include <stdarg.h>
+#endif
AP_HOOK_STRUCT(
AP_HOOK_LINK(translate_name)
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;
+ }
+ }
+}