2

I have a simple rule in the .htaccess file, to redirect all requests to inwork.php:

RewriteRule .* php/inwork.php?refpage=%{REQUEST_URI} [L]

But all parameters are missing. For the request http://example.com/example.php?check=1&check=2, I get example.php in inwork.php for $_GET['refpage']. But I want example.php?check=1&check=2 in inwork.php. (There are requests with many parameters in different orders, so I don't want to write them manually in .htaccess.)

Edit: Full htaccess:

Options -Indexes
RewriteEngine On
RewriteBase /

AddOutputFilterByType DEFLATE text/text text/html text/plain text/xml         text/css application/x-javascript application/javascript

RewriteCond %{HTTP_HOST} ^domain.de [NC] 
RewriteRule ^(.*)$ https://www.domain.de/$1 [L,R=301,NE]

RewriteCond %{SERVER_PORT} !^443$
RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]

RewriteCond %{THE_REQUEST} index.html [NC]
RewriteRule ^(.*)index.html /$1 [NC,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^(.*)/pics/(.*)$ [NC]
RewriteRule .* php/inwork.php?refpage=%{REQUEST_URI} [B,L]
7
  • Do you have a preceding condition to this RewriteRule that prevents an undesirable "loop"?
    – MrWhite
    Commented Jan 16, 2019 at 22:31
  • I don't have a specific loop-preventing rule, but that isn't a problem. The inwork.php file handles all request (also "bad" requests) Commented Jan 17, 2019 at 11:55
  • Right, it's just that by itself, the above directive would not work as intended on a default Apache install... the rewriting process starts over (a second time) and ends up rewriting to php/inwork.php?refpage=/php/inwork.php - In other words, it rewrites to itself and refpage ends up containing the script that is processing the request, instead of the URL being requested. If that isn't happening then there must be some other interaction we are not seeing... other directives, other .htaccess files (perhaps in the /php subdirectory)?
    – MrWhite
    Commented Jan 17, 2019 at 23:06
  • You can "edit" your question to add the relevant code. Apart from "looking like a confusing mess", posting unformatted code (especially regex, URLs and XML-like tags) can result in characters being omitted from display.
    – MrWhite
    Commented Jan 21, 2019 at 16:12
  • Thanks - I edited it on the original question and deleted "the mess". Commented Jan 22, 2019 at 17:10

1 Answer 1

4

tl;dr Alternatively, just rewrite to php/inwork.php and parse the PHP superglobal $_SERVER['REQUEST_URI'] instead, which already contains the URL-path and query string from the initial request. (Note that the $_SERVER['REQUEST_URI'] PHP variable is different to the REQUEST_URI Apache server variable, despite the name being the same.)


The REQUEST_URI Apache server variable contains the URL-path only, not the query string. If you want to include the query string from the original URL and make this part of the refpage URL parameter then you need to append the query string as an additional step.

However, I think it is "easier" to grab the entire URL (URL-path + query string) from the THE_REQUEST Apache server variable and pass this instead:

For example:

RewriteCond %{THE_REQUEST} \s(/.+)\s
RewriteRule ^ php/inwork.php?refpage=%1 [B,L]

The %1 backreference contains the full URL (URL-path + query string) from THE_REQUEST, which contains the initial line from the HTTP request (eg. GET /example.php?check=1&check=2 HTTP/1.1).

The B RewriteRule flag URL encodes the captured backreference - necessary in order to make sure everything ultimately belongs to the refpage URL parameter and not become part of the query string on the rewritten request.

You'll then need to manually parse the complete URL (value of the refpage URL param) into its component parts with PHP (which I assume you are already doing)...

For example... given a request for /example.php?check=1&check=2 then the PHP variable $_GET['refpage'] now contains /example.php?check=1&check=2 (having been automatically URL decoded by PHP). (Possibly just your hasty example, but the two check URL params will need special treatment if you want to avoid the later overwriting the former.)


However, unless you have a specific requirement to do it this way, I would simply parse the PHP superglobal $_SERVER['REQUEST_URI'] instead (as mentioned at the top of my answer). This already contains the complete URL from the request - the same value you are manually assigning to the refpage URL parameter. You can then simplify your rewrite:

RewriteRule .* php/inwork.php [L]

UPDATE:

RewriteCond %{THE_REQUEST} index.html [NC]
RewriteRule ^(.*)index.html /$1 [NC,R=301]

You are missing the L flag on the RewriteRule directive. This is a potential problem, since if this directive is triggered (removing index.html) processing will continue and will likely be externally redirected to /php/inwork.php. However, this shouldn't have affected your example URLs.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^(.*)/pics/(.*)$ [NC]
RewriteRule .* php/inwork.php?refpage=%{REQUEST_URI} [B,L]

The first condition here (checking that the request does not map to file) is what prevents the undesirable second loop back to itself.

The second condition that checks that /pics/ is not present in the URL-path can be simplified from !^(.*)/pics/(.*)$ to !/pics/. (No need for capturing subpatterns if they are not being used.)

The B flag is not required here. However, by using the REQUEST_URI server variable, you will naturally lose the query string parameters.

What you can try, is using the QSA flag on the RewriteRule. For example:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !/pics/ [NC]
RewriteRule .* php/inwork.php?refpage=%{REQUEST_URI} [QSA,L]

Although this won't do specifically what you are asking, as the query string parameters won't be part of the refpage URL param, they will be merged with the URL you are rewriting to and consequently should be available in PHP's $_GET array. For example, given a request for /example.php?check=1&check=2 then the $_GET array would be populated as follows:

Array (
  'refpage' => '/example.php',
  'check' => '2',
)

(Because the check URL param is duplicated.)

Additionally, you should also make sure that MultiViews is disabled. Although whether this is actually causing problems in this instance is dependent on your file structure. (It shouldn't be an issue with the example URL you posted.)

Options -Indexes -MultiViews
6
  • Unfourtanetely - RewriteCond %{THE_REQUEST} \s(/.+)\s RewriteRule ^ php/inwork.php?refpage=%1 [B,L] - get me an 403 Error: "Forbidden You don't have permission to access / on this server. Apache/2.4.10 (Debian) Server" and $_SERVER['REQUEST_URI'] in php doesn't contain the paramters. (if I have the complete url in the inwork.php file, it is no problem: I'm good in php, but really bad in the .htaccess stuff) Commented Jan 17, 2019 at 11:50
  • I managed to solve the problem in another way without paramters - thanks anyway Commented Jan 17, 2019 at 13:18
  • Glad you got it sorted. However, the above shouldn't have resulted in a 403 (given the example URL as stated) and nor should the PHP variable $_SERVER['REQUEST_URI'] be absent of parameters in the second example. Perhaps there was a conflict with existing directives? There would certainly seem to be "something else" going on here, given the behaviour of your directive in the question. (?)
    – MrWhite
    Commented Jan 17, 2019 at 23:16
  • I have posted my whole htaccess above (as comment). Perhaps there are strange server-adjustments. I don't know, it isn't my own server. Commented Jan 21, 2019 at 15:59
  • I've updated my answer.
    – MrWhite
    Commented Jan 23, 2019 at 0:02

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.