You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by bu...@apache.org on 2015/03/04 12:14:02 UTC

[Bug 57661] New: Delay sending of 100 continue response until application tries to read request body

https://bz.apache.org/bugzilla/show_bug.cgi?id=57661

            Bug ID: 57661
           Summary: Delay sending of 100 continue response until
                    application tries to read request body
           Product: Tomcat 9
           Version: unspecified
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: Connectors
          Assignee: dev@tomcat.apache.org
          Reporter: markt@apache.org

Currently Tomcat sends the 100 continue response just before the request is
passed to the application for processing. This denies the application the
opporutnity to reject the request early based on the request line and/or
headers. Dealying the 100 continue response until the application attempts to
read the requets body should address this.

-- 
You are receiving this mail because:
You are the assignee for the bug.

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


[Bug 57661] Delay sending of 100 continue response until application tries to read request body

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=57661

--- Comment #13 from Malay <ma...@backblaze.com> ---
I posted PR 332 https://github.com/apache/tomcat/pull/332 with my
implementation. Please let me know if this is the right approach, I thought of
several ways to implement this and decided on this approach because it allows
StandardContextValve to still be the brains behind sending the 100 Continue
response. Thanks!

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 57661] Delay sending of 100 continue response until application tries to read request body

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=57661

Michael Osipov <mi...@apache.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |michaelo@apache.org

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 57661] Delay sending of 100 continue response until application tries to read request body

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=57661

--- Comment #3 from Tobias Oberlies <to...@sap.com> ---
Sorry for the redundant comments.

I have an addition to my analysis in comment #1:
> ... (e.g. the Apache httpclient). These clients could
> send only headers plus the "Expect: 100-continue" and would then see an
> error response (e.g. 403)

With this enhancement implemented, there would be benefit, but it would be
limited. The benefit would be that the client sees the response instead of an
exception.

What we wouldn't get with the Apache 4.x httpclient is that the connection can
be reused for the next request. The problem is that because the httpclient
doesn't send the last chunk of the (to be discarded) entity after seeing a
final response to its "Expect: 100-continue" request. This forces the server to
close the connection. Apparently, this was only fixed in the 5.x httpclient [1]

[1] https://issues.apache.org/jira/browse/HTTPCORE-411

-- 
You are receiving this mail because:
You are the assignee for the bug.

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


[Bug 57661] Delay sending of 100 continue response until application tries to read request body

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=57661

--- Comment #5 from Mark Thomas <ma...@apache.org> ---
See https://github.com/eclipse-ee4j/servlet-api/issues/307 for a description of
what other containers do.

Options appear to be:
a) container sends it after auth (current Tomcat behaviour)
b) container sends it when an InputStream / Reader is obtained
c) container sends it when an InputStream / Reader is first used

I'm currently leaning towards adding an option to select between a) and b) but
as an Enum so additional options could be added later.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 57661] Delay sending of 100 continue response until application tries to read request body

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=57661

--- Comment #12 from Michael Osipov <mi...@apache.org> ---
(In reply to Malay from comment #11)
> I took a closer look at my implementation and it is actually option (c):
> c) container sends it when an InputStream / Reader is first used
> 
> The approach that I'm taking is to only send the '100 continue' response
> when the application reads the request body, there is no additional blocking
> involved, so it will not interfere with handling of requests with no content.
> 
> Regarding requests like DELETE that do not contain content, it is not
> allowed for those requests to contain the "Expect: 100-continue" header,
> from RFC 7231 5.1.1:
> A client MUST NOT generate a 100-continue expectation in a request
>       that does not include a message body.
> 
> From what I can tell, Apache HttpComponents will not add the "Expect:
> 100-continue" header if the content body size is zero.

Thanks for citing. I did not have this in mind.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 57661] Delay sending of 100 continue response until application tries to read request body

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=57661

Mark Thomas <ma...@apache.org> changed:

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

--- Comment #14 from Mark Thomas <ma...@apache.org> ---
Fixed in:
- master for 10.0.0-M8 onwards
- 9.0.x for 9.0.38 onwards
- 8.5.x for 8.5.58 onwards

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 57661] Delay sending of 100 continue response until application tries to read request body

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=57661

Tobias Oberlies <to...@sap.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |tobias.oberlies@sap.com

--- Comment #2 from Tobias Oberlies <to...@sap.com> ---
It is unfortunate that Tomcat unconditionally send 100 CONTINUE
acknowledgements. (In Tomcat 7 this is triggered by the StandardContextValve.)

The "Expect: 100-continue" is important for clients that want to send a large
POST request but are unable to read the response before they have sent the
complete request body (e.g. the Apache httpclient). These clients could send
only headers plus the "Expect: 100-continue" and would then see an error
response (e.g. 403). With the current behaviour of Tomcat however, they are
asked to send the entity, the server application responds with an error, but
the client doesn't see it (assuming the request entity is larger than the
swallow size, i.e. approx. 2 MB). Instead the client only sees an exception
("connection reset").

-- 
You are receiving this mail because:
You are the assignee for the bug.

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


[Bug 57661] Delay sending of 100 continue response until application tries to read request body

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=57661

--- Comment #9 from Christopher Schultz <ch...@christopherschultz.net> ---
Why send 100-continue if you don't expect to send a request entity? The whole
point of 100-continue is to request permission from the server to send a
(usually large) request entity.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 57661] Delay sending of 100 continue response until application tries to read request body

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=57661

--- Comment #7 from malay@backblaze.com ---
(In reply to Mark Thomas from comment #5)
I ran into this recently and ended up implementing option (b) locally:
b) container sends it when an InputStream / Reader is obtained

I'd be happy to prepare my local changes as a PR if there is a willingness to
move forward with this solution.

Thanks!

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 57661] Delay sending of 100 continue response until application tries to read request body

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=57661

--- Comment #6 from Michael Osipov <mi...@apache.org> ---
(In reply to Mark Thomas from comment #5)
> See https://github.com/eclipse-ee4j/servlet-api/issues/307 for a description
> of what other containers do.
> 
> Options appear to be:
> a) container sends it after auth (current Tomcat behaviour)
> b) container sends it when an InputStream / Reader is obtained
> c) container sends it when an InputStream / Reader is first used
> 
> I'm currently leaning towards adding an option to select between a) and b)
> but as an Enum so additional options could be added later.

Not only auth, on any status != 2xx. You may remember my redirect example on
the mailing list. At no point a filter should need to obtain/peek/consume the
input stream if a decision has to done based on headers only.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 57661] Delay sending of 100 continue response until application tries to read request body

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=57661

--- Comment #10 from Michael Osipov <mi...@apache.org> ---
(In reply to Christopher Schultz from comment #9)
> Why send 100-continue if you don't expect to send a request entity? The
> whole point of 100-continue is to request permission from the server to send
> a (usually large) request entity.

because a client impl may does this by default. I haven't veryfied Apache
HttpClient not to send the header when not HttpEntity is attached.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 57661] Delay sending of 100 continue response until application tries to read request body

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=57661

--- Comment #8 from Michael Osipov <mi...@apache.org> ---
Please note that state changing actions do not necessary require a body, e.g.,
DELETE or generic POST with command in the URL. If Tomcat would wait until
obtaining input this would completely defeat Expect Continue support.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 57661] Delay sending of 100 continue response until application tries to read request body

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=57661

--- Comment #11 from Malay <ma...@backblaze.com> ---
I took a closer look at my implementation and it is actually option (c):
c) container sends it when an InputStream / Reader is first used

The approach that I'm taking is to only send the '100 continue' response when
the application reads the request body, there is no additional blocking
involved, so it will not interfere with handling of requests with no content.

Regarding requests like DELETE that do not contain content, it is not allowed
for those requests to contain the "Expect: 100-continue" header, from RFC 7231
5.1.1:
A client MUST NOT generate a 100-continue expectation in a request
      that does not include a message body.

From what I can tell, Apache HttpComponents will not add the "Expect:
100-continue" header if the content body size is zero.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[Bug 57661] Delay sending of 100 continue response until application tries to read request body

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=57661

--- Comment #4 from Michael Osipov <19...@gmx.net> ---
To add some additional information based on my findings in Tomcat 6.0.45:
As already described by Mark, Tomcat sends the negative reponse before a client
has completely uploaded his request body. I believe that this implementation is
fully RFC compliant and reasonable one. Consider uploading hundreds of
megabytes and then wait for the denial? What a waste.

I was searching for a bug in Firefox and Tomcat and discovered that Firefox is
faulty too. curl perfectly handles the premature end of transfer. I have
documented my findings with Tomcat and the expect continue with Firefox here:
https://bugzilla.mozilla.org/show_bug.cgi?id=751552#c14. Similar issues:
https://bugzilla.mozilla.org/show_bug.cgi?id=914088,
https://bugzilla.mozilla.org/show_bug.cgi?id=729496

-- 
You are receiving this mail because:
You are the assignee for the bug.

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


[Bug 57661] Delay sending of 100 continue response until application tries to read request body

Posted by bu...@apache.org.
https://bz.apache.org/bugzilla/show_bug.cgi?id=57661

--- Comment #1 from Tobias Oberlies <to...@sap.com> ---
It is unfortunate that Tomcat unconditionally send 100 CONTINUE
acknowledgements. (In Tomcat 7 this is triggered by the StandardContextValve.)

The "Expect: 100-continue" is important for clients that want to send a large
POST request but are unable to read the response before they have sent the
complete request body (e.g. the Apache httpclient). These clients could send
only headers plus the "Expect: 100-continue" and would then see an error
response (e.g. 403). With the current behaviour of Tomcat however, they are
asked to send the entity, the server application responds with an error, but
the client doesn't see it (assuming the request entity is larger than the
swallow size, i.e. approx. 2 MB). Instead the client only sees an exception
("connection reset").

-- 
You are receiving this mail because:
You are the assignee for the bug.

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