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/04 19:19:53 UTC

Calling another URL from output filter

Hello,

How can I call another url from an output filter - here is the scenario:
when a client accesses abc.mydomain.com/signon, this url autheticates the
user and we dont want the response going back to the client rather call
another url xyz.mydomain.com/fetchdata which will return some data ... we
want to send the data from the second url and response headers from first
url merged back to the client. So my thought is to intercept the response
from the first url in an output ffilter and make a call from the output
filter to the second url. What function call would allow me to make th call
to the second url Any help appreciated

Rgds
Bhaskar
-- 
View this message in context: http://old.nabble.com/Calling-another-URL-from-output-filter-tp33439259p33439259.html
Sent from the Apache HTTP Server - Module Writers mailing list archive at Nabble.com.


Re: Calling another URL from output filter

Posted by Nick Kew <ni...@apache.org>.
On Sun, 4 Mar 2012 10:19:53 -0800 (PST)
Swaminathan Bhaskar <bh...@gmx.com> wrote:

> 
> Hello,
> 
> How can I call another url from an output filter 

The easy way is to use a subrequest.  "Include Virtual"
from mod_includes is an example.

-- 
Nick Kew

Re: Calling another URL from output filter

Posted by Sorin Manolache <so...@gmail.com>.
On 2012-03-16 02:57, Swaminathan Bhaskar wrote:
> Hi Sorin
>
> Can you share your code for this cae so that I can take a look to get an
> understanding. Can I call a uri on a different server before the proxy
> to the requested server ?
>


My conf on pqr.mydomain.com looks something like

<Location /my_url>
   RewriteEngine On
   RewriteRule .*  http://xyz.mydomain.com/fetchdata [P]
</Location>

<Proxy http://xyz.mydomain.com/fetchdata>
# access control directives (Order, Allow, Deny, etc)
    ProxyPass http://xyz.mydomain.com/fetchdata keepalive=On
</Proxy>

<Proxy http://abc.mydomain.com/signon>
# access control directives (Order, Allow, Deny, etc)
# RequestHeader directives to block/enable/edit the
# request headers to the signon server
    ProxyPass http://abc.mydomain.com/signon keepalive=On
</Proxy>

RewriteCond %{IS_SUBREQ} true
RewriteRule /internal_signon http://abc.mydomain.com/signon [P]


So the client accesses http://pqr.mydomain.com/my_url. My module makes a 
subrequest to /internal_signon. The rewrite rule redirects to 
http://abc.mydomain.com/signon. My module consumes the response of 
http://abc.mydomain.com/signon without producing any output. Then my 
handler returns DECLINED. Because it declines, the proxy module takes 
over and makes the request to http://xyz.mydomain.com/fetchdata.

The request to /internal_signon is made in a fixups hook. My fixups hook 
has to execute before mod_rewrite's fixup hook. So I register it as follows:

static const char * const fixups_succ[] = {"mod_rewrite.c", 
"mod_headers.c", NULL};
ap_hook_fixups(&fixups, NULL, fixups_succ, APR_HOOK_MIDDLE);

My fixups callback does something like this:

int fixups(request_rec *r) {
   if (!ap_is_initial_req(r))
      return DECLINED;
   // other conditions to see if we should handle it
   Data data;
   make_request("/internal_signon", r, &data);
   // use the data.
   return OK;
}

void make_request(const char *url, request_rec *r, Data *data) {
   request_rec *newreq = ap_sub_req_lookup_uri(url, r, NULL);
   if (NULL == newreq)
     ; // err_handler

   ap_set_module_config(newreq->request_config, &mymodule, data);

   ap_filter_t *flt = ap_add_output_filter("subreqflt", 0, newreq, 
newreq->connection);
   if (NULL == flt) {
     ap_destroy_sub_req(newreq);
     // err_handler;
   }

   int proxy_ret_code = ap_run_sub_req(newreq);
   int ret_code = newreq->status;

   ap_destroy_sub_req(newreq);

   if (ap_is_HTTP_ERROR(proxy_ret_code) || ap_is_HTTP_ERROR(ret_code)) {
     // err_handler
   }
}


The filter "subreqflt" gets the data object

Data *data = (Data *)ap_get_module_config(flt->r->request_config, 
&mymodule);

It parses the response, extracts from it the relevant data and puts them 
in the "data" object.

The subrequest response parsing is a "normal" filter. The only 
difference is that it does never "return ap_pass_brigade(flt->next, 
bb)". It always does "return APR_SUCCESS". Thus, downstream filters, 
like the one that sends the response to the client, are not called. The 
filter acts like a sink for the subrequest data.


Sorin


> Rgds
> Bhaskar
>
> On 03/05/2012 04:26 AM, Sorin Manolache wrote:
>> On 2012-03-04 19:19, Swaminathan Bhaskar wrote:
>>>
>>> Hello,
>>>
>>> How can I call another url from an output filter - here is the scenario:
>>> when a client accesses abc.mydomain.com/signon, this url autheticates
>>> the
>>> user and we dont want the response going back to the client rather call
>>> another url xyz.mydomain.com/fetchdata which will return some data
>>> ... we
>>> want to send the data from the second url and response headers from
>>> first
>>> url merged back to the client. So my thought is to intercept the
>>> response
>>> from the first url in an output ffilter and make a call from the output
>>> filter to the second url. What function call would allow me to make
>>> th call
>>> to the second url Any help appreciated
>>
>>
>> Hello,
>>
>> We did something similar but we didn't issue the 2nd request from the
>> output filter of the first.
>>
>> The first request was made by the apache subrequest API (the
>> ap_sub_req_lookup_uri and ap_run_sub_req functions). The output filter
>> ran until it encountered an end-of-stream. It did not make any other
>> request. The output filter of the subrequest did not pass any brigade
>> to downstream filters. It simply parsed the response, stored relevant
>> data in some structure and returned APR_SUCCESS to its upstream filters.
>>
>> Next, after ap_run_sub_req returned, we invoked the 2nd URL via the
>> proxy module. The useful data returned by the 1st URL was taken from
>> the structure in which the subrequest stored it.
>>
>> Calling a 2nd URL from output filters is a bit tricky, as you have
>> filter-chains invoked from within a filter-chain, so we preferred to
>> call the 2nd URL only after the request to the first completed.
>>
>> Regards,
>> Sorin
>>
>


Re: Calling another URL from output filter

Posted by Swaminathan Bhaskar <bh...@gmx.com>.
Hi Sorin

Can you share your code for this cae so that I can take a look to get an 
understanding. Can I call a uri on a different server before the proxy 
to the requested server ?

Rgds
Bhaskar

On 03/05/2012 04:26 AM, Sorin Manolache wrote:
> On 2012-03-04 19:19, Swaminathan Bhaskar wrote:
>>
>> Hello,
>>
>> How can I call another url from an output filter - here is the scenario:
>> when a client accesses abc.mydomain.com/signon, this url autheticates 
>> the
>> user and we dont want the response going back to the client rather call
>> another url xyz.mydomain.com/fetchdata which will return some data 
>> ... we
>> want to send the data from the second url and response headers from 
>> first
>> url merged back to the client. So my thought is to intercept the 
>> response
>> from the first url in an output ffilter and make a call from the output
>> filter to the second url. What function call would allow me to make 
>> th call
>> to the second url Any help appreciated
>
>
> Hello,
>
> We did something similar but we didn't issue the 2nd request from the 
> output filter of the first.
>
> The first request was made by the apache subrequest API (the 
> ap_sub_req_lookup_uri and ap_run_sub_req functions). The output filter 
> ran until it encountered an end-of-stream. It did not make any other 
> request. The output filter of the subrequest did not pass any brigade 
> to downstream filters. It simply parsed the response, stored relevant 
> data in some structure and returned APR_SUCCESS to its upstream filters.
>
> Next, after ap_run_sub_req returned, we invoked the 2nd URL via the 
> proxy module. The useful data returned by the 1st URL was taken from 
> the structure in which the subrequest stored it.
>
> Calling a 2nd URL from output filters is a bit tricky, as you have 
> filter-chains invoked from within a filter-chain, so we preferred to 
> call the 2nd URL only after the request to the first completed.
>
> Regards,
> Sorin
>


Re: Calling another URL from output filter

Posted by Sorin Manolache <so...@gmail.com>.
On 2012-03-04 19:19, Swaminathan Bhaskar wrote:
>
> Hello,
>
> How can I call another url from an output filter - here is the scenario:
> when a client accesses abc.mydomain.com/signon, this url autheticates the
> user and we dont want the response going back to the client rather call
> another url xyz.mydomain.com/fetchdata which will return some data ... we
> want to send the data from the second url and response headers from first
> url merged back to the client. So my thought is to intercept the response
> from the first url in an output ffilter and make a call from the output
> filter to the second url. What function call would allow me to make th call
> to the second url Any help appreciated


Hello,

We did something similar but we didn't issue the 2nd request from the 
output filter of the first.

The first request was made by the apache subrequest API (the 
ap_sub_req_lookup_uri and ap_run_sub_req functions). The output filter 
ran until it encountered an end-of-stream. It did not make any other 
request. The output filter of the subrequest did not pass any brigade to 
downstream filters. It simply parsed the response, stored relevant data 
in some structure and returned APR_SUCCESS to its upstream filters.

Next, after ap_run_sub_req returned, we invoked the 2nd URL via the 
proxy module. The useful data returned by the 1st URL was taken from the 
structure in which the subrequest stored it.

Calling a 2nd URL from output filters is a bit tricky, as you have 
filter-chains invoked from within a filter-chain, so we preferred to 
call the 2nd URL only after the request to the first completed.

Regards,
Sorin