skip to Main Content

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.

3

Answers


  1. 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>
    
    Login or Signup to reply.
  2. 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]
    
    Login or Signup to reply.
  3. 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 header 410 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
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search