Hi Sergey,

2015-08-20 12:33 GMT+02:00 Sergey Beryozkin <[email protected]>:
> Hi Aki
>
> Re your tests below: can you clarify please how the JAX-RS method is
> configured, what @Consumes it has ? And what do you mean sporadically ?

the method has no @Consumes but has only @POST and @Path.
But I think my problem was caused by my mistake in having another
operation that was interfering with this operation. So the operation
was randomly picked up ;-(. Sorry. Because I added this operation for
an empty body testing and didn't pay attention on interfering with the
existing operations.

>
> I appreciate you spending time on it :-), it is better that we have total
> understanding of what is going on in these cases.
>
> That said I'm not sure what exactly you are trying to suggest.

I thought something was happening at the server side, as I saw the
outgoing wire messages always look the same. But as I said, there was
an error in the way I configured my endpoint that caused that sporadic
errors.

>
> As I said that if we do not set any CT at all with the empty payloads then
> we have various side-effects when HTTPUrlConnection is used, in particular:
> - if it is empty POST (or PUT as you confirmed) HTTPUrlConnection defaults
> to a form content-type which IMHO is wrong
> - I've linked to a JIRA that was reported against CXF dropping Content-Type
> which was causing side-effects when GET was going via HTTP proxy
>

If you mean CXF-6214, I don't know who is adding text/xml.
HTTPUrlConnection is not adding any content-type when using GET and
going directly or over an http proxy. So I suppose their proxy is
doing it.

>
> So to avoid all of this CXF puts */* for empty requests. As you rightly
> observed most of real world services would not even bother about checking
> this CT for GET. Except for SpringBoot-powered services.
> Let me even criticize SpringBoot here: while CXF sending a redundant and
> arguably bogus CT with GET is not needed for HTTP but prely a workaround
> against HTTPUrlConnection issues, an HTTP server that rejects a request
> because a header that is not needed for processing this request is
> apparently invalid is anti-HTTP because the WEB processing is, among other
> things, about ignoring HTTP properties that are not relevant for processing
> a given request.

I can agree with your argument and SpringBoot should follow the
robustness principle that is the fundamental spirit of HTTP.
Otherwise, it is unnecessarily limiting its usability while not
getting any benefit from enforcing that strict rule.

>
> So now we let people:
> - configure CXF to drop CT no matter what
> - override */* CT
>
> If we have an empty request then not setting CT by default with
> HTTPUrlConnection causes more side-effects than adding CT */*.
>
> And indeed, now, if we have an empty POST and we know the target server
> accepts empty and non-empty text/xml requests then it is only natural that a
> user would set manually text/xml or application/json - so where is the
> problem ?

No. There is no problem.

>
> The situation with HTTP proxy + GET where CT is dropped (see JIRA) is a
> blocker IMHO. Can you please look at the JIRA I linked to and try to confirm
> it is a problem in your set-up, if not then I'll ask Alexey to help with
> double-checking it again in his set up and then we continue narrowing it
> down. OK ?

I don't know which JIRA ticket you mean.

For CXF-6214, I suspect that their proxy is causing this issue and not
HttpURLConnection nor CXFClient.
For CXF-6553, this was an issue and you just fixed it with the logging
issue ticket CXF-6548.
So, I'll also set CXF-6548 as resolved. And for CXF-6538, as I
commented there, I didn't see any difference in the behavior, with or
without using a proxy.

With the current option that you added and the fix to the initial
default content-type setting, there is no actual problem.
thanks.

regards, aki


>
>
> Thanks, Sergey
>
>
>
> On 20/08/15 11:01, Aki Yoshida wrote:
>>
>> Hi Sergey,
>> maybe the original issue has some other cause. After running some
>> tests (starting an JAXRS endpoint and invoking it over POST with an
>> empty content), I am observing sporadically a strange issue at the
>> server that the server think the call is for parameter.getType() is
>> FORM. The wire message looks always the same as shown below (shown the
>> inbound messages logged at the server). But sporadically
>> JAXRSUtils#processParameter gets called with parameter whose type is
>> FORM somehow. And when this happens, the missing content type or some
>> non matching content type like plain/text leads to
>> javax.ws.rs.NotSupportedException: HTTP 415 Unsupported Media Type. In
>> contrast, this method is most of the time called with REQUEST_BODY.
>> This has something do with some issue in setting up the endpoint and
>> it sporadically fails to get setup correctly. Even in that case, the
>> other calls are fine but those with an empty body will suffer when it
>> doesn't carry the appropriate content-type value because the server
>> wrongly assumes the message type.
>>
>> The message suffers looks like this.
>>
>> Address: http://localhost:8282/endpoint/map/11foo
>> Encoding: ISO-8859-1
>> Http-Method: POST
>> Content-Type: text/plain
>> Headers: {Accept=[text/plain], Cache-Control=[no-cache],
>> connection=[keep-alive], Content-Length=[0],
>> content-type=[text/plain], Host=[localhost:8282], Pragma=[no-cache],
>> User-Agent=[Apache CXF
>> 3.1.3-SNAPSHOT-ae95e49c500b529236732a14c86b4c9e100ac143]}
>>
>> In contrast, when the request has the content-type: */*, it does not
>> suffer this issue because its type is not rejected by the FORM
>> processing.
>>
>> Address: http://localhost:8282/endpoint/map/11foo
>> Encoding: ISO-8859-1
>> Http-Method: POST
>> Content-Type: */*
>> Headers: {Accept=[text/plain], Cache-Control=[no-cache],
>> connection=[keep-alive], Content-Length=[0], content-type=[*/*],
>> Host=[localhost:8282], Pragma=[no-cache], User-Agent=[Apache CXF
>> 3.1.3-SNAPSHOT-ae95e49c500b529236732a14c86b4c9e100ac143]}
>>
>>
>> So, I think when we find out why sporadically the endpoint is wrongly
>> started and fix it, we can avoid sending the bogus content-type for
>> the empty payload.
>>
>> regards, aki
>>
>>
>> 2015-08-13 19:23 GMT+02:00 Aki Yoshida <[email protected]>:
>>>
>>> Hi Sergey,
>>> thanks.
>>> Yes we have a proxy.
>>> I'll check it against our proxy tomorrow.
>>> regards, aki
>>>
>>> 2015-08-13 14:27 GMT+02:00 Sergey Beryozkin <[email protected]>:
>>>>
>>>> Hi,
>>>> We've talked a bit more about it with Aki where we indeed came to a
>>>> shared
>>>> understanding it was a workaround specifically around some
>>>> HttpUrlConnection
>>>> issues.
>>>> I've added a new property "set.content.type.for.empty.request" that (in
>>>> case
>>>> of the default conduit) can be set to false, is enabled by default
>>>> otherwise.
>>>>
>>>> I'm hoping that eventually we can have this property disabled by default
>>>> over time. See CXF-6528.
>>>> Aki, do you have an HTTP proxy setup in your office somewhere ? May be
>>>> you
>>>> can double check if GET with custom Accept is affected or not with
>>>> "set.content.type.for.empty.request" set to false ?
>>>>
>>>> Thanks, Sergey
>>>>
>>>>
>>>> On 11/08/15 15:02, Aki Yoshida wrote:
>>>>>
>>>>>
>>>>> Hi Sergey,
>>>>> */* may appear somewhere where the media-type is specified, but this
>>>>> value still appears to violate the BNF rules given for the
>>>>> Content-Type header.
>>>>> http://tools.ietf.org/html/rfc2045#section-5.1
>>>>>
>>>>> So, I still think it is actually wrong to set the content-type header
>>>>> with */*, no?
>>>>> regards, aki
>>>>>
>>>>> 2015-08-11 12:25 GMT+02:00 Sergey Beryozkin <[email protected]>:
>>>>>>
>>>>>>
>>>>>> Hi Aki
>>>>>> On 11/08/15 10:14, Aki Yoshida wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> HI Sergey,
>>>>>>> it could be that the problem had something to do with the proxy's
>>>>>>> configuration and not really a bug? Not related to this content-type
>>>>>>> issue, we had a similar misconfiguration in the forwarding rule
>>>>>>> (e.g.,
>>>>>>> it was letting only "Upgrade" accepted but not "upgrade") that
>>>>>>> prevented some clients e.g., IE from opening a websocket through it.
>>>>>>> ;-)
>>>>>>>
>>>>>> Well, I'm not sure, one thing is definite is that setting a wildcard
>>>>>> Content-Type helped to solve the strange Accept replacement bug. As I
>>>>>> said
>>>>>> even without a proxy if it empty POST then a form payload is added. I
>>>>>> think
>>>>>> in that the case the target server had @Produces (text/xml) or json
>>>>>> and
>>>>>> the
>>>>>> net effect was that the runtime returned the error due to media type
>>>>>> mismatches.
>>>>>>
>>>>>> The problem is not a wildcard but the actual redundant use of
>>>>>> Content-Type.
>>>>>> It is not an http consumer issue, ie. why Spring bother parsing
>>>>>> Content-Type
>>>>>> for GET ?
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Regarding the use of value */* for the content-type header , isn't
>>>>>>> this value syntactically invalid?
>>>>>>>
>>>>>> Not at all, */* is a valid media type. The Spring error is arguable
>>>>>> because
>>>>>> the more friendly server can assume instead that */* is equivalent to
>>>>>> CT
>>>>>> missing and then defaulting to some type as in JAX-RS servers.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> There is something interesting in the following section of the MIME
>>>>>>> spec.
>>>>>>> http://tools.ietf.org/html/rfc2045#section-5.2
>>>>>>> ----
>>>>>>> Default RFC 822 messages without a MIME Content-Type header are taken
>>>>>>>       by this protocol to be plain text in the US-ASCII character
>>>>>>> set,
>>>>>>>       which can be explicitly specified as:
>>>>>>>
>>>>>>>         Content-type: text/plain; charset=us-ascii
>>>>>>>
>>>>>>> This default is assumed if no Content-Type header field is specified.
>>>>>>>       It is also recommend that this default be assumed when a
>>>>>>>       syntactically invalid Content-Type header field is encountered.
>>>>>>> ...
>>>>>>> ----
>>>>>>>
>>>>>>> That means, we could also use "Content-type: text/plain;
>>>>>>> charset=us-ascii" instead of the no content-type to have the same
>>>>>>> effect or overwrite the default value with some valid content type.
>>>>>>> Interestingly, the last sentence recommends the server to accept a
>>>>>>> syntactically invalid type like */* and assume the default text/plain
>>>>>>> ascii type. But it is only recommended and not required.
>>>>>>>
>>>>>> I'm not sure we should use text/plain for GETs :-) as a workaround.
>>>>>> */*
>>>>>> is a
>>>>>> valid media type, though I do agree there should be a way to
>>>>>> completely
>>>>>> block it. This is already done in case of async conduits which do not
>>>>>> exhibit strange side-effects...
>>>>>>
>>>>>> Thanks, Sergey
>>>>>>
>>>>>>
>>>>>>> regards, aki
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 2015-08-10 22:26 GMT+02:00 Sergey Beryozkin <[email protected]>:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On 10/08/15 21:23, Sergey Beryozkin wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Hi Aki
>>>>>>>>>
>>>>>>>>> What I know is that if we have HTTP Proxy and GET without
>>>>>>>>> Content-Type
>>>>>>>>> then whatever Accept is there (ex. Accept: application/json) will
>>>>>>>>> be
>>>>>>>>> replaced with */* by HttpUrlConnection (or proxy, not sure) - I
>>>>>>>>> have a
>>>>>>>>> comment in the code about it though I haven't tried it myself - it
>>>>>>>>> was
>>>>>>>>> reported by my company's colleague.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> and wildcard is set to bypass that proxy bug, because it is just a
>>>>>>>> neutral
>>>>>>>> value.
>>>>>>>>
>>>>>>>> Sergey
>>>>>>>>
>>>>>>>>>
>>>>>>>>> While it is a redundant header I'd say Spring is not very HTTP
>>>>>>>>> friendly
>>>>>>>>> - in GET cases Content-Type simply needs to be ignored as opposed
>>>>>>>>> to
>>>>>>>>> reacting with the exception because it has no effect on the
>>>>>>>>> processing
>>>>>>>>> -
>>>>>>>>> the question is - would they accept GET with Content-Type
>>>>>>>>> application/json, etc :-)
>>>>>>>>>
>>>>>>>>> I'm not saying having a wildcard Content-Type with GET is very HTTP
>>>>>>>>> friendly either :-). I'll add a property, disabled by default, but
>>>>>>>>> if
>>>>>>>>> enabled then drop Content-Type.
>>>>>>>>>
>>>>>>>>> Do you have HTTP proxy somewhere nearby ? If yes, may be you can
>>>>>>>>> double
>>>>>>>>> check ? We can definitely have this new property (always drop CT
>>>>>>>>> for
>>>>>>>>> empty payloads) enabled by default eventually once the checks are
>>>>>>>>> green
>>>>>>>>>
>>>>>>>>> Thanks. Sergey
>>>>>>>>>
>>>>>>>>> On 10/08/15 18:37, Aki Yoshida wrote:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Hi Sergey,
>>>>>>>>>> If I undertand the original query, Steen is seeing "Content-Type:
>>>>>>>>>> */*"
>>>>>>>>>> in their GET request.
>>>>>>>>>> In that case, I don't understand why this unnecessary header with
>>>>>>>>>> this
>>>>>>>>>> invalid type value needs to be there to avoid some side-effect
>>>>>>>>>> that
>>>>>>>>>> you mentioned.
>>>>>>>>>> Did I misunderstand the situation?
>>>>>>>>>>
>>>>>>>>>> regards, aki
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> 2015-08-10 16:32 GMT+02:00 Sergey Beryozkin
>>>>>>>>>> <[email protected]>:
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> There's some history related to this issue.
>>>>>>>>>>> At some point I updated the CXF client code to ignore
>>>>>>>>>>> Content-Type
>>>>>>>>>>> completely. Then the side-effects caused by HttpUrlConnection
>>>>>>>>>>> started
>>>>>>>>>>> appearing:
>>>>>>>>>>>
>>>>>>>>>>> - empty POSTs lead to HttpUrlConnection setting a form
>>>>>>>>>>> conetnt-type
>>>>>>>>>>> - even more serious, if HTTP Proxy is used, a custom Accept is
>>>>>>>>>>> completely
>>>>>>>>>>> lost for requests with the empty payloads.
>>>>>>>>>>>
>>>>>>>>>>> So indeed, I reverted it to have Content-Type dropped in case of
>>>>>>>>>>> empty
>>>>>>>>>>> payloads only if the async conduit is used.
>>>>>>>>>>>
>>>>>>>>>>> I think it makes sense to let users control it via a property, as
>>>>>>>>>>> it
>>>>>>>>>>> obvious
>>>>>>>>>>> that unfortunately a single solution does not work with
>>>>>>>>>>> HttpUrlConnection -
>>>>>>>>>>> I'll take care of it.
>>>>>>>>>>> It might also make sense to check what HttpUrlConnection does in
>>>>>>>>>>> Java
>>>>>>>>>>> 8 and
>>>>>>>>>>> 9 re the above two side-effects
>>>>>>>>>>>
>>>>>>>>>>> Cheers, Sergey
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On 10/08/15 14:31, Steen Elvstrøm wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> I've been trying to use Apache CXF JAX-RS (version 3.0.4) to
>>>>>>>>>>>> send
>>>>>>>>>>>> GET
>>>>>>>>>>>> requests to a Spring Boot application. Unfortunately CFX adds a
>>>>>>>>>>>> Content-Type: */* to the request headers which is not accepted
>>>>>>>>>>>> by
>>>>>>>>>>>> spring
>>>>>>>>>>>> resulting in a 400 response stating "'Content-Type' cannot
>>>>>>>>>>>> contain
>>>>>>>>>>>> wildcard
>>>>>>>>>>>> type '*'".
>>>>>>>>>>>>
>>>>>>>>>>>> Since a Content-Type header on a GET request doesn't really make
>>>>>>>>>>>> sense
>>>>>>>>>>>> when
>>>>>>>>>>>> the request haven't got a request entity I guess it must be a
>>>>>>>>>>>> bug.
>>>>>>>>>>>>
>>>>>>>>>>>> A possible workaround is to add "cxf-rt-transports-http-hc" as a
>>>>>>>>>>>> dependency
>>>>>>>>>>>> and setting the property "use.async.http.conduit". Is it a valid
>>>>>>>>>>>> durable
>>>>>>>>>>>> way
>>>>>>>>>>>> to solve the issue?
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> View this message in context:
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> http://cxf.547215.n5.nabble.com/Why-does-CXF-JAX-RS-set-content-type-on-GET-requests-with-no-body-tp5759908.html
>>>>>>>>>>>>
>>>>>>>>>>>> Sent from the cxf-user mailing list archive at Nabble.com.
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sergey Beryozkin
>>>>>>>>
>>>>>>>> Talend Community Coders
>>>>>>>> http://coders.talend.com/
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sergey Beryozkin
>>>>>>
>>>>>> Talend Community Coders
>>>>>> http://coders.talend.com/
>>>>>>
>>>>>> Blog: http://sberyozkin.blogspot.com
>>>>
>>>>
>>>>
>
>
> --
> Sergey Beryozkin
>
> Talend Community Coders
> http://coders.talend.com/

Reply via email to