Forum Moderators: phranque

Message Too Old, No Replies

mod substitute not substituting

         

csdude55

5:57 pm on Jul 7, 2024 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I have this test in a .CONF file:

RewriteEngine on

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

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



And I'm using this basic PHP script to see the results:

<?php
echo <<<EOF
<html>
<head>
<title>Test</title>
</head>

<body>
<pre>

EOF;

print_r($_SERVER);

echo <<<EOF

</pre>
</body>
</html>
EOF;
?>


I see that $_SERVER['foo'] equals "bar", so the configuration is working properly and <Location> is matching. But "body" isn't being replaced with "BODY".

I'm using Apache 2.4.59, and EasyApache (via WHM) definitely shows that mod_substitute is installed. And I would assume that, if it wasn't, I would get an error when I rebuild Apache.

I double checked using Google's Dev Tools > Network > Name > Response Headers, and "Content-Type" shows:

text/html; charset=UTF-8

I'm running out of ideas! LOL Any other thoughts on why it's not substituting as expected?

lucy24

10:43 pm on Jul 7, 2024 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I see that $_SERVER['foo'] equals "bar", so the configuration is working properly and <Location> is matching.
But it’s not a rock-solid test, since it involves different modules.

:: quick run to Apache docs, since I’ve never done anything with mod_substitute ::

Context:directory, .htaccess
I wish they wouldn't say this and then turn right around and give all their examples using <Location>. Are we to understand that for present purposes they are interchangeable?

Since the substitution involves case changing, did you try it without the "i"? (Yes, I know the flag applies to the pattern, but let’s eliminate all options.)

Edit: Also try it with a bit of regular text, not an html directive. I wouldn’t put it past the server and/or your browser and/or gremlins to flatten the html casing.

csdude55

11:49 pm on Jul 7, 2024 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Haha, @lucy24, I knew you would be the first in line to reply <3

Since the substitution involves case changing, did you try it without the "i"? (Yes, I know the flag applies to the pattern, but let’s eliminate all options.) Edit: Also try it with a bit of regular text, not an html directive.

My first test was:

Substitute "s|(<body.*?>)|<!-- test -->\n$1|iq"

But that didn't work, either.

I tried to simplify it by removing the regex, grouping, backreference, and alternate delimiter, but it still didn't work.

I DID figure out, though, that it doesn't like \n! I'm pretty sure that \\n is required, but since nothing has worked I can't swear to that.

I'll try without the /i flag tonight. I THINK that I tried that last night, but I can't swear to that, either.

[edited by: phranque at 8:24 am (utc) on Jul 8, 2024]
[edit reason] disable graphic smile faces [/edit]

csdude55

4:33 am on Jul 8, 2024 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Good news, I found the solution!

I had to use:

AddOutputFilterByType INFLATE;SUBSTITUTE;DEFLATE text/html


[serverfault.com...]

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...

lucy24

5:13 pm on Jul 8, 2024 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I knew you would be the first in line
Well, you never know when some wild out-of-left-field notion will lead to a solution.

But now I’m intrigued by
Substitute "s|(<body.*?>)|<!-- test -->\n$1|iq"
The .*? bit seems perilous in the extreme. Does mod_substitute's RegEx engine do single-line or whole text? If the idea is to potentially include things like <body class = "classname"> (I used to have a fair number of these in a directory that used a small number of possible color schemes for the individual pages) I’d say
<body[^>]*>
instead.

In any case I don’t think the \n is needed. This is about generating html, right? In general, html doesn't care about line breaks--or whitespace of any kind--unless it’s necessary to separate words, like the “body class” above. Not like certain Apache mods one could name ;) where spaces and linebreaks carry syntactic meaning.

Will this affect the entire compression of the site, though?
It seems as if it would only apply to that category of files that are being substituted, i.e. all html files. If the real substitution (as opposed to the ones shown here for testing and/or posting purposes) is only meant to happen in a few files, then the AddOutputFilter business, along with the Substitute rule, could instead go in a <Files> or <Directory> envelope, whatever is appropriate.

csdude55

6:21 pm on Jul 8, 2024 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



My plan is to offer free Wordpress hosting, with the condition of a single floating banner (Infolinks) at the bottom of the page and using Hydro.online. Both of those require 2 lines of script in the HEAD, though, and since I can't trust the user to not remove it then I turned to forcing it via .CONF.

Right now, substituting </head> is resulting in this one long line:

<script type="text/javascript">var infolinks_pid = foo;var infolinks_wsid = 0;</script><script type="text/javascript" src="//resources.infolinks.com/js/infolinks_main.js"></script><script id="hydro_config" type="text/javascript">window.Hydro_tagId = "foo";</script><script id="hydro_script" src="https://track.hydro.online/"></script></head>


Which would be fine, except that Hydro can't tell that it's installed and I THINK it's because there's no \n. It works on the sites where I've installed it manually, and that's the only difference that I can see.

They're looking into it now, so it might not be important other than general readability.

If the real substitution (as opposed to the ones shown here for testing and/or posting purposes) is only meant to happen in a few files...

It would actually be on all text/html pages on the sites, but these would be small sites with low traffic so it's probably not all that important.

lucy24

8:26 pm on Jul 8, 2024 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Aha. I think javascript does care about line breaks, at least within a function. Otherwise it thinks it's meeting a mid-line semicolon, which is probably Not Allowed.

It might also work if instead you made a single-line SSI (no, it doesn't require changing everything to .shtml) and Included an external file containing all the scripts.

But if this is a WP site, isn't everything php?

csdude55

4:03 am on Jul 9, 2024 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I THINK that just adding a whitespace between the tags fixed it :-) At least, Hydro recognizes it now. Infolinks still isn't showing an ad, but that might just be because I'm testing on a tiny site.

But if this is a WP site, isn't everything php?

I honestly have zero experience with Wordpress, that's why it's one I'd rather give away! So I can offer little to no support. But I can't force these tags in any way that the user could circumvent, which is why I'm trying to do it via Apache configuration.