You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modules-dev@httpd.apache.org by James R Grinter <ja...@uk.nomura.com> on 2007/09/06 15:09:10 UTC

influencing mod_proxy via request_status hook

(If this is better directed at another Apache httpd tech list, please
let me know.)

I'm trying to modify the behaviour of mod_proxy via its optional
request_status hook. I want Apache to use mod_cache's local copy of
a file if it can't verify it with the remote, reverse-proxied server
(server down, or not responding, etc.)

The VirtualHost's Cache and Proxy is configured like this:

    CacheRoot /var/cache
    CacheEnable disk /
    ProxyRequests Off
    ProxyVia On
    <Proxy *>
        Order allow,deny
        Allow from all
    </Proxy>

    ProxyPass /path http://realserver/path
    ProxyPassReverse /path http://realserver/path

    ProxyRemote * http://proxyserver:8080/

The requests are just GETs. "realserver" is the remote server hostname,
and "proxyserver" is the in-between proxy server that the request must
go through (just for that added extra complication.)

I've successfully got my own module being called via the request_status
hook every time. But I can't seem to then make mod_proxy act as if it
had got a 304 HTTP_NOT_MODIFIED from the remote server (which is what
it would normally get if the remote server were to respond) and so
use the locally cached copy of the file.

Whenever the remote server is down, I get the 5xx error from the in-between
proxy. If I take the in-between proxy down, I get an error from within
Apache.

Here's my module's code:

  #include <httpd.h>
  #include <ap_config.h>
  #include <mod_core.h>
  #include <mod_proxy.h>

  static int proxy_request_status_handler ( int *status, request_rec *r )
  {
    ap_log_error(APLOG_MARK,APLOG_ERR,OK,NULL,"request_status hook called (%s): %d (%d)", r->server->server_hostname, *status, r->status);

    if ( r->status >= HTTP_INTERNAL_SERVER_ERROR ) {
      *status = DECLINED;

      ap_log_error(APLOG_MARK,APLOG_ERR,OK,NULL,"request_status hook declined: %d (%d)", *status, r->status);
    }
  }

  static void my_register_hooks(apr_pool_t *p)
  {
    APR_OPTIONAL_HOOK(proxy, request_status, proxy_request_status_handler, NULL, NULL, APR_HOOK_MIDDLE );
  }

  module AP_MODULE_DECLARE_DATA my_module =
  {
    STANDARD20_MODULE_STUFF,
    NULL,                       /* create per-dir config */
    NULL,                       /* merge per-dir config */
    NULL,                       /* server config */
    NULL,                       /* merge server config */
    NULL,                       /* command apr_table_t */
    my_register_hooks           /* register hooks */
  };

Here I'm setting the status code to DECLINED, but I've also tried
setting it to HTTP_NOT_MODIFIED, and I've tried setting the remote
r->status to that too. Clearly that's the wrong thing to do.
What should I be setting? Or should I do this a different way altogether?

James.