From: Daniel Gruno int and
takes a request_rec * and an int and is
called do_something, then declare it like this:
+
AP_DECLARE_HOOK(int, do_something, (request_rec *r, int n))
-
This should go in a header which modules will include if they want to use the hook.
@@ -62,14 +63,13 @@ which is used to record the module functions that use the hook. This is declared as follows: -
- APR_HOOK_STRUCT(
-
- APR_HOOK_LINK(do_something)
- ...
-
+
+ APR_HOOK_STRUCT(
+ APR_HOOK_LINK(do_something)
+ ...
)
-
If the return value of a hook is void, then all the
hooks are called, and the caller is implemented like this:
+
AP_IMPLEMENT_HOOK_VOID(do_something, (request_rec *r, int n), (r, n))
-
The second and third arguments are the dummy argument declaration and the dummy arguments as they will be used when calling the hook. In other words, this macro expands to something like this:
-
- void ap_run_do_something(request_rec *r, int n)
- {
-
- ...
- do_something(r, n);
-
+
+ void ap_run_do_something(request_rec *r, int n)
+ {
+ ...
+ do_something(r, n);
}
-
If the hook returns a value, then it can either be run until the first hook that does something interesting, like so:
-
+
AP_IMPLEMENT_HOOK_RUN_FIRST(int, do_something, (request_rec *r, int n), (r, n), DECLINED)
-
The first hook that does not return DECLINED
stops the loop and its return value is returned from the hook
@@ -123,9 +124,10 @@
value other than one of those two stops the loop, and its
return is the return value. Declare these like so:
+
AP_IMPLEMENT_HOOK_RUN_ALL(int, do_something, (request_rec *r, int n), (r, n), OK, DECLINED)
-
Again, OK and DECLINED are the traditional
values. You can use what you want.
At appropriate moments in the code, call the hook caller, like so:
-
- int n, ret;
- request_rec *r;
-
+
+ int n, ret;
+ request_rec *r;
+
ret=ap_run_do_something(r, n);
-
Include the appropriate header, and define a static function of the correct type:
-
+
static int my_something_doer(request_rec *r, int n)
- {
-
- ...
- return OK;
-
+ {
+ ...
+ return OK;
}
-
- static void my_register_hooks()
- {
-
- ap_hook_do_something(my_something_doer, NULL, NULL, APR_HOOK_MIDDLE);
-
- }
-
- mode MODULE_VAR_EXPORT my_module =
- {
-
- ...
- my_register_hooks /* register hooks */
-
+
+ static void my_register_hooks()
+ {
+ ap_hook_do_something(my_something_doer, NULL, NULL, APR_HOOK_MIDDLE);
+ }
+
+ mode MODULE_VAR_EXPORT my_module =
+ {
+ ...
+ my_register_hooks /* register hooks */
};
-
- static void register_hooks()
- {
-
- static const char * const aszPre[] = { "mod_xyz.c", "mod_abc.c", NULL };
-
- ap_hook_do_something(my_something_doer, aszPre, NULL, APR_HOOK_MIDDLE);
-
+
+ static void register_hooks()
+ {
+ static const char * const aszPre[] = { "mod_xyz.c", "mod_abc.c", NULL };
+
+ ap_hook_do_something(my_something_doer, aszPre, NULL, APR_HOOK_MIDDLE);
}
-
Note that the sort used to achieve this is stable, so
ordering set by APR_HOOK_ORDER is preserved, as far
diff --git a/docs/manual/developer/hooks.xml b/docs/manual/developer/hooks.xml
index 46d778c307c..fe6a1e14a8d 100644
--- a/docs/manual/developer/hooks.xml
+++ b/docs/manual/developer/hooks.xml
@@ -47,9 +47,9 @@
arguments. For example, if the hook returns an int and
takes a request_rec * and an int and is
called do_something, then declare it like this:
This should go in a header which modules will include if they want to use the hook.
@@ -60,14 +60,12 @@ which is used to record the module functions that use the hook. This is declared as follows: -If the return value of a hook is void, then all the
hooks are called, and the caller is implemented like this:
The second and third arguments are the dummy argument declaration and the dummy arguments as they will be used when calling the hook. In other words, this macro expands to something like this:
-If the hook returns a value, then it can either be run until the first hook that does something interesting, like so:
-The first hook that does not return DECLINED
stops the loop and its return value is returned from the hook
@@ -121,9 +117,9 @@
value other than one of those two stops the loop, and its
return is the return value. Declare these like so:
Again, OK and DECLINED are the traditional
values. You can use what you want.
At appropriate moments in the code, call the hook caller, like so:
-Include the appropriate header, and define a static function of the correct type:
-Note that the sort used to achieve this is stable, so
ordering set by APR_HOOK_ORDER is preserved, as far
diff --git a/docs/manual/developer/modguide.html.en b/docs/manual/developer/modguide.html.en
index 00d78a0008a..2dbddf587d8 100644
--- a/docs/manual/developer/modguide.html.en
+++ b/docs/manual/developer/modguide.html.en
@@ -1100,7 +1100,7 @@ different meanings to the user of the server, and thus different contexts
within which modules must operate. For example, let's assume you have this
configuration set up for mod_rewrite:
+
<Directory "/var/www">
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule (.*) http://www.example.com/$1
@@ -1108,7 +1108,8 @@ configuration set up for mod_rewrite:
<Directory "/var/www/sub">
RewriteRule ^foobar$ index.php?foobar=true
</Directory>
-In this example, you will have set up two different contexts for mod_rewrite:
@@ -1654,7 +1655,8 @@ static int example_handler(request_req *r) ap_rprintf(r, "<b>%s</b>: %s<br/>", e[i].key, e[i].val); } return OK; -} +} + @@ -1718,6 +1720,7 @@ static int example_handler(request_req* r) +
+
apr_status_t dummy_filter(ap_filter_t *f, apr_bucket_brigade *bb)
+
- {
-
- if (APR_BRIGADE_EMPTY(bb)) {
-
- return APR_SUCCESS;
-
- }
- ....
-
+ {
+ if (APR_BRIGADE_EMPTY(bb)) {
+ return APR_SUCCESS;
+ }
+ ....
+
- apr_bucket *e = APR_BRIGADE_FIRST(bb);
-const char *data;
-apr_size_t len;
-
-while (e != APR_BRIGADE_SENTINEL(bb)) {
-
- apr_bucket_read(e, &data, &length, APR_BLOCK_READ);
- e = APR_BUCKET_NEXT(e);
-
-}
-
+
+apr_bucket *e = APR_BRIGADE_FIRST(bb);
+const char *data;
+apr_size_t len;
+
+while (e != APR_BRIGADE_SENTINEL(bb)) {
+ apr_bucket_read(e, &data, &length, APR_BLOCK_READ);
+ e = APR_BUCKET_NEXT(e);
+
+}
+
return ap_pass_brigade(bb);
+
+
The above implementation would consume memory proportional to @@ -283,24 +284,25 @@ return ap_pass_brigade(bb); needed and must be allocated only once per response, see the Maintaining state section.
-apr_bucket *e;
-const char *data;
-apr_size_t len;
-
-while ((e = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) {
-
- rv = apr_bucket_read(e, &data, &length, APR_BLOCK_READ);
- if (rv) ...;
- /* Remove bucket e from bb. */
- APR_BUCKET_REMOVE(e);
- /* Insert it into temporary brigade. */
- APR_BRIGADE_INSERT_HEAD(tmpbb, e);
- /* Pass brigade downstream. */
- rv = ap_pass_brigade(f->next, tmpbb);
- if (rv) ...;
- apr_brigade_cleanup(tmpbb);
-
+
+apr_bucket *e;
+const char *data;
+apr_size_t len;
+
+while ((e = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) {
+ rv = apr_bucket_read(e, &data, &length, APR_BLOCK_READ);
+ if (rv) ...;
+ /* Remove bucket e from bb. */
+ APR_BUCKET_REMOVE(e);
+ /* Insert it into temporary brigade. */
+ APR_BRIGADE_INSERT_HEAD(tmpbb, e);
+ /* Pass brigade downstream. */
+ rv = ap_pass_brigade(f->next, tmpbb);
+ if (rv) ...;
+ apr_brigade_cleanup(tmpbb);
}
+
+
-struct dummy_state {
-
- apr_bucket_brigade *tmpbb;
- int filter_state;
- ....
-
-};
-
-apr_status_t dummy_filter(ap_filter_t *f, apr_bucket_brigade *bb)
-{
-
- struct dummy_state *state;
-
- state = f->ctx;
- if (state == NULL) {
-
+
+struct dummy_state {
+ apr_bucket_brigade *tmpbb;
+ int filter_state;
+ ....
+};
+
+apr_status_t dummy_filter(ap_filter_t *f, apr_bucket_brigade *bb)
+{
+
+ struct dummy_state *state;
+
+ state = f->ctx;
+ if (state == NULL) {
+
/* First invocation for this response: initialise state structure.
- */
- }
- f->ctx = state = apr_palloc(sizeof *state, f->r->pool);
-
- state->tmpbb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
- state->filter_state = ...;
-
+ */
+ f->ctx = state = apr_palloc(sizeof *state, f->r->pool);
+
+ state->tmpbb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
+ state->filter_state = ...;
+
+ }
...
-
+
+
-apr_bucket *e;
-apr_read_type_e mode = APR_NONBLOCK_READ;
-
-while ((e = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) {
-
- apr_status_t rv;
-
- rv = apr_bucket_read(e, &data, &length, mode);
- if (rv == APR_EAGAIN && mode == APR_NONBLOCK_READ) {
-
- /* Pass down a brigade containing a flush bucket: */
- APR_BRIGADE_INSERT_TAIL(tmpbb, apr_bucket_flush_create(...));
- rv = ap_pass_brigade(f->next, tmpbb);
- apr_brigade_cleanup(tmpbb);
- if (rv != APR_SUCCESS) return rv;
-
- /* Retry, using a blocking read. */
- mode = APR_BLOCK_READ;
- continue;
-
- } else if (rv != APR_SUCCESS) {
-
- /* handle errors */
-
- }
-
- /* Next time, try a non-blocking read first. */
- mode = APR_NONBLOCK_READ;
- ...
-
+
+apr_bucket *e;
+apr_read_type_e mode = APR_NONBLOCK_READ;
+
+while ((e = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) {
+ apr_status_t rv;
+
+ rv = apr_bucket_read(e, &data, &length, mode);
+ if (rv == APR_EAGAIN && mode == APR_NONBLOCK_READ) {
+
+ /* Pass down a brigade containing a flush bucket: */
+ APR_BRIGADE_INSERT_TAIL(tmpbb, apr_bucket_flush_create(...));
+ rv = ap_pass_brigade(f->next, tmpbb);
+ apr_brigade_cleanup(tmpbb);
+ if (rv != APR_SUCCESS) return rv;
+
+ /* Retry, using a blocking read. */
+ mode = APR_BLOCK_READ;
+ continue;
+ } else if (rv != APR_SUCCESS) {
+ /* handle errors */
+ }
+
+ /* Next time, try a non-blocking read first. */
+ mode = APR_NONBLOCK_READ;
+ ...
}
+
+
The above implementation would consume memory proportional to @@ -277,24 +276,24 @@ return ap_pass_brigade(bb); href="#state">Maintaining state section.
Needs Documentation. Code is:
-
+
if ((access_status = ap_run_access_checker(r)) != 0) {
return decl_die(access_status, "check access", r);
}
@@ -162,7 +162,8 @@
if ((access_status = ap_run_auth_checker(r)) != 0) {
return decl_die(access_status, "check authorization", r);
}
- Needs Documentation. Code is:
-+-if ((access_status = ap_run_access_checker(r)) != 0) { return decl_die(access_status, "check access", r); } @@ -160,8 +160,7 @@ if ((access_status = ap_run_auth_checker(r)) != 0) { return decl_die(access_status, "check authorization", r); } -