I'm trying to handle logically simple operation, but apache rewrite does not handle my website's query strings requests. I heard it's does not do it eventually. Still cannot understand it's regex syntax.

RewriteEngine on
RewriteBase /
#RewriteCond %{QUERY_STRING} ^\?category=([a-z])$ // WHY DO I NEED THIS?
RewriteRule ^!(?category=[a-z]+|?do=[a-z]+)$ [R=404,L,NC]

Goal is to send client to 404 for any query NOT matching /?category=[a-z]+ and /?do=[a-z]+. It would be much better if it's possible to load patterns from the text file.

Apache documentation is poor and Google does not help too.

Please help. Thanks.

1 Answer 1


You need the RewriteCond because RewriteRules only see the path portion of the URL, not the query string. From the documentation:

"What is matched?

In VirtualHost context, The Pattern will initially be matched against the part of the URL after the hostname and port, and before the query string (e.g. "/app1/index.html").

In Directory and htaccess context, the Pattern will initially be matched against the filesystem path, after removing the prefix that lead the server to the current RewriteRule (e.g. "app1/index.html" or "index.html" depending on where the directives are defined).

If you wish to match against the hostname, port, or query string, use a RewriteCond with the %{HTTP_HOST}, %{SERVER_PORT}, or %{QUERY_STRING} variables respectively."

I would also strongly recommend reading the "Per-directory Rewrites" box below that, since that's exactly what you're doing here.

One way to accomplish what you want might be like this:

RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_URI}  !^/$  [OR]
RewriteCond %{QUERY_STRING} !^(category|do)=[a-z]+$
RewriteRule ^ - [R=404,L,NS]

Note how the RewriteRule simply matches everything, and the actual checks are done with the RewriteConds. The first RewriteCond matches if the path portion of the URI doesn't equal /; the second will match either if the first one did (because of the OR flag) or if the query string (sans ?) doesn't match category=[a-z]+ or do=[a-z]+.

(Note: I have not actually tested this code. I think it should work as intended, but it's hard to be sure there are no bugs without testing.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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