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

[jsr339-experts] Re: No Content-Type in Request - when default to application/octet-stream

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Tue, 21 Jan 2014 16:22:50 +0000

Hi Santiago
On 21/01/14 14:23, Santiago Pericas-Geertsen wrote:
> Hi Sergey,
>
> It's clearly a case that could be made explicit in the spec by consider the no CT case. However, it still seems that the easiest solution at this point would be for the client to add a CT. This would make the entire system more robust and would allow better compatibility with servers --regardless of whether they are based on JAX-RS or not.
>
I agree, I've recommended it too with the comments at the related JIRA
issue - there's a general agreement to it
> In any case, I don't see a problem with adding a note about this in 2.1.
>
Sounds good - it would help avoiding the side-effects in some edge cases
Thanks, Sergey
> -- Santiago
>
> On Jan 20, 2014, at 6:53 AM, Sergey Beryozkin <sberyozkin_at_talend.com> wrote:
>
>> By the way, here is why I asked.
>>
>> A project depending on Apache CXF has a root resource like this one:
>>
>> @Path("root")
>> public class Root {
>>
>> @Consumes("*/*")
>> @PUT
>> public Response process(InputStream is) {
>> // auto-detect a stream content type by reading into IS if needed and parse it
>>
>> }
>> }
>>
>> where the content is submitted with a "curl -T" command which, note, does not set Content-Type in the request.
>>
>> And all has worked fine before a new method has been added:
>>
>> @Path("root")
>> public class Root {
>>
>> @Consumes("*/*")
>> @PUT
>> public Response process(InputStream is) {
>> // auto-detect a stream content type by reading into IS if needed and parse it
>>
>> }
>>
>> @Consumes("multipart/form-data")
>> @PUT
>> public Response processForm(SomeMultipartPart part) {
>> // extract the attachments and deal with them
>> }
>> }
>>
>> what happens, now that JAX-RS 2.0 clearly specifies how to choose between multiple resource method candidates listening on the same path, is that "processForm" is selected when "curl -T" is used due to the latter setting no Content-Type.
>>
>> Next, when reading SomeMultipartPart, Content-Type (as per the spec) is set to application/octet-stream, and the multipart provider fails to recognize it and the processing fails.
>>
>> Now, if the spec said "If CT is not available then set it to application/octet-stream before the method selection is done" then adding the new processForm() method would have no negative side-effect, the original process() would've been selected and things would work as usual.
>>
>> Now the easy fix if for the client to add Content-Type - this is reasonable but in the above case I know people have written their scripts/tests to use "curl -T" without setting a CT which worked fine due to the auto-detection logic of the server.
>>
>> Effectively after migrating to JAX-RS 2.0 aware Apache CXF they now face a minor backward-compatibility issue.
>>
>> I'm perfectly OK with accepting it is a CXF bug but as I said below I quite firmly believe the defaulting to application/octet-stream is delayed in CXF till the moment the stream is read due to TCK failures.
>>
>> As such I'd like to treat it as a JAX-RS 2.0 spec text bug, and would like to propose to fix it for 2.1.
>>
>> Any comments ? When does Jersey or RestEasy default to application/octet-stream if no CT is specified in the request ?
>>
>> Thanks, Sergey
>>
>> On 19/01/14 18:52, Sergey Beryozkin wrote:
>>> Hi
>>>
>>> According to the spec, if no Content-Type is specified in the request
>>> then it has to be defaulted to application/octet-stream, this is
>>> mentioned in the section describing how MBR can be found for mapping the
>>> stream into a given Java type.
>>>
>>> My question is, should this 'no CT to application/octet-stream
>>> defaulting' take place earlier, when the method selection takes place ?
>>>
>>> I think I did try to do it earlier initially but saw CXF failing a
>>> couple of early TCK tests as a result.
>>>
>>> So what CXF does now is this: if no CT is available - set it to '*/*'
>>> and do the method selection. Next, when the method selection is done,
>>> and when MBR is checked, it is set to application/octet-stream.
>>>
>>> I think this is wrong, but I said I believe it was TCK failures which
>>> forced me to do it.
>>>
>>> Can someone please confirm the above algorithm is correct or should we
>>> actually have a 2.1 JIRA issue clarifying that when no CT is available
>>> then set it to application/octet-stream before the resource methods are
>>> selected ?
>>>
>>>
>>> Thanks, Sergey
>>>
>>
>