Apache 2.4.3 SSI if expr no variables?
Asked Answered
D

5

6

I have many files with small differences. The included file contains this, which tries to differentiate on one part of a longer path:

<!--#if expr="${DOCUMENT_URI}=/internet/"-->Internet<!--#else-->Intranet<!--#endif-->

In the error log I get

AH01337: Could not parse expr "${DOCUMENT_URI}=/internet/" in /opt/apache/htdocs/ssi/time.shtml: Parse error near '$'

I find many variations on this theme, like no braces, parentheses around the inside of the quotes, space before the comment end or =~, but nothing helps. There doesn't seem to be a debug setting for mod_include, which would tell me what's wrong...

Another variant I found is

<!--#if expr='"${DOCUMENT_URI}"=~/internet/'-->

this gives no error. But it always chooses the else branch, likewise with REQUEST_URI, as though the variables were unset. But I can echo them fine. I also tried /.+internet.+/ in case it was anchoring this.

Since these are CGI variables I also tried loading cgid_module – no good either.

Diarthrosis answered 28/1, 2013 at 18:40 Comment(1)
Ok, found it. Apparently they changed everything in 2.4 and you now need the undocumented (except by example) v function to access variables by name. So this works: <!--#if expr='v("REQUEST_URI")=~/internet/'-->Diarthrosis
S
11

As of version 2.3.13, mod_include has switched to the new ap_expr syntax for conditional expressions in #if flow control elements.

Add the SSILegacyExprParser on directive to switch to the old syntax which is compatible with Apache HTTPD version 2.2.x and earlier.

http://httpd.apache.org/docs/current/mod/mod_include.html#ssilegacyexprparser

Shamus answered 4/7, 2013 at 23:25 Comment(2)
Instead of enabling legacy conditional expressions, can you suggest how to rewrite the conditional so it doesn't use deprecated syntax?Unweighed
@Unweighed I've given an alternative answer which provides this, and links to the ap_expr syntax format examples.Minoan
M
3

As many other people noted you can use the v("foo") style, but the examples given in the Apache 2.4 documentation (http://httpd.apache.org/docs/2.4/expr.html#examples) give this form:

<!--#if expr="%{DOCUMENT_URI} =~ /internet/"-->Internet<!--#else-->Intranet<!--#endif-->

Note the % instead of $ on the variable, and the =~ for regex match.

I've just tested this and it works fine.

(Or use SSILegacyExprParser on as also mentioned, to allow for backward-compatibility with the 2.2.x format. But I expect this compatibility will be removed at some point in the distant future..)

Minoan answered 17/8, 2016 at 10:34 Comment(0)
R
1

Newer Apache versions use ap_expr. I just wanted to add the relevant link: Apache docs. Note that the v function is not yet documented.

Raby answered 5/2, 2013 at 13:4 Comment(1)
It is documented actually. See Functions section of httpd.apache.org/docs/current/expr.html : "reqenv : Lookup request environment variable (as a shortcut, v can be used too to access variables)."Lett
L
1

I got it working with:

 <!--#if expr='v("foo") = "bar"' -->
 foo is bar
 <!--#endif --> 

See Flow Control Elements

Lett answered 8/11, 2015 at 10:31 Comment(0)
C
0

The variable resolves to a text string, so it needs to be enclosed in double quotes, and you need to escape those double quotes.... (warning this may be deprecated syntax - I used it on my old Apache 1 and just never changed it when upgrading):

<!--# if expr="\"$DOCUMENT_URI\"=/internet/" -->
Cheesecake answered 26/5, 2013 at 13:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.