jsr339-experts@jax-rs-spec.java.net

[jsr339-experts] Re: [jax-rs-spec users] Re: _at_Consumes matching when Content-Type is null

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Thu, 23 May 2013 21:26:38 +0100

On 23/05/13 21:11, Bill Burke wrote:
>
>
> On 5/23/2013 3:58 PM, Sergey Beryozkin wrote:
>> On 23/05/13 19:18, Bill Burke wrote:
>>>
>>>
>>> On 5/23/2013 1:47 PM, Marek Potociar wrote:
>>>>
>>>> On May 23, 2013, at 7:34 PM, Bill Burke <bburke_at_redhat.com> wrote:
>>>>
>>>>>
>>>>>
>>>>> On 5/23/2013 11:00 AM, Marek Potociar wrote:
>>>>>>
>>>>>> On May 22, 2013, at 9:56 PM, Bill Burke <bburke_at_redhat.com> wrote:
>>>>>>
>>>>>>>
>>>>>>> @Consumes("text/plain")
>>>>>>> @POST
>>>>>>> @Path("plain")
>>>>>>> public void tckPOST();
>>>>>>>
>>>>>>> @Path("start")
>>>>>>> @POST
>>>>>>> public void start()
>>>>>>>
>>>>>>> @Path("start")
>>>>>>> @POST
>>>>>>> @Consumes("application/xml")
>>>>>>> public void start(XML xml)
>>>>>>>
>>>>>>>
>>>>>>> I have 2 different test cases whose solutions currently conflict.
>>>>>>>
>>>>>>>
>>>>>>> Case #1:
>>>>>>>
>>>>>>> The TCK is posting a NULL entity with no Content-Type header to:
>>>>>>>
>>>>>>> POST /plain
>>>>>>>
>>>>>>> The TCK is expecting this to match tckPOST() even though two
>>>>>>> different sections of the spec conflict:
>>>>>>>
>>>>>>> - Section 4.2.1.1 Says that if the request does not contain a
>>>>>>> Content-Type, then application/octet-stream is used. This is for
>>>>>>> matching bodies though.
>>>>>>
>>>>>> Yes, I think that one should not apply to requests without a body.
>>>>>>
>>>>>>>
>>>>>>> - The matching algorithm in Step 3(a) says:
>>>>>>>
>>>>>>> "The media type of the request entity body *(if any)* is supported
>>>>>>> by the input format"
>>>>>>>
>>>>>>> What does *if any* mean? The TCK seems to assume that if the
>>>>>>> Content-Type header is null, then the @Consumes annotation is
>>>>>>> ignored. Or am I supposed to look at the method to see if it is
>>>>>>> expecting a request body?
>>>>>>
>>>>>> I guess that's the correct interpretation. FWIW, the whole test is
>>>>>> good in that it uncovers these hidden portability issues, but I
>>>>>> would in this case even support removing the test as it is testing a
>>>>>> completely artificial use case.
>>>>>>
>>>>>
>>>>> Only real way to test for a body is to either a) check the
>>>>> Content-Type header is null or b) check the resource method to see if
>>>>> it expects a body. So the 2 start() methods would be ambiguous so
>>>>> I'm free to match them however I see fit. This is another user
>>>>> posted use case where they want a no-param start() method to match if
>>>>> there is no content.
>>>>
>>>> What about checking Content-Length and/or trying to read from an
>>>> entity input stream?
>>>>
>>>
>>> You can't read from the input stream. Bytes may not be ready and you
>>> probably do not want to block for any amount of time. I guess checking
>>> for Content-Length or Transfer-Encoding would work as long as you're not
>>> doing some COMET protocol with JAX-RS.
>>>
>>>
>> I opened a JIRA request recently for the spec to stay that checking for
>> 'Content-Length: 0' was the only portable way for the JAX-RS runtime to
>> tell if a request was empty or not. I tried checking for Content-Length,
>> in one case (with async client via HTTP client) I got a non empty
>> payload with no Content-Length at all, and when I tried to do
>> InputStream.available() I got one of security tests failing...
>>
>
> I guess checking to see if the resource method expects a body is the
> only thing you can reliably do then?
>
As far as I recall some tests there enforce that MBR throws an exception
if the body is empty so I guess the test methods have body parameters in
place...

Cheers, Sergey