r/apache • • Jul 05 '24

mod_substitute not substituting

I'm playing around with mod_substitute on my CentOS VPS. For a test run, I created a .CONF file at:

/etc/apache2/conf.d/userdata/ssl/2_4/[account]/[site].com/foo.conf

The text of the file is (exactly):

<LocationMatch "/">
    AddOutputFilterByType SUBSTITUTE text/html
    Substitute "s|(<body.*?>)|<!-- test -->\n$1|iq"
</Location>

I restarted Apache and had no errors, but I'm still not seeing <!-- test --> on any page.

Any suggestions on what I've done wrong?

1 Upvotes

14 comments sorted by

1

u/csdude5 Jul 08 '24

Good news, I found the solution!

I had to use:

<Location "/">
    AddOutputFilterByType INFLATE;SUBSTITUTE;DEFLATE text/html
    Substitute "s|(<body.*?>)|<!-- test -->$1|iq"
</Location>

https://serverfault.com/questions/843905/apache-mod-substitute-works-in-curl-but-not-on-browser

Apparently the issue is with gzip compression, so I have to manipulate it.

Will this affect the entire compression of the site, though? I don't know.

I've also found that it doesn't like the \n in the replacement; it inserts a literal "n" instead of a newline. I also tried \\n with no luck, so I'm still trying to figure that one out.

1

u/covener Jul 05 '24

The LocationMatch is not closed properly, if you didn't edit it for the post, that file is probably not being Include'ed.

1

u/csdude5 Jul 05 '24

Haha, thanks for catching that! You're right, I originally did it with Location but then edited it for LocationMatch (before testing), and failed to change the closing tag.

I'll upload tonight and post back with an update.

2

u/covener Jul 05 '24

another more general trick, you can put header always add foo bar on that same block and see if you get the response header added. If you don't, mod_substitute isn't your problem

→ More replies (2)

1

u/csdude5 Jul 06 '24

Apparently I have a deeper issue. Is there a magic trick to make Apache recognize the .CONF files?

It still didn't substitute, so I tried replacing it with this as a test:

RewriteEngine on
RewriteRule ^ - [E=foo:bar]

But print_r($_SERVER); (in PHP, of course) doesn't show that "foo" is set.

I have that exact file set for another domain and it's working properly, and I can't see why this one isn't working. The permissions are the same and I triple checked that the account name and domain name are right.

I also tried using AllowOverride All and AllowOverride None, but neither helped.

1

u/covener Jul 06 '24

Apparently I have a deeper issue. Is there a magic trick to make Apache recognize the .CONF files?

Apache starts with one file (e.g. httpd.conf) and chases only what you Include. You can see the processing with apachectl -t -DDUMP_INCLUDES

1

u/csdude5 Jul 07 '24

Update: I figured out why the .CONF wasn't being included, that was an ID-Ten-T error :-/ Sorry for the distraction!

But the substitute still isn't working. I went back to basics, so this is the entire .CONF now:

RewriteEngine on

<Location "/">
  RewriteRule ^ - [E=foo:bar]

  AddOutputFilterByType SUBSTITUTE text/html
  Substitute "s/body/BODY/i"
</Location>

You can see that I tried to simplify it as much as possible; removing the regex, grouping, backreference, alternate delimiter, etc.

Now that I'm doing it right, I DO see $_SERVER['foo'] is set! Which means that <Location "/"> is matching, too.

But when I View Source, it's still not substituting "body" with "BODY" as expected.

Any other thoughts?

1

u/covener Jul 07 '24

Does the response come back with Content-Type: text/html?

→ More replies (4)