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 Swaminathan Bhaskar <bh...@gmx.com> on 2012/03/01 02:01:54 UTC

Intercepting HTTP 301/302 redirects

Hi

Is there anyway to intercept HTTP 301/302 redirects ? I tried 
registering a very simple output filter (AP_FTYPE_RESOURCE) and the 
filter function did not get a callback. I would assume all output goes 
through the filter chain

Rgds
Bhaskar

Re: Intercepting HTTP 301/302 redirects

Posted by Joe Lewis <jo...@joe-lewis.com>.
Congrats!  Welcome to the world of filters!


On 03/01/2012 09:37 AM, Swaminathan Bhaskar wrote:
> Ahh - Finally, I was able to get it working. Thanks for the pointer.
>
> Here is the code snippet:
>
> #include<stdio.h>
> #include<httpd.h>
> #include<http_protocol.h>
> #include<http_config.h>
> #include<http_log.h>
> #include<util_filter.h>
>
> #define MY_FILTER_NAME "myfilter"
>
> static void insert_myfilter(request_rec *req)
> {
>      ap_add_output_filter(MY_FILTER_NAME, NULL, req, req->connection);
>
>      ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, req->server, "mod_myfilter:
> inserted myfilter");
> }
>
> static int my_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
> {
>      if (f->r->status_line != NULL) {
>          ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, f->r->server,
> "mod_myfilter: status = %d, status-line = %s", f->r->status,
> f->r->status_line);
>      }
>      else {
>          ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, f->r->server,
> "mod_myfilter: status = %d", f->r->status);
>      }
>
>      ap_pass_brigade(f->next, bb);
>
>      return APR_SUCCESS;
> }
>
> static void my_filter_hooks(apr_pool_t *pool)
> {
>      ap_register_output_filter(MY_FILTER_NAME, my_output_filter, NULL,
> AP_FTYPE_RESOURCE);
>
>      ap_hook_insert_filter(insert_myfilter, NULL, NULL, APR_HOOK_LAST);
>
>      ap_hook_insert_error_filter(insert_myfilter, NULL, NULL, APR_HOOK_LAST);
>
>      fprintf(stderr, "mod_myfilter: registered my_output_filter\n");
> }
>
> module AP_MODULE_DECLARE_DATA myfilter_module = {
>      STANDARD20_MODULE_STUFF,
>      NULL,
>      NULL,
>      NULL,
>      NULL,
>      NULL,
>      my_filter_hooks
> };
>
> Rgds
> Bhaskar

Re: Intercepting HTTP 301/302 redirects

Posted by Swaminathan Bhaskar <bh...@gmx.com>.
Ahh - Finally, I was able to get it working. Thanks for the pointer.

Here is the code snippet:

#include <stdio.h>
#include <httpd.h>
#include <http_protocol.h>
#include <http_config.h>
#include <http_log.h>
#include <util_filter.h>

#define MY_FILTER_NAME "myfilter"

static void insert_myfilter(request_rec *req)
{
    ap_add_output_filter(MY_FILTER_NAME, NULL, req, req->connection);
    
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, req->server, "mod_myfilter:
inserted myfilter");
}

static int my_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
{
    if (f->r->status_line != NULL) {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, f->r->server,
"mod_myfilter: status = %d, status-line = %s", f->r->status,
f->r->status_line);
    }
    else {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, f->r->server,
"mod_myfilter: status = %d", f->r->status);
    }
    
    ap_pass_brigade(f->next, bb);
    
    return APR_SUCCESS;
}

static void my_filter_hooks(apr_pool_t *pool)
{
    ap_register_output_filter(MY_FILTER_NAME, my_output_filter, NULL,
AP_FTYPE_RESOURCE);
    
    ap_hook_insert_filter(insert_myfilter, NULL, NULL, APR_HOOK_LAST);
    
    ap_hook_insert_error_filter(insert_myfilter, NULL, NULL, APR_HOOK_LAST);
    
    fprintf(stderr, "mod_myfilter: registered my_output_filter\n");
}

module AP_MODULE_DECLARE_DATA myfilter_module = {
    STANDARD20_MODULE_STUFF,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    my_filter_hooks
};

Rgds
Bhaskar
-- 
View this message in context: http://old.nabble.com/Intercepting-HTTP-301-302-redirects-tp33418215p33422513.html
Sent from the Apache HTTP Server - Module Writers mailing list archive at Nabble.com.


Re: Intercepting HTTP 301/302 redirects

Posted by Joe Lewis <jo...@joe-lewis.com>.
On 02/29/2012 07:46 PM, Swaminathan Bhaskar wrote:
> Thanks for the quick response Joe. Just to make sure, here is what I did:
>
> <IfModule mod_myfilter.c>
> <Location />
>         SetOutputFilter myfilter
> </Location>
> </IfModule>
>
> and the code
>
> #include <stdio.h>
> #include <httpd.h>
> #include <http_protocol.h>
> #include <http_config.h>
> #include <util_filter.h>
>
> #define MY_FILTER_NAME "myfilter"
>
> static int my_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
> {
>     fprintf(stderr, "mod_myfilter: status = %d, status-line = %s\n", 
> f->r->status, f->r->status_line);
>
>     ap_pass_brigade(f->next, bb);
>
>     return APR_SUCCESS;
> }
>
> static void my_filter_hooks(apr_pool_t *pool)
> {
>     ap_register_output_filter(MY_FILTER_NAME, my_output_filter, NULL, 
> AP_FTYPE_RESOURCE);
>
>     fprintf(stderr, "mod_myfilter: registered my_output_filter\n");
> }
>
> module AP_MODULE_DECLARE_DATA myfilter_module = {
>     STANDARD20_MODULE_STUFF,
>     NULL,
>     NULL,
>     NULL,
>     NULL,
>     NULL,
>     my_filter_hooks
> };
>
> I setup an intentional redirect for testing
>
> Redirect 301 /red.htm http://localhost/green.htm
>
> When I try http://localhost/, should I not see the output from myfilter ?

Maybe.  Remember, errors don't go through the same outputs as regular 
responses.  If you want to filter the results of anything outside of the 
standard 2xx HTTP responses, you have to insert an error filter as well, 
hence my reference to ap_hook_insert_error_filter().  As an example 
(borrowed from some of my source and modified for yours) :

static void insert_my_output_error_filter(request_rec *r) {
   ap_add_output_filter(MY_FILTER_NAME,NULL,r,r->connection);
}

static void my_filter_hooks(apr_pool_t *p) {
   ap_hook_insert_error_filter(insert_my_output_error_filter, NULL, 
NULL, APR_HOOK_LAST);
   
ap_register_output_filter(MY_FILTER_NAME,my_output_filter,NULL,AP_FTYPE_RESOURCE);
};

Again, output filters and errors do not coincide.  If you want to catch 
both, you have to hook both.  (Same thing for r->headers_out and 
r->err_headers_out - r->headers_out won't make it into r->err_headers_out).

Joe
--
http://www.silverhawk.net

Re: Intercepting HTTP 301/302 redirects

Posted by Swaminathan Bhaskar <bh...@gmx.com>.
Thanks for the quick response Joe. Just to make sure, here is what I did:

<IfModule mod_myfilter.c>
<Location />
         SetOutputFilter myfilter
</Location>
</IfModule>

and the code

#include <stdio.h>
#include <httpd.h>
#include <http_protocol.h>
#include <http_config.h>
#include <util_filter.h>

#define MY_FILTER_NAME "myfilter"

static int my_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
{
     fprintf(stderr, "mod_myfilter: status = %d, status-line = %s\n", 
f->r->status, f->r->status_line);

     ap_pass_brigade(f->next, bb);

     return APR_SUCCESS;
}

static void my_filter_hooks(apr_pool_t *pool)
{
     ap_register_output_filter(MY_FILTER_NAME, my_output_filter, NULL, 
AP_FTYPE_RESOURCE);

     fprintf(stderr, "mod_myfilter: registered my_output_filter\n");
}

module AP_MODULE_DECLARE_DATA myfilter_module = {
     STANDARD20_MODULE_STUFF,
     NULL,
     NULL,
     NULL,
     NULL,
     NULL,
     my_filter_hooks
};

I setup an intentional redirect for testing

Redirect 301 /red.htm http://localhost/green.htm

When I try http://localhost/, should I not see the output from myfilter ?

May be I am doing something wrong ?

Also you indicated I need to hook into ap_hook_insert_error_filter - 
would you by any chance have any sample code ?

Rgds
Bhaskar

On 02/29/2012 08:06 PM, Joe Lewis wrote:
> On 02/29/2012 06:01 PM, Swaminathan Bhaskar wrote:
>> Hi
>>
>> Is there anyway to intercept HTTP 301/302 redirects ? I tried 
>> registering a very simple output filter (AP_FTYPE_RESOURCE) and the 
>> filter function did not get a callback. I would assume all output 
>> goes through the filter chain
>>
>> Rgds
>> Bhaskar
>
> Did you hook the ap_hook_insert_error_filter function?  For errors, 
> you need that one.
>
> Joe
> -- 
> http://www.silverhawk.net/


Re: Intercepting HTTP 301/302 redirects

Posted by Joe Lewis <jo...@joe-lewis.com>.
On 02/29/2012 06:01 PM, Swaminathan Bhaskar wrote:
> Hi
>
> Is there anyway to intercept HTTP 301/302 redirects ? I tried 
> registering a very simple output filter (AP_FTYPE_RESOURCE) and the 
> filter function did not get a callback. I would assume all output goes 
> through the filter chain
>
> Rgds
> Bhaskar

Did you hook the ap_hook_insert_error_filter function?  For errors, you 
need that one.

Joe
--
http://www.silverhawk.net/