Bug 57629 - sending large file with Expect: 100-continue wrong messages order
Summary: sending large file with Expect: 100-continue wrong messages order
Status: RESOLVED WONTFIX
Alias: None
Product: Tomcat 8
Classification: Unclassified
Component: Connectors (show other bugs)
Version: 8.0.18
Hardware: PC Linux
: P2 major (vote)
Target Milestone: ----
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-02-24 11:41 UTC by Lorenzo Caenazzo
Modified: 2015-02-26 18:40 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lorenzo Caenazzo 2015-02-24 11:41:26 UTC
With reference ( https://bz.apache.org/bugzilla/show_bug.cgi?id=56725#c7 )
I want to POST/PUT a large amount of data (60MB+) but, following the tips on BUG #56725, I've configured my client to send an Expect: 100-continue.
I think my server needs to authenticate the client BEFORE sending the "100 Continue" response.

This is what i get:

-> PUT /put/URL HTTP/1.1
-> Content-Type: application/json;charset=UTF-8
-> Content-Length: 69748665
-> Host: localhost:8084
-> Connection: Keep-Alive
-> User-Agent: Apache-HttpClient/4.3.6 (java 1.5)
-> Expect: 100-continue
-> Accept-Encoding: gzip,deflate

<- HTTP/1.1 100 Continue

<- HTTP/1.1 401 Unauthorized
<- Server: Apache-Coyote/1.1
<- Set-Cookie: JSESSIONID=00655E5BBBAB2F993D735F5A5B392FB5; Path=/put/; HttpOnly
<- WWW-Authenticate: Basic realm="Spring Security Application"
<- Content-Type: text/html;charset=utf-8
<- Content-Language: en
<- Content-Length: 1104
<- Date: Tue, 24 Feb 2015 10:00:08 GMT
<- Connection: close

<- <!DOCTYPE html><html><head><title>Apache Tomcat/8.0.18 - Error report</title><style type="text/css">H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}.line {height: 1px; background-color: #525D76; border: none;}</style> </head><body><h1>HTTP Status 401 - Full authentication is required to access this resource</h1><div class="line"></div><p><b>type</b> Status report</p><p><b>message</b> <u>Full authentication is required to access this resource</u></p><p><b>description</b> <u>This request requires HTTP authentication.</u></p><hr class="line"><h3>Apache Tomcat/8.0.18</h3></body></html>

-> DATA (truncated by connection reset)

And this is what I expect:

-> PUT /put/URL HTTP/1.1
-> Content-Type: application/json;charset=UTF-8
-> Content-Length: 69748665
-> Host: localhost:8084
-> Connection: Keep-Alive
-> User-Agent: Apache-HttpClient/4.3.6 (java 1.5)
-> Expect: 100-continue
-> Accept-Encoding: gzip,deflate

<- HTTP/1.1 401 Unauthorized
<- Server: Apache-Coyote/1.1
<- Set-Cookie: JSESSIONID=00655E5BBBAB2F993D735F5A5B392FB5; Path=/put/; HttpOnly
<- WWW-Authenticate: Basic realm="Spring Security Application"
<- Content-Type: text/html;charset=utf-8
<- Content-Language: en
<- Content-Length: 1104
<- Date: Tue, 24 Feb 2015 10:00:08 GMT
<- Connection: close

<- ERROR_PAGE

-> PUT /put/URL HTTP/1.1
-> Content-Type: application/json;charset=UTF-8
-> Content-Length: 69748665
-> Host: localhost:8084
-> Authorization: Basic cGFzc3dvcmQK==
-> Connection: Keep-Alive
-> User-Agent: Apache-HttpClient/4.3.6 (java 1.5)
-> Expect: 100-continue
-> Accept-Encoding: gzip,deflate

<- HTTP/1.1 100 Continue

-> DATA
Comment 1 Mark Thomas 2015-02-25 14:13:05 UTC
This is only going to work if Tomcat does the authentication otherwise, as you have observed, Tomcat sends the 100 response before passing the request/response to the application for processing.

One of the aims for Tomcat 9 is to implement JASPIC which would allow libraries like Spring Security to plug into Tomcat's authentication mechanism allowing for the behaviour you are looking for.

The other option would be to add an option to the Context to delegate sending of the 100 response to the application. There are security concerns around expectation handling but as long as Tomcat's current handling stays in place I don't believe this would create any issues. The down side is that if the application does not send the 100 continue response then the client may wait for an unknown period of time before sending the request body any way.

If you think such an option (to delegate the sending of 100 response) would be useful, we can move this issue to an enhancement. If not, it will get resolved as WONTFIX.
Comment 2 Lorenzo Caenazzo 2015-02-26 16:03:27 UTC
ok,
I think the responability to send 100-continue header is not of "contained" application.

But if the container send a 100 header I expect which it not closes the soket if the body of the request is "big". Maybe if Tomcat send a 100 continue header it must take and discard (in some case) the request body. Because the client receve the 100 header and say "ok now I can send a lot of data!" but after a while the server hang up the connection. What do you think?

P.S.
for now I've implemented a preemptive authentication method.
Comment 3 Mark Thomas 2015-02-26 16:31:23 UTC
Tomcat will swallow the request body up to maxSwallowSize after which Tomcat will close the connection.

Most clients will not read the response until the body is fully sent so if maxSwallowSize < request body size then the client will just see a closed connection. You can increase maxSwallowSize to avoid this (at the cost of pointlessly reading more data).
Comment 4 Christopher Schultz 2015-02-26 16:57:27 UTC
Does this currently work when Tomcat /is/ managing the authentication and authorization? If so, then I agree with WONTFIX.
Comment 5 Mark Thomas 2015-02-26 18:40:59 UTC
Yes. You get the right 4xx response along with a Connection: close header.