1

I have some files that exist under a directory and its name contains a question mark.

I'm trying to replace the ? with %3F (URL encoded ?) but I get a "404 Not Found" response. Numbers in the URL are dynamic.

What I have:

https://www.example.com/uploads/10015015?afe/filename.doc

What I need:

https://www.example.com/uploads/10015015%3Fafe/filename.doc

This is the rule I added in .htaccess but it doesn't work:

RewriteCond %{QUERY_STRING} ^?afe([^&]*)
RewriteRule (.*) /$1%3F%{QUERY_STRING}? [L]
2
  • 1
    QUERY_STRING contains the question mark, as your own regex tests. You then embed this after %3F. Seems one question mark too many, no? Commented Jan 26, 2024 at 1:02
  • @deceze Although the QUERY_STRING server var does not contain the question mark, which is part of the problem. Commented Jan 26, 2024 at 1:36

1 Answer 1

0
RewriteCond %{QUERY_STRING} ^?afe([^&]*)
RewriteCond %{QUERY_STRING} !=""
RewriteRule (.*) /$1%3F%{QUERY_STRING}? [L]

The QUERY_STRING server variable does not contain the ? itself (query string delimiter). However, the regex ^?afe([^&]*) is entirely invalid (the ? is a regex quantifier and ^ is not quantifiable) so this would/should result in a 500 Internal Server Error since the regex cannot be compiled. (Although you say you are getting a 404, so is this rule even being processed?!)

There's no need to check that the query string is not empty (second condition) when you have already established that there is a query string that matches the pattern (in the first condition).

Try the following instead:

RewriteCond %{QUERY_STRING} ^afe/[^&]+\.doc$
RewriteRule ^(uploads/.+) $1\%3F%{QUERY_STRING} [NE,QSD,L]

Note that the % before 3 must be backslash-escaped to avoid it being treated as a numeric backreference (which would otherwise be empty).

I removed the slash prefix on the substitution string so it would be treated as a relative file-path, as opposed to a URL-path (unless you have a RewriteBase directive set).

The QSD (Query String Discard) flag is the preferred way to discard the original query string from the request on Apache 2.4, rather than appending an empty query string (trailing ?) which would have been required on earlier versions of Apache.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. I can download the files now but the problem is the files are named with the numbers string. E.g: example.com/uploads/10015015?afe/filename.doc The downloaded file is renamed as 10015015.doc instead filename.doc
@lccv If you are downloading this to a Windows machine then ? is not a permitted character in Windows filenames (a limitation of the OS). To control the default filename you would need to replace the ? with some other character and use this in the filename field of the Content-Disposition header as the file is downloaded.
The file name would be the result of the browser still effectively seeing a query string. To avoid that, you could redirect to a different URL externally first - say, /uploads/10015015_afe/filename.doc - and then rewrite that to the question mark version for file system access again, internally. (But in that case, I would rather rename the folder to begin with - and then at most rewrite old external links, that still use the old version.)

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.