1

I have a 3rd party who POST's to a specific page on my website. They post a file and my site does some wizardry with the contents of that file.

The request URL would be for example https://example.com/product-configrator

Sometimes they use a string in their REFERER url like:

https://referrer.com/embed/section.htm?bikes=1

If the referrer passes traffic to me with the argument bikes=1 (contained within the HTTP_REFERER rather than the QUERY_STRING) I'd like to serve up a different page.

Here's an example of an access.log entry where the 3rd party is posting to my site:

 90.xxx.xxx.xxx- - [21/Oct/2019:15:03:51 +0000] "POST /product-configurator HTTP/1.1" 200 23505 "https://referrer.com/embed/products.htm?bikes=1" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36"

So, they're POSTing to my /product-configrator page. I want to redirect this to /bikes-configrator retaining the POST data (using a 307)

I've tested a redirect using some htaccess syntax testing tools but can't get the correct syntax.

RewriteEngine On
RewriteCond %{HTTP_REFERER} ^(.*)\.referrer\.(.*)./*bikes* [NC]
RewriteRule ^(.*)$ https://www.example.com/bikes-configurator [R=307,L]

How can I do this? I know this question has been done to death but I can't see an example that matches my question. I've also asked this question recently on Stack Overflow but the responses I received didn't help me construct a valid entry in my .htaccess file. Any help gratefully appreciated.

10
  • 1
    Any specific reason why you want to externally "redirect" the request rather than internally "rewrite" the request - as the destination appears to be on the same server? (Does the 3rd party follow redirects? Or is this simply a request via a browser?) Are you only wanting to "redirect" POST requests? (Your example rule with also redirect GET.)
    – MrWhite
    Commented Oct 23, 2019 at 8:58
  • If there's a way rewrite internally then that's even better, but I need to retain the POST data (I thought a 307 redirect was the only way of doing this). The 3rd party does nothing except POST to my site - they don't issue any GETS. The rule would just need to work for any traffic coming from the referrer with that string bikes=1 in the HTTP_REFERER string
    – Huskie69
    Commented Oct 23, 2019 at 9:10
  • How is /bikes-configurator then routed in your app? (This presumably does not map directly to a physical file?)
    – MrWhite
    Commented Oct 23, 2019 at 11:01
  • There's a PHP test - something like if (isset($_POST["bike"])) { do stuff ...}
    – Huskie69
    Commented Oct 23, 2019 at 11:04
  • So which PHP file is handling the request?
    – MrWhite
    Commented Oct 23, 2019 at 11:05

1 Answer 1

1

To externally redirect the request from /product-configurator (I assume the missing u was a typo?) to /bikes-configurator when the HTTP Referer contains bikes=1 in the query string part of the URL then you could do something like the following using mod_rewrite near the top of your .htaccess in the document root:

RewriteEngine On

RewriteCond %{HTTP_REFERER} \?.*\bbikes=1\b [NC]
RewriteRule ^product-configurator$ /bikes-configurator [R=307,L]

The RewriteCond directive checks for the URL parameter bikes=1 anywhere in the query string of the Referer HTTP request header.

If this is intended to work for "any traffic" (as suggested in a comment), not just requests for /product-configurator then change the RewriteRule pattern to something like ^ instead.

The 307 status is required for the user-agent to preserve the HTTP method in the redirected request.

Note that this redirects all requests, POST and GET. You could specifically redirect only POST requests if you wish by checking against the REQUEST_METHOD server variable.

The 3rd party does nothing except POST to my site

The "3rd party" needs to be able to follow redirect responses (and submit the 2nd request). An ordinary HTML form submission in a browser will naturally follow the redirect. However, a scripted CURL (for example) may not.


However, it's not clear why you would need to "redirect" the request since this is all happening on the same server. You could potentially internally rewrite the request instead (no external redirect, no second request, quicker and more efficient all round). However, /product-configurator and /bikes-configurator require further routing to get to your PHP script - so "rewriting" to /bikes-configurator is not correct.

UPDATE: In that case, it would be /product-configurator.php

Assuming you are just using extensionless URLs and the underlying file that handles the request is simply /bikes-configurator.php then you can perhaps implement an internal rewrite instead.

For example, instead of the above, this would be written as:

RewriteCond %{HTTP_REFERER} \?.*\bbikes=1\b [NC]
RewriteRule ^product-configurator$ /bikes-configurator.php [L]

The URL in the address bar stays as /product-configurator, but the request is internally rewritten (note the absence of the R flag) to /bikes-configurator.php when bikes=1 is included in the query string of the HTTP Referer. There is no external redirect.

This may also be solvable directly in your PHP script - no additional redirect/rewrite in .htaccess required. (Although from your recent comments, it looks like the request /bike-configurator is simply extensionless and the request maps to the PHP file /bike-configurator.php? The logic that tests the HTTP_REFERER would need to be in /product-configurator.php - you then make the necessary PHP calls to pass control to /bike-configurator.php if the condition is met - but exactly how you do this depends on the structure of your app.)

1
  • How did you get on with this?
    – MrWhite
    Commented Oct 26, 2019 at 20:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.