Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ErrorPageFilter causes a forwarded request that sends an error to actually send a 200 OK response instead #11814

Closed
tankilo opened this issue Jan 28, 2018 · 1 comment
Assignees
Labels
type: bug A general bug
Milestone

Comments

@tankilo
Copy link

tankilo commented Jan 28, 2018

Question

With default servlet enabled, when deployed in an external Tomcat, the request to non-existent resource returned 200 instead of 404.
I created a demo for this problem. https://github.com/tankilo/spring-boot-problem-demo
Version Info : Spring Boot 1.5.9.RELEASE Tomcat 8.5.24

  1. When i used IDEA to deploy war, visiting http://localhost:8080/ will get 200.
    445bf743-f7f8-4056-9d55-2928f87ceffa
    And in the log ,i found
2018-01-28 09:38:28.495 ERROR 12928 --- [nio-8080-exec-4] o.s.boot.web.support.ErrorPageFilter     : Cannot forward to error page for request [/] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false
  1. When i used IDEA to run com.tankilo.demo.DemoApplication, visiting http://localhost:8080/ will get Spring Whitelabel Error Page.
    image

Personal Understanding

After i debug and compare the two scenes, i find:

  1. Only when deployed as a war will ErrorPageFilter be in used. (SpringBootServletInitializer#createRootApplicationContext)
  2. When running com.tankilo.demo.DemoApplication, even without ErrorPageFilter, ErrorMvcAutoConfiguration will configure Tomcat ErrorPage,and we still see the Whitelabel Error Page.

I am still not clear about this question, is there something wrong with the way i use springboot? -_-

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jan 28, 2018
@wilkinsona wilkinsona self-assigned this Jan 29, 2018
@wilkinsona wilkinsona added type: bug A general bug priority: normal and removed status: waiting-for-triage An issue we've not yet triaged labels Jan 29, 2018
@wilkinsona wilkinsona added this to the 1.5.11 milestone Jan 29, 2018
@wilkinsona
Copy link
Member

wilkinsona commented Jan 29, 2018

The problem here is that the ErrorWrapperResponse that's used by ErrorPageFilter suppresses a call to sendError that's done by the default servlet to send the 404 back. Normally this suppression is desirable as it gives the error page filter a chance to send the error at the right time. However, it doesn't work in this case as the dispatch that has forwarded the request to the default servlet concludes by closing the response's writer which commits the response. Due to the suppression of the call to sendError, the response's status is 200 and that's what the client receives. I think we need to send the suppressed error as soon as an attempt is made to access the response's writer.

@wilkinsona wilkinsona changed the title ErrorPageFilter cause the request to non-existent resource returned 200 instead of 404 ErrorPageFilter causes a forwarded request that sends an error to actually send a 200 OK response instead Jan 29, 2018
@philwebb philwebb modified the milestones: 1.5.11, 1.5.x Mar 21, 2018
@wilkinsona wilkinsona modified the milestones: 1.5.x, 1.5.11 Apr 4, 2018
wilkinsona added a commit to wilkinsona/spring-boot that referenced this issue Apr 9, 2018
Previously, the error page filter used sendError to set the response
status when handling an exception and before forwarding the request
to the error controller. Following the fix for spring-projectsgh-11814, this meant
that the error controller was unable to write its response and the
containers default error page was returned instead.

This commit updates the error page filter to use setStatus rather than
sendError. This ensures that the response has the correct status code
while allowing the error controller to write its body. Tests have
been added to the Tomcat deployment test suite to verify that the
error page filter behaves as intended when dealing with a sent error
and an exception for requests accepting HTML, JSON, or anything.

Closes spring-projectsgh-12787
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

4 participants