Reputation: 2605
I have URLs like https://example.com/page/1234/
and https://example.com/page/9876/
. For these URLs i want set certain status code via htaccess (Apache 2.4).
I try to do it with
<If "%{REQUEST_URI} =~ (1234|9876)\/$">
Header set Status "HTTP/1.1 410 Gone"
</If>
but i seem to have an error in the code, because i don't see the new status code as response in developer tools. How should it be done on the correct way?
PS: i can't use 'rewriteRule' - this kind of setting 410 triggers ErrorDocument, what i don't want. For these two URLs i only want to set the status code. For other URLs, which get 410 on the native way, ErrorDocument shold be triggered.
Upvotes: 3
Views: 4378
Reputation: 45968
Are you wanting the "normal page response" (as generated by your application), but with a 410 HTTP status?
100% correct: usual page, but with response status 410 Gone
Triggering the 410 response in Apache will always serve the appropriate Apache ErrorDocument
. What you could do is set the 410 ErrorDocument
itself to the same URL and trigger the 410 response in the usual way. However, we need to be careful not to create a "rewrite-loop".
For example:
<If "%{REQUEST_URI} =~ m#^/page/(1234|9876)/$# && %{ENV:REDIRECT_STATUS} == ''">
# Capture the URL-path after the slash prefix
SetEnvIf Request_URI "^/(.+)" REL_URL_PATH=$1
# Dynamic ErrorDocument to the same as the requested URL
# The slash prefix in the directive is necessary to be seen as a local URL-path
ErrorDocument 410 /%{reqenv:REL_URL_PATH}
# Trigger 410 Gone
RewriteRule ^ - [G]
</If>
This requires Apache 2.4.13+ due to the expression syntax in the ErrorDocument
directive.
The check against the REDIRECT_STATUS
in the <If>
expression is necessary to avoid a rewrite loop (500 response) when serving the error document itself.
The alternative is to set the 410 response code in your application itself, which would be my preference.
Aside: Setting the Status
HTTP response header, which appears to be what you are trying to do in the question simply sets a Status
HTTP response header, it does not change the HTTP response status itself. (The Status
response header is a non-standard header used by CGI scripts to indicate to the webserver what response code should be set.)
UPDATE: in my tests if i add to htaccess only the rule
Header set Status "HTTP/1.1 410 Gone"
, without any condition, it works like i expect: all URLs from this directory get the header410 Gone
but are still available (ErrorDocument isn't triggered).
Maybe your server is configured differently and is perhaps behind a proxy that sets the HTTP response? But as mentioned above, that simply sets a Status
HTTP response header, it doesn't change the HTTP response code on the request. It doesn't "work" on my test server. (If used at all, the Status
header doesn't normally contain the protocol, it would simply be Header set Status "410 Gone"
.)
So, if this does work for you then you just need to "correct" the syntax in your Apache expression.
For example:
<If "%{REQUEST_URI} =~ m#/(1234|9876)/$#">
Header set Status "HTTP/1.1 410 Gone"
</If>
The above matches any URL that simply ends with /1234/
or /9876/
. Or, to be more specific and match the entire URL use m#^/page/(1234|9876)/$#
. This uses the alternative syntax for delimiting regex (ie. m#<regex>#
), instead of using slashes (ie. /<regex>/
), in order to avoid having to escape the slashes in the pattern.
Alternatively, you don't need the Apache expression, you could use SetEnvIf
and set the header conditionally based on the environment variable.
For example:
SetEnvIf Request_URI "/(1234|9876)/$" GONE=1
Header set Status "HTTP/1.1 410 Gone" env=GONE
Upvotes: 3
Reputation: 786091
You may use this block with <If>
expression that uses default ErrorDocument 410
for a specific URL pattern:
RewriteEngine On
<If "%{REQUEST_URI} =~ m#/(1234|9876)/?$#">
# only for above URL disable ErrorDocument
ErrorDocument 410 default
# set status=410
RewriteRule . - [L,G]
</If>
Upvotes: 3
Reputation: 133760
With your shown samples please try following. Please do clear your browser cache before testing your URLs.
RewriteEngine ON
RewriteRule ^page/(1234|9876)/?$ - [NC,R=410,L]
Upvotes: 2