From 05eb8c17d0c1e45ff076c0580cc5a3ba4bf9e263 Mon Sep 17 00:00:00 2001 From: Sander Striker Date: Sat, 6 Apr 2002 01:11:50 +0000 Subject: [PATCH] Add DASL(SEARCH) support to mod_dav. Submitted by: Sung Kim git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@94486 13f79535-47bb-0310-9956-ffa450edef68 --- modules/dav/fs/repos.c | 3 +- modules/dav/main/mod_dav.c | 89 +++++++++++++++++++++++++++++++++++++- modules/dav/main/mod_dav.h | 37 +++++++++++++++- 3 files changed, 126 insertions(+), 3 deletions(-) diff --git a/modules/dav/fs/repos.c b/modules/dav/fs/repos.c index 0333ea7da5..d9d7aed7da 100644 --- a/modules/dav/fs/repos.c +++ b/modules/dav/fs/repos.c @@ -2097,7 +2097,8 @@ static const dav_provider dav_fs_provider = &dav_hooks_db_dbm, &dav_hooks_locks_fs, NULL, /* vsn */ - NULL /* binding */ + NULL, /* binding */ + NULL /* search */ }; void dav_fs_gather_propsets(apr_array_header_t *uris) diff --git a/modules/dav/main/mod_dav.c b/modules/dav/main/mod_dav.c index bb78e806f0..5822c06cc5 100644 --- a/modules/dav/main/mod_dav.c +++ b/modules/dav/main/mod_dav.c @@ -133,6 +133,7 @@ extern module DAV_DECLARE_DATA dav_module; /* DAV methods */ enum { DAV_M_BIND = 0, + DAV_M_SEARCH, DAV_M_LAST }; static int dav_methods[DAV_M_LAST]; @@ -145,6 +146,7 @@ static int dav_init_handler(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, /* Register DAV methods */ dav_methods[DAV_M_BIND] = ap_method_register(p, "BIND"); + dav_methods[DAV_M_SEARCH] = ap_method_register(p, "SEARCH"); ap_add_version_component(p, "DAV/2"); @@ -265,6 +267,11 @@ const dav_hooks_binding *dav_get_binding_hooks(request_rec *r) return dav_get_provider(r)->binding; } +const dav_hooks_search *dav_get_search_hooks(request_rec *r) +{ + return dav_get_provider(r)->search; +} + /* * Command handler for the DAV directive, which is TAKE1. */ @@ -1427,12 +1434,69 @@ static dav_error *dav_gen_supported_reports(request_rec *r, return NULL; } + +/* handle the SEARCH method */ +static int dav_method_search(request_rec *r) +{ + const dav_hooks_search *search_hooks = DAV_GET_HOOKS_SEARCH(r); + dav_resource *resource; + dav_error *err; + dav_response *multi_status; + + /* If no search provider, decline the request */ + if (search_hooks == NULL) + return DECLINED; + + /* This method should only be called when the resource is not + * visible to Apache. We will fetch the resource from the repository, + * then create a subrequest for Apache to handle. + */ + err = dav_get_resource(r, 1 /* label_allowed */, 0 /* use_checked_in */, + &resource); + if (err != NULL) + return dav_handle_err(r, err, NULL); + + if (!resource->exists) { + /* Apache will supply a default error for this. */ + return HTTP_NOT_FOUND; + } + + /* set up the HTTP headers for the response */ + if ((err = (*resource->hooks->set_headers)(r, resource)) != NULL) { + err = dav_push_error(r->pool, err->status, 0, + "Unable to set up HTTP headers.", + err); + return dav_handle_err(r, err, NULL); + } + + if (r->header_only) { + return DONE; + } + + /* okay... time to search the content */ + /* Let's validate XML and process walk function + * in the hook function + */ + if ((err = (*search_hooks->search_resource)(r, &multi_status)) != NULL) { + /* ### add a higher-level description? */ + return dav_handle_err(r, err, NULL); + } + + /* We have results in multi_status */ + /* Should I pass namespace?? */ + dav_send_multistatus(r, HTTP_MULTI_STATUS, multi_status, NULL); + + return DONE; +} + + /* handle the OPTIONS method */ static int dav_method_options(request_rec *r) { const dav_hooks_locks *locks_hooks = DAV_GET_HOOKS_LOCKS(r); const dav_hooks_vsn *vsn_hooks = DAV_GET_HOOKS_VSN(r); const dav_hooks_binding *binding_hooks = DAV_GET_HOOKS_BINDING(r); + const dav_hooks_search *search_hooks = DAV_GET_HOOKS_SEARCH(r); dav_resource *resource; const char *dav_level; char *allow; @@ -1617,6 +1681,11 @@ static int dav_method_options(request_rec *r) apr_table_addn(methods, "BIND", ""); } + /* If there is a search provider, set SEARCH in option */ + if (search_hooks != NULL) { + apr_table_addn(methods, "SEARCH", ""); + } + /* Generate the Allow header */ arr = apr_table_elts(methods); elts = (const apr_table_entry_t *)arr->elts; @@ -1646,6 +1715,19 @@ static int dav_method_options(request_rec *r) apr_table_setn(r->headers_out, "Allow", allow); + + /* If there is search set_option_head function, set head */ + /* DASL: + * DASL: + * DASL: + */ + if (search_hooks != NULL + && *search_hooks->set_option_head != NULL) { + if ((err = (*search_hooks->set_option_head)(r)) != NULL) { + return dav_handle_err(r, err, NULL); + } + } + /* if there was no request body, then there is no response body */ if (doc == NULL) { ap_set_content_length(r, 0); @@ -4513,7 +4595,12 @@ static int dav_handler(request_rec *r) return dav_method_bind(r); } - /* ### add'l methods for Advanced Collections, ACLs, DASL */ + /* DASL method */ + if (r->method_number == dav_methods[DAV_M_SEARCH]) { + return dav_method_search(r); + } + + /* ### add'l methods for Advanced Collections, ACLs */ return DECLINED; } diff --git a/modules/dav/main/mod_dav.h b/modules/dav/main/mod_dav.h index 9abe3c7179..04d83d0290 100644 --- a/modules/dav/main/mod_dav.h +++ b/modules/dav/main/mod_dav.h @@ -268,6 +268,7 @@ typedef struct dav_hooks_vsn dav_hooks_vsn; typedef struct dav_hooks_repository dav_hooks_repository; typedef struct dav_hooks_liveprop dav_hooks_liveprop; typedef struct dav_hooks_binding dav_hooks_binding; +typedef struct dav_hooks_search dav_hooks_search; /* ### deprecated name */ typedef dav_hooks_propdb dav_hooks_db; @@ -612,7 +613,7 @@ typedef struct { const dav_hooks_locks *locks; const dav_hooks_vsn *vsn; const dav_hooks_binding *binding; - + const dav_hooks_search *search; } dav_provider; /* @@ -666,6 +667,7 @@ const dav_hooks_locks *dav_get_lock_hooks(request_rec *r); const dav_hooks_propdb *dav_get_propdb_hooks(request_rec *r); const dav_hooks_vsn *dav_get_vsn_hooks(request_rec *r); const dav_hooks_binding *dav_get_binding_hooks(request_rec *r); +const dav_hooks_search *dav_get_search(request_rec *r); DAV_DECLARE(void) dav_register_provider(apr_pool_t *p, const char *name, const dav_provider *hooks); @@ -677,6 +679,7 @@ const dav_provider * dav_lookup_provider(const char *name); #define DAV_GET_HOOKS_LOCKS(r) dav_get_lock_hooks(r) #define DAV_GET_HOOKS_VSN(r) dav_get_vsn_hooks(r) #define DAV_GET_HOOKS_BINDING(r) dav_get_binding_hooks(r) +#define DAV_GET_HOOKS_SEARCH(r) dav_get_search_hooks(r) /* -------------------------------------------------------------------- @@ -2334,6 +2337,38 @@ struct dav_hooks_binding { }; +/* -------------------------------------------------------------------- +** +** SEARCH(DASL) FUNCTIONS +*/ + +/* search provider hooks */ +struct dav_hooks_search { + /* Set header for a OPTION method + * An error may be returned. + * To set a hadder, this function might call + * apr_table_setn(r->headers_out, "DASL", dasl_optin1); + * + * Examples: + * DASL: + * DASL: + * DASL: + */ + dav_error * (*set_option_head)(request_rec *r); + + /* Search resources + * An error may be returned. *response will contain multistatus + * responses (if any) suitable for the body of the error. It is also + * possible to return NULL, yet still have multistatus responses. + * In this case, typically the caller should return a 207 (Multistatus) + * and the responses (in the body) as the HTTP response. + */ + dav_error * (*search_resource)(request_rec *r, + dav_response **response); + +}; + + /* -------------------------------------------------------------------- ** ** MISCELLANEOUS STUFF -- 2.40.0