On 18/09/2011 11:34, Sorin Manolache wrote:
On Thu, Sep 15, 2011 at 12:52, Martin Townsend
<[email protected]> wrote:
Hi,
I have an output filter that parses custom tags to retrieve data from an
application running on the same device.
Everything was working well until I tried to move some HTML into Server Side
Include pages. Snippet below:
<?smu smu extio_sensor_read mappings ?>
<?smu smu extio_read front_ana all led ?>
<?smu smu extio_read rear_ana all led ?>
<!--#include virtual="/include/SSI_SensorStatus.html" -->
<!--#include virtual="/include/SSI_SensorStatusAnalogRear.html" -->
The first three commands will populate hash tables that are saved in my
output filters context.
The HTML in the included pages then use custom tags to query the hash tables
but for some reason the hash tables are NULL.
Having stepped through with the debugger I can see that the pointer to the
output filter when processing the main HTML page is different to the one
when parsing custom tags in SSI pages. Looking through mod_include I can
see it creates a sub request for include and sub requests call
make_sub_request to create a new filter. Should this new filter also
inherit the output filters context? Am I doing something wrong with my use
of mod_include? I've tried moving my filter so it's after mod_include but
still the same problem.
I'm using Server version: Apache/2.2.19 (Unix) on an ARM board.
Best Regards,
Martin.
How do you construct the context of your filter? At the first
invokation of the filter or in the init function of the filter?
In the second case, it could be that you construct the context twice,
the first time in the main request processing and the second time in
the subrequest processing.
In my opinion, apache uses the same filter structure in both the main
and the sub request. In mod_includes apache creates a subrequest,
passing f->next to it. Thus, the first filter in the filter chain of
the subrequest is the filter succeeding the INCLUDES filter. In my
opinion, if you place your filter before the INCLUDES filter, your
filter should not be called in the subrequest if yours is a
AP_FTYPE_RESOURCE filter. If you place your filter after the INCLUDES
filter, the hash tables you mention are not initialised at the time
when your filter processes the responses of the includes subrequests.
I am not sure of what I'm saying because I have no experience in how
mod_includes interacts with other filters. Anyway, I hope this helps.
Have a look in server/request.c at make_sub_request. The subrequest
inherits the protocol filters of the main request, but not all of the
non-protocol output filters of the main request. Maybe you should make
your filter a AP_FTYPE_PROTOCOL filter such that it is not removed
from the chain by mod_includes.
S
Hi,
Thanks for the reply, I create the context when the filter is invoked,
below is my output filter hook that I use.
apr_status_t
smu_output_filter(
ap_filter_t * filter_in_p,
apr_bucket_brigade * bb_in_p
) {
if(APR_BRIGADE_EMPTY(bb_in_p)) {
return APR_SUCCESS;
}
/* If this filter has been called for the first time then create a
new one */
if(!filter_in_p->ctx) {
rv = mod_smu_output_filter_ctx_init(filter_in_p);
if(rv != APR_SUCCESS) {
/* If we fail to initialise let other filters try and
finish. */
return ap_pass_brigade(filter_in_p->next, bb_in_p);
}
....
}
Here is the code that registers it
ap_register_output_filter(
smu_output_filter_name,
smu_output_filter,
NULL,
AP_FTYPE_RESOURCE + 2);
So it should be after the "include" filter.
I've stepped through the code and the filter_in_p->ctx of the sub
request is NULL so I then create a new one. As Joachim suggests this is
expected behaviour I need a method of storing my hash tables so they are
preserved across requests and sub requests. So 2 questions
1) In my output filter can I get the context of the main requests filter
and use this in the sub request.
2) If not what other mechanism can I use, as these hash tables only need
to persist for the lifetime of the request is there something in the
request structure. Maybe use the "notes" table where the value
parameter is cast to a pointer to a hash table.
Thanks in advance,
Martin.