2017-03-17 22:33 GMT+01:00 Luca Toscano <toscano.l...@gmail.com>:

>
>
> 2017-03-09 22:47 GMT+01:00 Luca Toscano <toscano.l...@gmail.com>:
>
>>
>>
>> 2017-02-24 23:27 GMT+01:00 Luca Toscano <toscano.l...@gmail.com>:
>>
>>> Hi everybody,
>>>
>>> the following users@ question is interesting in my opinion:
>>>
>>> 2017-02-20 18:17 GMT+01:00 Mike Schlottman <mschl...@spe.org>:
>>>
>>>>
>>>> The problem comes when I combine these 2 so that all users except those
>>>> coming from 127.*.*.* or 192.168.*.* see the nice error page.
>>>>
>>>> <If  "! %{HTTP:X-Real-IP}  -ipmatch '127.0.0.0/8' ">
>>>>
>>>>   <If  "! %{HTTP:X-Real-IP}  -ipmatch '192.168.0.0/16' ">
>>>>
>>>>     ErrorDocument 404 /errors/404
>>>>
>>>>   </If>
>>>>
>>>> </If>
>>>>
>>>> The user from 172.28.1.84 does not get the nice 404 page, but the
>>>> default 404 page.   The IP does not match either of the ranges as observed
>>>> when using the ranges individually, but when combined in this way it does
>>>> not work as expected.
>>>>
>>>>
>>>>
>>>> Any ideas why this is?
>>>>
>>>>
>>>>
>>>
>>> He ended up using a single if with an expression composed by the two
>>> conditions in && to solve the problem, but I started to wonder why this
>>> configuration does not work. I tested the "nested ifs" config with trace8
>>> logging and it seem that only the outermost <If> expression gets evaluated.
>>>
>>> Is there a specific reason why this happens? I'd expect two possible
>>> outcomes from this configuration, namely either a syntax error while
>>> parsing the config (preferred imho) or a context merge, but not a no-op.
>>>
>>> Any pointers/suggestions about where to look?
>>>
>>>
>> I tried to investigate a bit the problem to write a good explanation in
>> the docs (and also to better understand the httpd internals for fun) but I
>> am still far from a satisfactory result.
>>
>> I tried the following config (inside other containers like Location too):
>>
>> <If  "true">
>>     ErrorDocument 503 "This is a custom 503 inside the outer IF!"
>>     <If "true">
>>        ErrorDocument 503 "This is a custom 503 inside the inner IF!"
>>     </If>
>> </If>
>>
>> Each time that 503 is generated, I get the "outer IF" 503 response, never
>> the inner one.
>>
>> With gdb it is easy to see that when ap_if_walk is executed,
>> dconf->sec_if->nelts is 1, so only one of the Ifs is evaluated.
>>
>> So I checked how the if sections are parsed and built
>> with 
>> ap_process_config_tree->ap_walk_config->ap_walk_config_sub->invoke_cmd->ifsection
>> and eventually ap_add_if, but I only got that the parent/child relationship
>> is set up correctly.
>>
>> My only goal is to figure out if nested Ifs are not evaluated on purpose
>> and if so why they are allowed by the syntax checker. Eventually it would
>> be really great to update the docs (regular user docs and also
>> https://httpd.apache.org/docs/trunk/developer/request.html).
>>
>>
> This time (hopefully) I think I found what I was looking for, namely why
> nested <If> blocks are definitely not going to work.
>
> The ap_if_walk (request.c) function gets the core_dir_config settings
> via ap_get_core_module_config(r->per_dir_config), retrieving all the <If>
> containers using the sec_if field, and then iterating through them to
> evaluate their (apr_expr) conditions.
>
> In order to be able to use nested <If> blocks ap_if_walk would need to
> check, for each sec_if->elts element of the core's r->per_dir_config, if it
> contains a sec_if blocks too (and restart the process of checking its
> condition etc..). Something like:
>
> AP_DECLARE(int) ap_if_walk(request_rec *r) {
> [..]
>     /* Go through the if entries, and check for matches  */
>     for (sec_idx = 0; sec_idx < num_sec; ++sec_idx) {
>         core_dir_config *entry_core;
>         entry_core = ap_get_core_module_config(sec_ent[sec_idx]);
>         if(entry_core->sec_if->nelts > 0) { .. /* handling nested <If>s */
> .. }
> [..]
>
> In this way we would allow arbitrary nesting of <If> blocks in the httpd
> config. I am not advocating for this solution but we should either allow
> nested <If> blocks or explicitly warn the users when httpd checks its
> config that a nested configuration will be silently ignored (emitting an
> explicit configuration error while parsing the config would be even better
> but probably too invasive for 2.4.x releases).
>

Documentation updated with the current status, plus the following patch
seems to allow nested if blocks (probably not the best one but it is a pof):

http://home.apache.org/~elukey/httpd-trunk-core-nested_if_blocks.patch

 Luca

Reply via email to