You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Behrang Saeedzadeh <be...@gmail.com> on 2019/12/08 10:18:08 UTC

Expected behavior of calling javax.servlet.ServletRequest#getInputStream after javax.servlet.http.HttpServletRequest#getPart

Hi,

If I call javax.servlet.ServletRequest#getInputStream after having called
javax.servlet.http.HttpServletRequest#getPart, even without performing any
operations on the given part, I am getting an empty stream (0-bytes).

Is this in compliance with the spec?

Best regards,

{
  "blog" :
    "https://blog.behrang.org",
  "twitter":
     "https://twitter.com/behrangsa",
  "github":
     "https://github.com/behrangsa/",
  "stackoverflow":
     "https://stackoverflow.com/users/309683?tab=profile"}

Re: Expected behavior of calling javax.servlet.ServletRequest#getInputStream after javax.servlet.http.HttpServletRequest#getPart

Posted by Konstantin Kolinko <kn...@gmail.com>.
ср, 11 дек. 2019 г. в 13:06, Behrang Saeedzadeh <be...@gmail.com>:
>
> Thanks Andre for explaining it much better than I did.
>
> I posted this to Jakarta EE's mailing list too:
> https://www.eclipse.org/lists/jakarta.ee-community/msg01477.html
>
> I think at least the JavaDocs comments and the spec need minor amendments
> to document this expected behaviour clearly.

javax.servlet.ServletRequest#getInputStream() and getParameter()
methods address different use cases. It is rather unusual to try
calling getInputStream() when the Content-Type of the request is the
one handled by parameter parsing.

It is possible to use both getParameter() and getInputStream() if
request body has content-type that is not processed by parameter
parsing. In this case getParameter() returns the parameters parsed
from the query string of the request line and does not process the
body.


E.g. in Tomcat Manager web application it is possible to send a WAR
file in the body of a PUT request. The context path for the uploaded
web application is specified by a parameter in the request URL. Both
getParameter() and getInputStream() are used here.

http://tomcat.apache.org/tomcat-9.0-doc/manager-howto.html#Deploy_A_New_Application_Archive_(WAR)_Remotely

I think that changing the method getInputStream() to throw an
IllegalStateException (e.g. as a vendor-specific option) may help
developers to detect their programming errors, but does not address
any real use case. On the good side, it also means that it does not
break any real use case.

Best regards,
Konstantin Kolinko

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


Re: Expected behavior of calling javax.servlet.ServletRequest#getInputStream after javax.servlet.http.HttpServletRequest#getPart

Posted by Behrang Saeedzadeh <be...@gmail.com>.
Thanks Andre for explaining it much better than I did.

I posted this to Jakarta EE's mailing list too:
https://www.eclipse.org/lists/jakarta.ee-community/msg01477.html

I think at least the JavaDocs comments and the spec need minor amendments
to document this expected behaviour clearly.

Best regards,

{
  "blog" :
    "https://blog.behrang.org",
  "twitter":
     "https://twitter.com/behrangsa",
  "github":
     "https://github.com/behrangsa/",
  "stackoverflow":
     "https://stackoverflow.com/users/309683?tab=profile"}



On Wed, Dec 11, 2019 at 8:47 AM André Warnier (tomcat/perl) <aw...@ice-sa.com>
wrote:

> On 10.12.2019 15:31, Christopher Schultz wrote:
> > -----BEGIN PGP SIGNED MESSAGE-----
> > Hash: SHA256
> >
> > Behrang,
> >
> > On 12/8/19 05:18, Behrang Saeedzadeh wrote:
> >> If I call javax.servlet.ServletRequest#getInputStream after having
> >> called javax.servlet.http.HttpServletRequest#getPart, even without
> >> performing any operations on the given part, I am getting an empty
> >> stream (0-bytes).
> >>
> >> Is this in compliance with the spec?
> >
> > What does the servlet spec say about that situation?
> >
>
> A bit in defense of the OP, I have to say that the Servlet Spec (4.0
> final) does not seem
> extremely clear on that subject.
> In section "3.1.1 When Parameters Are Available", it /does/ say this :
>
> "If the conditions are met, post form data will no longer be available for
> reading directly from the request object’s input stream."
>
> But among those conditions that have to be met (just above that quote) is
> "4. The servlet has made an initial call of any of the "getParameter
> family" of methods
> on the request object."
>
> (So there, it talks about "the getParameter family", not the "getPart"
> ones).
>
> It only talks about the "getPart" methods in the next section "3.2 File
> upload", and in
> that section, all it says about the input stream is :
> "If the servlet container does not provide the multi-part/form-data
> processing,
> the data will be available through the HttpServletReuqest.getInputStream."
>
> So the way I read this, is that there is nothing that explicitly says that
> the InputStream
> is no longer available if you have called "getPart".
>
> (It is also in fact not very clear about what happens to the parameters,
> when the
> content-type of the Request is "multipart/form-data", which is only
> mentioned in section 3.2.)
>
> On the other hand,
> http://tomcat.apache.org/tomcat-9.0-doc/servletapi/index.html
> --> Interface HttpServletRequest
> says :
>
> Part getPart(java.lang.String name)
>        throws java.io.IOException,
>               ServletException
> Gets the named Part or null if the Part does not exist. *Triggers upload
> of all Parts*.
> (emphasis mine)
>
> which /may/ be taken to mean (and probably does) that it consumes the
> whole InputStream.
>
> But again, this may be lacking some overall clarity.
>
> In any case, the OP's question is not really unwarranted, unless there is
> some other
> explanation somewhere which I have missed.
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

Re: Expected behavior of calling javax.servlet.ServletRequest#getInputStream after javax.servlet.http.HttpServletRequest#getPart

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Behrang,

On 12/13/19 00:18, Behrang Saeedzadeh wrote:
> Unless an email, including its signature, is in violation of the
> mailing list policies, no one is in a position to ask participants
> to format their emails in a given way or not to include their email
> signatures. I suggest reading
> https://www.apache.org/foundation/policies/conduct.html and 
> https://apache.org/dev/contrib-email-tips.html for those that are
> not familiar with these policies.

In that case, I'll direct you to
http://tomcat.apache.org/lists.html#tomcat-users which is the policy
for THIS mailing list where you have violated a few items:

1. please state your exact Tomcat version
6. please write your text below the quoted one

It would be very easy for us to change our mailing list policy to
prohibit advertisements (and, frankly, I'm surprised it's not in there
already), but it's much easier to ask politely. The development of
rigid policies are only necessary when bad actors refuse to take
gentle hints.

- -chris
> On Fri, Dec 13, 2019 at 2:08 AM Christopher Schultz < 
> chris@christopherschultz.net> wrote:
> 
> Behrang,
> 
> On 12/12/19 03:56, Behrang Saeedzadeh wrote:
>>>> Chris,
>>>> 
>>>> 1) Does it make sense to call ServletRequest#getInputStream
>>>> after ServletRequest#getReader? No, and consequently it will
>>>> throw IllegalStateException. 2) Does it make sense to call 
>>>> ServletRequest#getInputStream after ServletRequest#getPart/s?
>>>> No, but it returns an empty stream instead of throwing 
>>>> IllegalStateException.
>>>> 
>>>> These behaviours are not consistent.
> 
> Perhaps, but they do not violate the specification.
> 
> Tomcat must call getInputStream to parse the various 
> multipart/form-data parts. If you call getInputStream, too, there
> will be no error.
> 
> I suspect if you call getReader, you'll find you'll get an 
> IllegalStateException.
> 
>>>> Best regards,
>>>> 
>>>> { "blog" : "https://blog.behrang.org", "twitter": 
>>>> "https://twitter.com/behrangsa", "github": 
>>>> "https://github.com/behrangsa/", "stackoverflow": 
>>>> "https://stackoverflow.com/users/309683?tab=profile"}
> 
> 
> Please stop advertising yourself on a public mailing list.
> 
> -chris
> 
>>>> On Thu, Dec 12, 2019 at 4:31 AM Christopher Schultz < 
>>>> chris@christopherschultz.net> wrote:
>>>> 
>>>> André,
>>>> 
>>>> On 12/10/19 16:47, André Warnier (tomcat/perl) wrote:
>>>>>>> On 10.12.2019 15:31, Christopher Schultz wrote:
>>>>>>>> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
>>>>>>>> 
>>>>>>>> Behrang,
>>>>>>>> 
>>>>>>>> On 12/8/19 05:18, Behrang Saeedzadeh wrote:
>>>>>>>>> If I call
>>>>>>>>> javax.servlet.ServletRequest#getInputStream after
>>>>>>>>> having called 
>>>>>>>>> javax.servlet.http.HttpServletRequest#getPart,
>>>>>>>>> even without performing any operations on the given
>>>>>>>>> part, I am getting an empty stream (0-bytes).
>>>>>>>>> 
>>>>>>>>> Is this in compliance with the spec?
>>>>>>>> 
>>>>>>>> What does the servlet spec say about that situation?
>>>>>>>> 
>>>>>>> 
>>>>>>> A bit in defense of the OP, I have to say that the
>>>>>>> Servlet Spec (4.0 final) does not seem extremely clear
>>>>>>> on that subject.
>>>> 
>>>> While I appreciate your research activities, I was hoping the
>>>> OP would actually read the spec to get some clarification.
>>>> 
>>>>>>> In section "3.1.1 When Parameters Are Available", it
>>>>>>> /does/ say this :
>>>>>>> 
>>>>>>> "If the conditions are met, post form data will no
>>>>>>> longer be available for reading directly from the
>>>>>>> request object’s input stream."
>>>>>>> 
>>>>>>> But among those conditions that have to be met (just
>>>>>>> above that quote) is "4. The servlet has made an
>>>>>>> initial call of any of the "getParameter family" of
>>>>>>> methods on the request object."
>>>>>>> 
>>>>>>> (So there, it talks about "the getParameter family",
>>>>>>> not the "getPart" ones).
>>>>>>> 
>>>>>>> It only talks about the "getPart" methods in the next
>>>>>>> section "3.2 File upload", and in that section, all it
>>>>>>> says about the input stream is : "If the servlet
>>>>>>> container does not provide the multi-part/form-data
>>>>>>> processing, the data will be available through the
>>>>>>> HttpServletReuqest.getInputStream."
>>>>>>> 
>>>>>>> So the way I read this, is that there is nothing that 
>>>>>>> explicitly says that the InputStream is no longer
>>>>>>> available if you have called "getPart".
>>>> 
>>>> The only reason the container would process
>>>> multi-part/form-data requests is if you called
>>>> request.getPart*. Therefore, the InputStream is no longer
>>>> available.
>>>> 
>>>>>>> (It is also in fact not very clear about what happens
>>>>>>> to the parameters, when the content-type of the Request
>>>>>>> is "multipart/form-data", which is only mentioned in
>>>>>>> section 3.2.)
>>>> 
>>>> Normal parameters are available via request.getParameter*.
>>>> You can also go through the agony of
>>>> getPart("foo").getInputStream() if you'd like. This is
>>>> documented in section 3.2 "File Upload".
>>>> 
>>>>>>> On the other hand, 
>>>>>>> http://tomcat.apache.org/tomcat-9.0-doc/servletapi/index.html
>>>>>>>
>>>>>>> 
- --> Interface HttpServletRequest says :
>>>>>>> 
>>>>>>> Part getPart(java.lang.String name) throws 
>>>>>>> java.io.IOException, ServletException Gets the named
>>>>>>> Part or null if the Part does not exist. *Triggers
>>>>>>> upload of all Parts*. (emphasis mine)
>>>>>>> 
>>>>>>> which /may/ be taken to mean (and probably does) that
>>>>>>> it consumes the whole InputStream.
>>>> 
>>>> It does. And, necessarily, it must. You can't find out what's
>>>> in the request entity without ... reading the request
>>>> entity.
>>>> 
>>>>>>> But again, this may be lacking some overall clarity.
>>>>>>> 
>>>>>>> In any case, the OP's question is not really
>>>>>>> unwarranted, unless there is some other explanation
>>>>>>> somewhere which I have missed.
>>>> 
>>>> I guess to me this falls under the category of "obvious", but
>>>> then again I know quite a bit about this subject.
>>>> 
>>>> -chris
>>>>> 
>>>>> ------------------------------------------------------------------
- ---
>>>>>
>>>>>
>
>>>>> 
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>>>>> For additional commands, e-mail:
>>>>> users-help@tomcat.apache.org
>>>>> 
>>>>> 
>>>> 
>> 
>> ---------------------------------------------------------------------
>>
>> 
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>> For additional commands, e-mail: users-help@tomcat.apache.org
>> 
>> 
> 
-----BEGIN PGP SIGNATURE-----
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl3z/5IACgkQHPApP6U8
pFj7Lw/+L8cm3pfmLVcVLbxNFm4iUTrrfNzlrmrH9ch19ICTyJSf+PQUfI/F2qmR
8MvQL6kf+0MTX85oN+PjDM12Zg1uwHrKaBPiGjIFHIksbhGo183GSCMbQP1hqrQn
Z9HZvdahKrp25v6gLcLp9uBUn+eJvdRqmKTl76Br673YTd2i4HjC2HpwkYQKsi8D
zTPACMo3acRC/iMbri76t6kxfPhC/ILmv7QTBC4holZcyXHgvR48B+LNN7EtbKNN
7nkN5cS/NS1NoKfCfcGfcM9lwaQTylys4IbwPHMwaFGkCTS5YPLHeqj5Fyc9YTTS
9TrmsJTos0+RaIQ0eX3huGF338CTXKVLB/BTFUvdfgQpDleKQbOl9dtKXqEkJiLE
2ahYpeUKODTphTSixS0YjoB4eTBh4QfQbLppOXn/BRhjWsb+/bZxTVc0M5UaBSbS
rEf/QOuX7v5OBeVOoAPFSArmUEbz7EXm+gjQ5vy6smKHuAh6OMXl/TXSfM/6M3SE
xeHZOQiQJH1Jfhokz4RYtSZU4ZSf8DJUaCSf8mLDjzwfhPd67Zod4N82CIQrd/zj
Q/7Ifbisxs/rzwdLGv5vGTLFJpCXSo0jMgcpkFXomCCb7eB0H2FOpLjcGmX2lqkH
01Znz2MhtawkoitCAOzy3Fn/WAzhG/silPaO8VTXRwmNR9QFVTY=
=g4YM
-----END PGP SIGNATURE-----

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


Re: Expected behavior of calling javax.servlet.ServletRequest#getInputStream after javax.servlet.http.HttpServletRequest#getPart

Posted by Konstantin Kolinko <kn...@gmail.com>.
пт, 13 дек. 2019 г. в 08:18, Behrang Saeedzadeh <be...@gmail.com>:
>
> Unless an email, including its signature, is in violation of the mailing
> list policies, no one is in a position to ask participants to format their
> emails in a given way or not to include their email signatures. I suggest
> reading [...] for those that are not
> familiar with these policies.

Thank you for your kind references.

Please note that

1. It is up to PMC to oversee its project and its mailing lists.

2. Please note the rules of this mailing list, as stated in
https://tomcat.apache.org/lists.html#tomcat-users
-> 6.

and also
https://www.apache.org/foundation/policies/conduct.html
-> 6. Be concise

3. The mail signatures like the one that was seen in this mail thread look
a lot like click bait spam or SEO spam that many of us are tired of.

I do not really mind how one likes to present oneself. Though personally
my first reaction to any e-mail that resembles spam is to ignore it.

Best regards,
Konstantin Kolinko

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


Re: Expected behavior of calling javax.servlet.ServletRequest#getInputStream after javax.servlet.http.HttpServletRequest#getPart

Posted by Behrang Saeedzadeh <be...@gmail.com>.
Unless an email, including its signature, is in violation of the mailing
list policies, no one is in a position to ask participants to format their
emails in a given way or not to include their email signatures. I suggest
reading https://www.apache.org/foundation/policies/conduct.html and
https://apache.org/dev/contrib-email-tips.html for those that are not
familiar with these policies.

Best regards,

{
  "blog" :
    "https://blog.behrang.org",
  "twitter":
     "https://twitter.com/behrangsa",
  "github":
     "https://github.com/behrangsa/",
  "stackoverflow":
     "https://stackoverflow.com/users/309683?tab=profile"}



On Fri, Dec 13, 2019 at 2:08 AM Christopher Schultz <
chris@christopherschultz.net> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
>
> Behrang,
>
> On 12/12/19 03:56, Behrang Saeedzadeh wrote:
> > Chris,
> >
> > 1) Does it make sense to call ServletRequest#getInputStream after
> > ServletRequest#getReader? No, and consequently it will throw
> > IllegalStateException. 2) Does it make sense to call
> > ServletRequest#getInputStream after ServletRequest#getPart/s? No,
> > but it returns an empty stream instead of throwing
> > IllegalStateException.
> >
> > These behaviours are not consistent.
>
> Perhaps, but they do not violate the specification.
>
> Tomcat must call getInputStream to parse the various
> multipart/form-data parts. If you call getInputStream, too, there will
> be no error.
>
> I suspect if you call getReader, you'll find you'll get an
> IllegalStateException.
>
> > Best regards,
> >
> > { "blog" : "https://blog.behrang.org", "twitter":
> > "https://twitter.com/behrangsa", "github":
> > "https://github.com/behrangsa/", "stackoverflow":
> > "https://stackoverflow.com/users/309683?tab=profile"}
>
>
> Please stop advertising yourself on a public mailing list.
>
> - -chris
>
> > On Thu, Dec 12, 2019 at 4:31 AM Christopher Schultz <
> > chris@christopherschultz.net> wrote:
> >
> > André,
> >
> > On 12/10/19 16:47, André Warnier (tomcat/perl) wrote:
> >>>> On 10.12.2019 15:31, Christopher Schultz wrote:
> >>>>> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
> >>>>>
> >>>>> Behrang,
> >>>>>
> >>>>> On 12/8/19 05:18, Behrang Saeedzadeh wrote:
> >>>>>> If I call javax.servlet.ServletRequest#getInputStream
> >>>>>> after having called
> >>>>>> javax.servlet.http.HttpServletRequest#getPart, even
> >>>>>> without performing any operations on the given part, I
> >>>>>> am getting an empty stream (0-bytes).
> >>>>>>
> >>>>>> Is this in compliance with the spec?
> >>>>>
> >>>>> What does the servlet spec say about that situation?
> >>>>>
> >>>>
> >>>> A bit in defense of the OP, I have to say that the Servlet
> >>>> Spec (4.0 final) does not seem extremely clear on that
> >>>> subject.
> >
> > While I appreciate your research activities, I was hoping the OP
> > would actually read the spec to get some clarification.
> >
> >>>> In section "3.1.1 When Parameters Are Available", it /does/
> >>>> say this :
> >>>>
> >>>> "If the conditions are met, post form data will no longer be
> >>>> available for reading directly from the request object’s
> >>>> input stream."
> >>>>
> >>>> But among those conditions that have to be met (just above
> >>>> that quote) is "4. The servlet has made an initial call of
> >>>> any of the "getParameter family" of methods on the request
> >>>> object."
> >>>>
> >>>> (So there, it talks about "the getParameter family", not the
> >>>> "getPart" ones).
> >>>>
> >>>> It only talks about the "getPart" methods in the next section
> >>>> "3.2 File upload", and in that section, all it says about the
> >>>> input stream is : "If the servlet container does not provide
> >>>> the multi-part/form-data processing, the data will be
> >>>> available through the HttpServletReuqest.getInputStream."
> >>>>
> >>>> So the way I read this, is that there is nothing that
> >>>> explicitly says that the InputStream is no longer available
> >>>> if you have called "getPart".
> >
> > The only reason the container would process multi-part/form-data
> > requests is if you called request.getPart*. Therefore, the
> > InputStream is no longer available.
> >
> >>>> (It is also in fact not very clear about what happens to the
> >>>> parameters, when the content-type of the Request is
> >>>> "multipart/form-data", which is only mentioned in section
> >>>> 3.2.)
> >
> > Normal parameters are available via request.getParameter*. You can
> > also go through the agony of getPart("foo").getInputStream() if
> > you'd like. This is documented in section 3.2 "File Upload".
> >
> >>>> On the other hand,
> >>>> http://tomcat.apache.org/tomcat-9.0-doc/servletapi/index.html
> >>>> --> Interface HttpServletRequest says :
> >>>>
> >>>> Part getPart(java.lang.String name) throws
> >>>> java.io.IOException, ServletException Gets the named Part or
> >>>> null if the Part does not exist. *Triggers upload of all
> >>>> Parts*. (emphasis mine)
> >>>>
> >>>> which /may/ be taken to mean (and probably does) that it
> >>>> consumes the whole InputStream.
> >
> > It does. And, necessarily, it must. You can't find out what's in
> > the request entity without ... reading the request entity.
> >
> >>>> But again, this may be lacking some overall clarity.
> >>>>
> >>>> In any case, the OP's question is not really unwarranted,
> >>>> unless there is some other explanation somewhere which I have
> >>>> missed.
> >
> > I guess to me this falls under the category of "obvious", but then
> > again I know quite a bit about this subject.
> >
> > -chris
> >>
> >> ---------------------------------------------------------------------
> >>
> >>
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> >> For additional commands, e-mail: users-help@tomcat.apache.org
> >>
> >>
> >
> -----BEGIN PGP SIGNATURE-----
> Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/
>
> iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl3yV8AACgkQHPApP6U8
> pFh11hAAvJ4wdKJLUW89Xgk0oJa7HtaqVuFkDTSwPZ0NfRSs372eQO6N503d3vjp
> SPlros1irLmmtFnDWN4b3/t/oJRirdExbiEjPP8hiRynGm7V3RT+naVmvm5ksyL8
> RbEXbiD1Gu0/UcrR+uSr1Omxa9rxb18uyBDrUw/WmXZVu0k/geRabyrAXvTKIJaa
> MMXrK8sxAG5Yk6dXu3Lm1qgx1d8vo1oeoGfbAxCGiaQ0EwOHLpn2PTce/39s9EmI
> +8MhIDfEy8O1ZSSoLnInSxka6zgP6n3yk7onGIgzIkE4YwZTXOPKh/s4GZNXg2ly
> 5/600W3AuOT4ymDNdvw9Hx64PnfElo85WgL2iPSi1NfPmKjNxJKFDKB//W5GAGgk
> us51bWkFf4wRaUSTHBKty0xipEoy8EJA/P2TWm8JWNcHXF+CDuPq54ygK6iYT2XL
> RTSRflC5EiUA1NfAIhVgwFjN3L/aUMrRaAzEqFQKK1Z/7z3W5Ql4dRAgdq75QAE+
> XpYynPEHfWABR7VwbmplVXMsjGfvqc5Ry6AK3gwdsERryrZBezdLZHnojLcxMDaQ
> 3refYsMGM3h79O4zd30quGJx72nW6/DsotfYLsGHw6iZMvzdhNPOiLZu44LoIS3D
> juhbDbJNAothwwNCnAV0GSueqcMPo8N4bYYA4yL3x7WgKLuRLAU=
> =RHsI
> -----END PGP SIGNATURE-----
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

Re: Expected behavior of calling javax.servlet.ServletRequest#getInputStream after javax.servlet.http.HttpServletRequest#getPart

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Behrang,

On 12/12/19 03:56, Behrang Saeedzadeh wrote:
> Chris,
> 
> 1) Does it make sense to call ServletRequest#getInputStream after 
> ServletRequest#getReader? No, and consequently it will throw 
> IllegalStateException. 2) Does it make sense to call
> ServletRequest#getInputStream after ServletRequest#getPart/s? No,
> but it returns an empty stream instead of throwing
> IllegalStateException.
> 
> These behaviours are not consistent.

Perhaps, but they do not violate the specification.

Tomcat must call getInputStream to parse the various
multipart/form-data parts. If you call getInputStream, too, there will
be no error.

I suspect if you call getReader, you'll find you'll get an
IllegalStateException.

> Best regards,
> 
> { "blog" : "https://blog.behrang.org", "twitter": 
> "https://twitter.com/behrangsa", "github": 
> "https://github.com/behrangsa/", "stackoverflow": 
> "https://stackoverflow.com/users/309683?tab=profile"}


Please stop advertising yourself on a public mailing list.

- -chris

> On Thu, Dec 12, 2019 at 4:31 AM Christopher Schultz < 
> chris@christopherschultz.net> wrote:
> 
> André,
> 
> On 12/10/19 16:47, André Warnier (tomcat/perl) wrote:
>>>> On 10.12.2019 15:31, Christopher Schultz wrote:
>>>>> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
>>>>> 
>>>>> Behrang,
>>>>> 
>>>>> On 12/8/19 05:18, Behrang Saeedzadeh wrote:
>>>>>> If I call javax.servlet.ServletRequest#getInputStream
>>>>>> after having called
>>>>>> javax.servlet.http.HttpServletRequest#getPart, even
>>>>>> without performing any operations on the given part, I
>>>>>> am getting an empty stream (0-bytes).
>>>>>> 
>>>>>> Is this in compliance with the spec?
>>>>> 
>>>>> What does the servlet spec say about that situation?
>>>>> 
>>>> 
>>>> A bit in defense of the OP, I have to say that the Servlet
>>>> Spec (4.0 final) does not seem extremely clear on that
>>>> subject.
> 
> While I appreciate your research activities, I was hoping the OP
> would actually read the spec to get some clarification.
> 
>>>> In section "3.1.1 When Parameters Are Available", it /does/
>>>> say this :
>>>> 
>>>> "If the conditions are met, post form data will no longer be 
>>>> available for reading directly from the request object’s
>>>> input stream."
>>>> 
>>>> But among those conditions that have to be met (just above
>>>> that quote) is "4. The servlet has made an initial call of
>>>> any of the "getParameter family" of methods on the request
>>>> object."
>>>> 
>>>> (So there, it talks about "the getParameter family", not the 
>>>> "getPart" ones).
>>>> 
>>>> It only talks about the "getPart" methods in the next section
>>>> "3.2 File upload", and in that section, all it says about the
>>>> input stream is : "If the servlet container does not provide
>>>> the multi-part/form-data processing, the data will be
>>>> available through the HttpServletReuqest.getInputStream."
>>>> 
>>>> So the way I read this, is that there is nothing that
>>>> explicitly says that the InputStream is no longer available
>>>> if you have called "getPart".
> 
> The only reason the container would process multi-part/form-data 
> requests is if you called request.getPart*. Therefore, the
> InputStream is no longer available.
> 
>>>> (It is also in fact not very clear about what happens to the 
>>>> parameters, when the content-type of the Request is 
>>>> "multipart/form-data", which is only mentioned in section
>>>> 3.2.)
> 
> Normal parameters are available via request.getParameter*. You can 
> also go through the agony of getPart("foo").getInputStream() if
> you'd like. This is documented in section 3.2 "File Upload".
> 
>>>> On the other hand, 
>>>> http://tomcat.apache.org/tomcat-9.0-doc/servletapi/index.html
>>>> --> Interface HttpServletRequest says :
>>>> 
>>>> Part getPart(java.lang.String name) throws
>>>> java.io.IOException, ServletException Gets the named Part or
>>>> null if the Part does not exist. *Triggers upload of all
>>>> Parts*. (emphasis mine)
>>>> 
>>>> which /may/ be taken to mean (and probably does) that it
>>>> consumes the whole InputStream.
> 
> It does. And, necessarily, it must. You can't find out what's in
> the request entity without ... reading the request entity.
> 
>>>> But again, this may be lacking some overall clarity.
>>>> 
>>>> In any case, the OP's question is not really unwarranted,
>>>> unless there is some other explanation somewhere which I have
>>>> missed.
> 
> I guess to me this falls under the category of "obvious", but then 
> again I know quite a bit about this subject.
> 
> -chris
>> 
>> ---------------------------------------------------------------------
>>
>> 
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
>> For additional commands, e-mail: users-help@tomcat.apache.org
>> 
>> 
> 
-----BEGIN PGP SIGNATURE-----
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl3yV8AACgkQHPApP6U8
pFh11hAAvJ4wdKJLUW89Xgk0oJa7HtaqVuFkDTSwPZ0NfRSs372eQO6N503d3vjp
SPlros1irLmmtFnDWN4b3/t/oJRirdExbiEjPP8hiRynGm7V3RT+naVmvm5ksyL8
RbEXbiD1Gu0/UcrR+uSr1Omxa9rxb18uyBDrUw/WmXZVu0k/geRabyrAXvTKIJaa
MMXrK8sxAG5Yk6dXu3Lm1qgx1d8vo1oeoGfbAxCGiaQ0EwOHLpn2PTce/39s9EmI
+8MhIDfEy8O1ZSSoLnInSxka6zgP6n3yk7onGIgzIkE4YwZTXOPKh/s4GZNXg2ly
5/600W3AuOT4ymDNdvw9Hx64PnfElo85WgL2iPSi1NfPmKjNxJKFDKB//W5GAGgk
us51bWkFf4wRaUSTHBKty0xipEoy8EJA/P2TWm8JWNcHXF+CDuPq54ygK6iYT2XL
RTSRflC5EiUA1NfAIhVgwFjN3L/aUMrRaAzEqFQKK1Z/7z3W5Ql4dRAgdq75QAE+
XpYynPEHfWABR7VwbmplVXMsjGfvqc5Ry6AK3gwdsERryrZBezdLZHnojLcxMDaQ
3refYsMGM3h79O4zd30quGJx72nW6/DsotfYLsGHw6iZMvzdhNPOiLZu44LoIS3D
juhbDbJNAothwwNCnAV0GSueqcMPo8N4bYYA4yL3x7WgKLuRLAU=
=RHsI
-----END PGP SIGNATURE-----

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


Re: Expected behavior of calling javax.servlet.ServletRequest#getInputStream after javax.servlet.http.HttpServletRequest#getPart

Posted by Behrang Saeedzadeh <be...@gmail.com>.
Chris,

1) Does it make sense to call ServletRequest#getInputStream after
ServletRequest#getReader? No, and consequently it will throw
IllegalStateException.
2) Does it make sense to call ServletRequest#getInputStream after
ServletRequest#getPart/s? No, but it returns an empty stream instead of
throwing IllegalStateException.

These behaviours are not consistent.

Best regards,

{
  "blog" :
    "https://blog.behrang.org",
  "twitter":
     "https://twitter.com/behrangsa",
  "github":
     "https://github.com/behrangsa/",
  "stackoverflow":
     "https://stackoverflow.com/users/309683?tab=profile"}



On Thu, Dec 12, 2019 at 4:31 AM Christopher Schultz <
chris@christopherschultz.net> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
>
> André,
>
> On 12/10/19 16:47, André Warnier (tomcat/perl) wrote:
> > On 10.12.2019 15:31, Christopher Schultz wrote:
> >> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
> >>
> >> Behrang,
> >>
> >> On 12/8/19 05:18, Behrang Saeedzadeh wrote:
> >>> If I call javax.servlet.ServletRequest#getInputStream after
> >>> having called javax.servlet.http.HttpServletRequest#getPart,
> >>> even without performing any operations on the given part, I am
> >>> getting an empty stream (0-bytes).
> >>>
> >>> Is this in compliance with the spec?
> >>
> >> What does the servlet spec say about that situation?
> >>
> >
> > A bit in defense of the OP, I have to say that the Servlet Spec
> > (4.0 final) does not seem extremely clear on that subject.
>
> While I appreciate your research activities, I was hoping the OP would
> actually read the spec to get some clarification.
>
> > In section "3.1.1 When Parameters Are Available", it /does/ say
> > this :
> >
> > "If the conditions are met, post form data will no longer be
> > available for reading directly from the request object’s input
> > stream."
> >
> > But among those conditions that have to be met (just above that
> > quote) is "4. The servlet has made an initial call of any of the
> > "getParameter family" of methods on the request object."
> >
> > (So there, it talks about "the getParameter family", not the
> > "getPart" ones).
> >
> > It only talks about the "getPart" methods in the next section "3.2
> > File upload", and in that section, all it says about the input
> > stream is : "If the servlet container does not provide the
> > multi-part/form-data processing, the data will be available through
> > the HttpServletReuqest.getInputStream."
> >
> > So the way I read this, is that there is nothing that explicitly
> > says that the InputStream is no longer available if you have called
> > "getPart".
>
> The only reason the container would process multi-part/form-data
> requests is if you called request.getPart*. Therefore, the InputStream
> is no longer available.
>
> > (It is also in fact not very clear about what happens to the
> > parameters, when the content-type of the Request is
> > "multipart/form-data", which is only mentioned in section 3.2.)
>
> Normal parameters are available via request.getParameter*. You can
> also go through the agony of getPart("foo").getInputStream() if you'd
> like. This is documented in section 3.2 "File Upload".
>
> > On the other hand,
> > http://tomcat.apache.org/tomcat-9.0-doc/servletapi/index.html -->
> > Interface HttpServletRequest says :
> >
> > Part getPart(java.lang.String name) throws java.io.IOException,
> > ServletException Gets the named Part or null if the Part does not
> > exist. *Triggers upload of all Parts*. (emphasis mine)
> >
> > which /may/ be taken to mean (and probably does) that it consumes
> > the whole InputStream.
>
> It does. And, necessarily, it must. You can't find out what's in the
> request entity without ... reading the request entity.
>
> > But again, this may be lacking some overall clarity.
> >
> > In any case, the OP's question is not really unwarranted, unless
> > there is some other explanation somewhere which I have missed.
>
> I guess to me this falls under the category of "obvious", but then
> again I know quite a bit about this subject.
>
> - -chris
> -----BEGIN PGP SIGNATURE-----
> Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/
>
> iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl3xJ+IACgkQHPApP6U8
> pFj+aQ//eGoRadiIjoP5uG3e9rzwjK8JqL6aa39UIz0iQH3rgXGpQBAJf2u0QBwJ
> 8qjFVG8PpJV6yIrcLK8IxbrgJyKTeBsvxZc6/F092w1lU2ScHr96qSNJQFVyw94J
> YQUZezyP2yVn6SHcm5Ok6lLnf/wo2Nf527ritAkAmrNg31pnEPa89giCJFKzIUkm
> OJj82MZ8CoLmaL4u0gV4Ad5AghasCNASvrnTuc7BAh8COWDBOqHFpKc7esrHzilw
> R8uBHJJ5cHujPQPcHTpMeeSWFUOo6IU+LUi91KxYM6ROjZIb+74e6Pi0fpIVPWAk
> ycukcRPJKKGAucjDzst8TSwVsJZ659Q77UKp8PaIMms2s5njZvOwrXsTn0ZGF/uI
> PLUISkt+jbj0o/EMYJdsanVfE4ZsZXA4JSDXXiCwOAswccRluMgkLEJxQsrsRac1
> rfsWvUYqqIchTpfOSc/K0UgR4hcMIewiaF0FU0qru0eZfk6ErWVr7Pvnc6w+HkU6
> TzYxFnHY03+LZsCvu8lYDysKgNg5/ibrklyekTkebmBgSMV7LuR9ewM12X7Yqmvw
> ABhyNt8hRKHJx7yY4kg1WozwtIc+MhAWCVhKqetZzvc9E+KQbYcJHxiGOmuop5cJ
> oWnhGSQbWPx6xOqtgvWczDfJfgwCBm4UAeIn5W/62KVG7EuukfA=
> =fdap
> -----END PGP SIGNATURE-----
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

Re: Expected behavior of calling javax.servlet.ServletRequest#getInputStream after javax.servlet.http.HttpServletRequest#getPart

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

André,

On 12/10/19 16:47, André Warnier (tomcat/perl) wrote:
> On 10.12.2019 15:31, Christopher Schultz wrote:
>> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
>> 
>> Behrang,
>> 
>> On 12/8/19 05:18, Behrang Saeedzadeh wrote:
>>> If I call javax.servlet.ServletRequest#getInputStream after
>>> having called javax.servlet.http.HttpServletRequest#getPart,
>>> even without performing any operations on the given part, I am
>>> getting an empty stream (0-bytes).
>>> 
>>> Is this in compliance with the spec?
>> 
>> What does the servlet spec say about that situation?
>> 
> 
> A bit in defense of the OP, I have to say that the Servlet Spec
> (4.0 final) does not seem extremely clear on that subject.

While I appreciate your research activities, I was hoping the OP would
actually read the spec to get some clarification.

> In section "3.1.1 When Parameters Are Available", it /does/ say
> this :
> 
> "If the conditions are met, post form data will no longer be
> available for reading directly from the request object’s input
> stream."
> 
> But among those conditions that have to be met (just above that
> quote) is "4. The servlet has made an initial call of any of the
> "getParameter family" of methods on the request object."
> 
> (So there, it talks about "the getParameter family", not the
> "getPart" ones).
> 
> It only talks about the "getPart" methods in the next section "3.2
> File upload", and in that section, all it says about the input
> stream is : "If the servlet container does not provide the
> multi-part/form-data processing, the data will be available through
> the HttpServletReuqest.getInputStream."
> 
> So the way I read this, is that there is nothing that explicitly
> says that the InputStream is no longer available if you have called
> "getPart".

The only reason the container would process multi-part/form-data
requests is if you called request.getPart*. Therefore, the InputStream
is no longer available.

> (It is also in fact not very clear about what happens to the
> parameters, when the content-type of the Request is
> "multipart/form-data", which is only mentioned in section 3.2.)

Normal parameters are available via request.getParameter*. You can
also go through the agony of getPart("foo").getInputStream() if you'd
like. This is documented in section 3.2 "File Upload".

> On the other hand, 
> http://tomcat.apache.org/tomcat-9.0-doc/servletapi/index.html -->
> Interface HttpServletRequest says :
> 
> Part getPart(java.lang.String name) throws java.io.IOException, 
> ServletException Gets the named Part or null if the Part does not
> exist. *Triggers upload of all Parts*. (emphasis mine)
> 
> which /may/ be taken to mean (and probably does) that it consumes
> the whole InputStream.

It does. And, necessarily, it must. You can't find out what's in the
request entity without ... reading the request entity.

> But again, this may be lacking some overall clarity.
> 
> In any case, the OP's question is not really unwarranted, unless
> there is some other explanation somewhere which I have missed.

I guess to me this falls under the category of "obvious", but then
again I know quite a bit about this subject.

- -chris
-----BEGIN PGP SIGNATURE-----
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl3xJ+IACgkQHPApP6U8
pFj+aQ//eGoRadiIjoP5uG3e9rzwjK8JqL6aa39UIz0iQH3rgXGpQBAJf2u0QBwJ
8qjFVG8PpJV6yIrcLK8IxbrgJyKTeBsvxZc6/F092w1lU2ScHr96qSNJQFVyw94J
YQUZezyP2yVn6SHcm5Ok6lLnf/wo2Nf527ritAkAmrNg31pnEPa89giCJFKzIUkm
OJj82MZ8CoLmaL4u0gV4Ad5AghasCNASvrnTuc7BAh8COWDBOqHFpKc7esrHzilw
R8uBHJJ5cHujPQPcHTpMeeSWFUOo6IU+LUi91KxYM6ROjZIb+74e6Pi0fpIVPWAk
ycukcRPJKKGAucjDzst8TSwVsJZ659Q77UKp8PaIMms2s5njZvOwrXsTn0ZGF/uI
PLUISkt+jbj0o/EMYJdsanVfE4ZsZXA4JSDXXiCwOAswccRluMgkLEJxQsrsRac1
rfsWvUYqqIchTpfOSc/K0UgR4hcMIewiaF0FU0qru0eZfk6ErWVr7Pvnc6w+HkU6
TzYxFnHY03+LZsCvu8lYDysKgNg5/ibrklyekTkebmBgSMV7LuR9ewM12X7Yqmvw
ABhyNt8hRKHJx7yY4kg1WozwtIc+MhAWCVhKqetZzvc9E+KQbYcJHxiGOmuop5cJ
oWnhGSQbWPx6xOqtgvWczDfJfgwCBm4UAeIn5W/62KVG7EuukfA=
=fdap
-----END PGP SIGNATURE-----

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


Re: Expected behavior of calling javax.servlet.ServletRequest#getInputStream after javax.servlet.http.HttpServletRequest#getPart

Posted by "André Warnier (tomcat/perl)" <aw...@ice-sa.com>.
On 10.12.2019 15:31, Christopher Schultz wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
>
> Behrang,
>
> On 12/8/19 05:18, Behrang Saeedzadeh wrote:
>> If I call javax.servlet.ServletRequest#getInputStream after having
>> called javax.servlet.http.HttpServletRequest#getPart, even without
>> performing any operations on the given part, I am getting an empty
>> stream (0-bytes).
>>
>> Is this in compliance with the spec?
>
> What does the servlet spec say about that situation?
>

A bit in defense of the OP, I have to say that the Servlet Spec (4.0 final) does not seem 
extremely clear on that subject.
In section "3.1.1 When Parameters Are Available", it /does/ say this :

"If the conditions are met, post form data will no longer be available for
reading directly from the request object’s input stream."

But among those conditions that have to be met (just above that quote) is
"4. The servlet has made an initial call of any of the "getParameter family" of methods
on the request object."

(So there, it talks about "the getParameter family", not the "getPart" ones).

It only talks about the "getPart" methods in the next section "3.2 File upload", and in 
that section, all it says about the input stream is :
"If the servlet container does not provide the multi-part/form-data processing,
the data will be available through the HttpServletReuqest.getInputStream."

So the way I read this, is that there is nothing that explicitly says that the InputStream 
is no longer available if you have called "getPart".

(It is also in fact not very clear about what happens to the parameters, when the 
content-type of the Request is "multipart/form-data", which is only mentioned in section 3.2.)

On the other hand,
http://tomcat.apache.org/tomcat-9.0-doc/servletapi/index.html
--> Interface HttpServletRequest
says :

Part getPart(java.lang.String name)
       throws java.io.IOException,
              ServletException
Gets the named Part or null if the Part does not exist. *Triggers upload of all Parts*.
(emphasis mine)

which /may/ be taken to mean (and probably does) that it consumes the whole InputStream.

But again, this may be lacking some overall clarity.

In any case, the OP's question is not really unwarranted, unless there is some other 
explanation somewhere which I have missed.




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


Re: Expected behavior of calling javax.servlet.ServletRequest#getInputStream after javax.servlet.http.HttpServletRequest#getPart

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Behrang,

On 12/8/19 05:18, Behrang Saeedzadeh wrote:
> If I call javax.servlet.ServletRequest#getInputStream after having
> called javax.servlet.http.HttpServletRequest#getPart, even without
> performing any operations on the given part, I am getting an empty
> stream (0-bytes).
> 
> Is this in compliance with the spec?

What does the servlet spec say about that situation?

- -chris
-----BEGIN PGP SIGNATURE-----
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl3vrCgACgkQHPApP6U8
pFgXaRAAyIjSDXvbXJvqgKnjRoZch/OnPP8gKviPywjH+aOtI1pzDz/U1XoCWaba
GJJfw12LLrX/NcbtYG5hADQLnayn26Xi203F6TPG7PckHzwIp8UbhWa5qI/QNIeu
JRM1P7LZgsBVMX+we0ziXAwt1UtWIGZp6gU0V6z3zg0V2DSsEcu/zuRzqJqKweVH
fCmkJk2i6RInhw1eeEa4B6eRuAEl69WKPuddpJwNFdzj3hbAy0yMdnK/K9v/60BQ
igxdlITy7xL6V9tT9/DDXS07DByLop2bbectiMJ7J+6j7PksZygneGf4gPjRiDPw
eH2r6SloPN+sZGy7ttYqLI3/eMKKd8ad5s3+5ArnDgmBp/95y+pgaBUStUQQrycc
mcywbl2cxPF+7hv4vMquYIi24uQjQcBpSVKuiFllO/ThP2NDgII8kZ7pNBfOUJQd
pRDv4jwmpgh5ozm5dYfysLZ+fyxakkY0I1PnUSsJ7j0FEU9TT3+5UvbNjyPmPr0/
7dfHiiM+wLOQ9b1vc1wISwzZ1tgS2sLUU9js4RlpDXp5Ru5vIgREAF1fO3Za2MBT
hoRGbL4eAdzkAGPfMMYwCLr36FXv+Ra6KBScWd0V2u8cehz0nIp+QpyNrFXhdaK6
HQJLkaNmC/rY7Aw4nQ/AEIbT4a5ECUa4kHtimWYDse/I14zvYG4=
=ISFn
-----END PGP SIGNATURE-----

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