https://issues.apache.org/bugzilla/show_bug.cgi?id=51197

Konstantin Kolinko <knst.koli...@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|FIXED                       |

--- Comment #5 from Konstantin Kolinko <knst.koli...@gmail.com> 2012-02-20 
01:00:26 UTC ---
(In reply to comment #4)
> There is a unit test already for this issue that passes. I expanded it
> to cover calling
> sendError in a new thread and the same thread (this is one of the specifics 
> the
> report is lacking) and both tests pass with BIO.

For reference,
the test is TestAsyncContextImpl - search for "51197" and see r1124342 and
r1290875

The test does not check what response text is sent to the client. It just
checks response status and the access log.

It might be that client is responded with correct HTTP status line, but HTTP
response content is empty.


1. I tried to update the doTestBug51197(..) test in TestAsyncContextImpl to
test for error message, but it is not trivial.
As of now it is not possible to use the ByteChunk passed to getUrl() call. The
URLConnection used to implement getUrl() cannot read content if response code
is >= 400.  If I remove status code check in TomcatBaseTest#getUrl() to always
read response text regardless of status code, it just fails with an
IOException:

[[[
Testcase: testBug51197b took 4,188 sec
    Caused an ERROR
Server returned HTTP response code: 400 for URL:
http://localhost:3596/asyncErrorServlet
java.io.IOException: Server returned HTTP response code: 400 for URL:
http://localhost:3596/asyncErrorServlet
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at
sun.net.www.protocol.http.HttpURLConnection$6.run(HttpURLConnection.java:1491)
    at java.security.AccessController.doPrivileged(Native Method)
    at
sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.java:1485)
    at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1139)
    at
org.apache.catalina.startup.TomcatBaseTest.getUrl(TomcatBaseTest.java:239)
    at
org.apache.catalina.startup.TomcatBaseTest.getUrl(TomcatBaseTest.java:206)
    at
org.apache.catalina.startup.TomcatBaseTest.getUrl(TomcatBaseTest.java:200)
    at
org.apache.catalina.core.TestAsyncContextImpl.doTestBug51197(TestAsyncContextImpl.java:1207)
    at
org.apache.catalina.core.TestAsyncContextImpl.testBug51197b(TestAsyncContextImpl.java:1177)

Caused by: java.io.IOException: Server returned HTTP response code: 400 for
URL: http://localhost:3596/asyncErrorServlet
    at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1436)
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
    at
org.apache.catalina.startup.TomcatBaseTest.getUrl(TomcatBaseTest.java:232)
]]]


2. I enabled access log in the test, by adding the following line to
build.properties:

test.accesslog=true

The access log shows as if error message was sent to the client - see bytes
count in the last column:
[[[
127.0.0.1 - - [20/Feb/2012:04:14:50 +0400] "GET /asyncErrorServlet HTTP/1.1"
400 5 http-bio-127.0.0.1-auto-32-exec-2 3985
127.0.0.1 - - [20/Feb/2012:04:14:56 +0400] "GET /asyncErrorServlet HTTP/1.1"
400 5 http-bio-127.0.0.1-auto-33-exec-3 4000

127.0.0.1 - - [20/Feb/2012:04:15:50 +0400] "GET /asyncErrorServlet HTTP/1.1"
400 5 http-nio-127.0.0.1-auto-32-exec-2 4000
127.0.0.1 - - [20/Feb/2012:04:15:56 +0400] "GET /asyncErrorServlet HTTP/1.1"
400 5 http-nio-127.0.0.1-auto-33-exec-3 4000

127.0.0.1 - - [20/Feb/2012:04:16:57 +0400] "GET /asyncErrorServlet HTTP/1.1"
400 5 http-apr-127.0.0.1-auto-32-exec-3 4000
127.0.0.1 - - [20/Feb/2012:04:17:02 +0400] "GET /asyncErrorServlet HTTP/1.1"
400 5 http-apr-127.0.0.1-auto-33-exec-4 4000
]]]


3. Finally I was able to reproduce the issue.
I extracted AsyncErrorServlet as a standalone class, configured a simple web
application and tried to access it directly. It reproduces the issue! The
response is empty. Moreover access log shows that only 5 bytes were sent to the
client.

[[[
127.0.0.1 - - [20/Feb/2012:04:39:53 +0400] "GET
/test/asyncErrorServlet?status=404&treaded=true HTTP/1.1" 404 5
127.0.0.1 - - [20/Feb/2012:04:40:03 +0400] "GET
/test/asyncErrorServlet?status=404&treaded=false HTTP/1.1" 404 5
127.0.0.1 - - [20/Feb/2012:04:40:42 +0400] "GET /test/asyncErrorServlet
HTTP/1.1" 500 1472
]]]

I converted the constructor arguments to request parameters. If I call the
servlet without arguments it fails on parseInt call, and see above - it
responds with proper error 500 message of 1472 bytes.

I will attach the war below.


4. sendError() call as used in Comment 3 interacts with error handling.
I have not tested how it behaves when there is a custom error page configured.

5. BTW, r1290875 has not been merged into 7.0.x yet.

-- 
Configure bugmail: https://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to