[MAGNOLIA-2936] Error pages not served properly Created: 10/Nov/09  Updated: 23/Jan/13  Resolved: 15/Dec/09

Status: Closed
Project: Magnolia
Component/s: cache
Affects Version/s: None
Fix Version/s: 4.2.2

Type: Bug Priority: Major
Reporter: Magnolia International Assignee: Jan Haderka
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
relation
is related to MAGNOLIA-2178 Error pages are sent with gzip headers Closed
is related to MAGNOLIA-2968 security: login form fails to render ... Closed
Template:
Acceptance criteria:
Empty
Task DoD:
[ ]* Doc/release notes changes? Comment present?
[ ]* Downstream builds green?
[ ]* Solution information and context easily available?
[ ]* Tests
[ ]* FixVersion filled and not yet released
[ ]  Architecture Decision Record (ADR)
Bug DoR:
[ ]* Steps to reproduce, expected, and actual results filled
[ ]* Affected version filled
Date of First Response:

 Description   

If a user tries to access a page which is protected by content-security-filter (as opposed to uri-security-filter, which is located before the cache and gzip filters), the error page is simply not served. This is fairly obvious when looking at the code:

        if (statusCode != HttpServletResponse.SC_OK) {
            return;
        }

This links back to MAGNOLIA-2178, but

  • commenting that bit out seems to work fine (tried Safari 3.0.4, 3.2.1, 4.0.3, Firefox 3.0.4), I can't seem the reproduce the problems of MAGNOLIA-2178
  • I'm trying to see what changes could have made this work/fail before, but I can't quite see it right now.

Given the current code of GZipFilter, if there was indeed an incompatibility between error pages headers and the fact these pages are gzipped, we could anyway easily serve those non-zipped. (it wasn't that trivial when GZipFilter was wrapping the response's output with a GZipOutputStream)



 Comments   
Comment by Jan Haderka [ 11/Nov/09 ]

AFAIK the problem here is with the errors that come not from magnolia but from the underlying server infrastructure. In case of Magnolia related errors, the response is not committed even after setting the error header, but if it is the Tomcat who gets the error, it will commit the original response because it keeps reference to it and doesn't access the wrapped response that GZipFilter swapped for the original.
To reproduce the issue, that the above code snippet is trying to prevent, just execute request like http://localhost:8080/magnoliaAuthor/someDummyPage ... if you were not authenticated upfront, the statusCode will be 304 (and response will not be committed) and the login page appear in the browser, however upon hitting the "Login" button, request goes through the whole chain this time, and not being Magnolia page, the statusCode is set to 404 (by tomcat I believe), and when the piece of code above is executed, the response is already committed. If the further processing is not abandoned at this point, the attempt to set the gzip encoding header will fail, as shown for example at http://paste.debian.net/51266 and the user gets the 500 error instead.
... took me while to figure that out again ... there might be gaps in the "why" this happens, but the "how" should be correct. In any case, the scenario described above can be used to verify the case when code in question is not executed.

Comment by Magnolia International [ 11/Nov/09 ]

The piece of code mentioned above is also necessary for redirects

Comment by Magnolia International [ 13/Nov/09 ]

One of the inline comments says:
//return on error or redirect code, because response is already committed
But as far as I can tell, it's not. For instance in case of 404 and the contents (flat byte array stream) is actually empty at that point (since Magnolia doesn't generate it)

Another thing that might be related or not: the CacheResponseWrapper does not implement containsHeader and probably should. I haven't committed this, since I'm not sure how it should do this:

    public boolean containsHeader(String name) {
        return super.containsHeader(name) || headers.containsKey(name);
// or
        return headers.containsKey(name);
    }

(probably the former, since headers might have been prior to this wrapper)

Comment by Magnolia International [ 13/Nov/09 ]

Also see MAGNOLIA-2472

Comment by Jan Haderka [ 16/Nov/09 ]

But as far as I can tell, it's not. For instance in case of 404 and the contents (flat byte array stream) is actually empty at that point (since Magnolia doesn't generate it)

The call to sendError() method causes response to be committed (check the spec).
Try to run it in debug mode and call response.isCommited() ... As soon as the request goes through the Magnolia filter chain completely and no content is found and the last thing that is done is letting the request go through to the Tomcat so it can try to serve a static content from the webapp (and it also doesn't find anything), the response will be committed even tho we override the sendError() methods in the wrapper response. Just re-run the scenario I described above, you'll see that it is really committed at this point.

Generated at Mon Feb 12 03:41:34 CET 2024 using Jira 9.4.2#940002-sha1:46d1a51de284217efdcb32434eab47a99af2938b.