cxf-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sergey Beryozkin <sberyoz...@gmail.com>
Subject Re: CXF 3.1.6 - Headers Added MessageBodyWriter Don't Appear to be Flushed Before OutputStream
Date Tue, 17 May 2016 19:54:02 GMT
Hi Andrey
On 17/05/16 16:52, Andrei Shakirin wrote:
> Interesting,
>
> IEFT spec said that quoted-string is used for file names containing spaces: https://tools.ietf.org/html/rfc6266#section-5
>
> @Sergei: do you think it is client code or CXF responsibility to check that?
>
I'd say it the responsibility of the client code to make it understood 
by all the browsers.
Having CXF enforcing the correct values for certain headers can be 
problematic. Even technically challenging as in this case - we'd need to 
intercept all the map header writes (when they are done from inside 
MBW.writeTo()). But while I can imagine it can be done I'd rather not 
have CXF going into it :-).
One recent example. Cookie value with spaces needs to be double-quoted. 
As it happens the latest session spec says that all the Cookie 
attributes (besides the value), such as Path, etc, need to be 
double-quoted if they contain special chars, it even gives the example, 
such as "Path=a/b", where '/' is a special char, ignoring the fact that 
'/' is not a special one for a (URI) Path component.
So the issue was opened and this is what was done (with the best 
intentions). Next day after a release (or may the week :-)) we had an 
issue opened that Firefox was ignoring a double-quoted Path making their 
application expecting the cookies available at certain Paths 
non-functional. So the tweak was needed to be applied.

Thanks, Sergey

> Regards,
> Andrei.
>
>> -----Original Message-----
>> From: Christopher Gardner [mailto:chris.r.gardner@gmail.com]
>> Sent: Dienstag, 17. Mai 2016 17:32
>> To: users@cxf.apache.org
>> Subject: Re: CXF 3.1.6 - Headers Added MessageBodyWriter Don't Appear to
>> be Flushed Before OutputStream
>>
>> Sergey,
>>
>> Thanks for the suggestion.  I found the following:
>>
>> http://stackoverflow.com/questions/9154415/firefox-and-content-
>> disposition-header
>>
>> Someone on that thread said he or she used double quotes around the file
>> name.  This now works for me.
>>
>> Thanks for your help.
>>
>> On Tue, May 17, 2016 at 10:57 AM, Sergey Beryozkin
>> <sberyozkin@gmail.com>
>> wrote:
>>
>>> Which confirms the headers are being reported properly.
>>>
>>> You might want to check if there are some known restrictions in the
>>> way Firefox treats Content-Disposition, etc
>>>
>>> Sergey
>>>
>>> On 17/05/16 15:36, Christopher Gardner wrote:
>>>
>>>> For both FF and Chrome, I see the following in the trace utility.
>>>>
>>>> HTTP/1.1 200 OK
>>>> Server: Apache-Coyote/1.1
>>>> Date: Tue, 17 May 2016 14:25:26 GMT
>>>> Content-Disposition: attachment; filename=My_Report.xlsx
>>>> Content-Type:
>>>> application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
>>>> Transfer-Encoding: chunked
>>>>
>>>> On Tue, May 17, 2016 at 9:04 AM, Sergey Beryozkin
>>>> <sberyozkin@gmail.com>
>>>> wrote:
>>>>
>>>> Hi
>>>>> On 17/05/16 13:50, Christopher Gardner wrote:
>>>>>
>>>>> Sergey,
>>>>>>
>>>>>> To answer your questions:
>>>>>>
>>>>>> * Can you try writing a very small payload, few bytes, and see if
>>>>>> the browser prompts ?
>>>>>> I tested this in Firefox, which prompted me to save the file with
a
>>>>>> default file name (not the one the web service added to Content
>>>>>> Disposition).
>>>>>> However, today I tested in Chrome, which prompted me to save the
>>>>>> file name with the one that web service added to Content
>>>>>> Disposition.
>>>>>>
>>>>>> Right, so that does confirm that the header is reported back.
>>>>>>
>>>>>
>>>>> * Are you modifying the headers earlier before MBW gets the control ?
>>>>>
>>>>>> I'm not explicitly modifying the headers before MBW gets control.
>>>>>> My method signature and annotations look like this:
>>>>>>
>>>>>> @GET
>>>>>> @Path("{id}/content")
>>>>>>
>>>>>>
>>>>>> @Produces("application/vnd.openxmlformats-
>> officedocument.spreadshee
>>>>>> tml.sheet") public Response downloadContent(@PathParam("id")
>> Long
>>>>>> id) { ...
>>>>>> }
>>>>>>
>>>>>> OK
>>>>>>
>>>>>
>>>>> * Any chance you can get a basic Maven project created so that I can
>>>>> drop
>>>>>> a
>>>>>> war into Tomcat and try to reproduce ?
>>>>>> I'll try to work on that.
>>>>>>
>>>>>> Thanks, lets try to figure out first why different browsers are
>>>>>> acting
>>>>>>
>>>>> differently, to save you some time
>>>>>
>>>>> In the meantime, I'm still wondering about the difference in
>>>>> behavior
>>>>>> with
>>>>>> Firefox, which does prompt, but doesn't offer the file name at the
>>>>>> time of prompting, and Chrome, which behaves properly.
>>>>>>
>>>>>> Perhaps due to the fact that Content-Disposition is not really a
>>>>> top-level
>>>>> HTTP response header, it is meant to accompany the individual part,
>>>>> inside the actual multipart payload. May be this is why Firefox
>>>>> ignores it, while Chrome does not.
>>>>>
>>>>> Can you try the following check:
>>>>>
>>>>> start a tcp trace utility which will listen say on 9001 (and
>>>>> redirect to
>>>>> 9000 - the real service port), and update the form to submit via
>>>>> 9001, and check in the tcp trace what is coming back, which headers
>>>>> are set. Or may be enable Firefox and Chrome debug mode and see
>>>>> which headers came back there...
>>>>>
>>>>> Let me know what you find please
>>>>>
>>>>> Cheers, Sergey
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On Tue, May 17, 2016 at 7:37 AM, Sergey Beryozkin
>>>>> <sberyozkin@gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>> I have updated the existing test:
>>>>>>
>>>>>>>
>>>>>>> http://git-wip-us.apache.org/repos/asf/cxf/commit/e2fb0483
>>>>>>>
>>>>>>> and all works as expected: the two headers set in MBW are
>>>>>>> available to the client.
>>>>>>>
>>>>>>> I wonder why it does not work in your case.
>>>>>>> Can you try writing a very small payload, few bytes, and see
if
>>>>>>> the browser prompts ?
>>>>>>> Are you modifying the headers earlier before MBW gets the control
?
>>>>>>> Any chance you can get a basic Maven project created so that
I can
>>>>>>> drop a war into Tomcat and try to reproduce ?
>>>>>>>
>>>>>>> Cheers, Sergey
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 16/05/16 23:55, Christopher Gardner wrote:
>>>>>>>
>>>>>>> I'm writing a large object in MessageBodyWriter.writeTo().  Before
>>>>>>> I copy
>>>>>>>
>>>>>>>> the object to the OutputStream parameter, I set an additional
>>>>>>>> http header on the MultiValuedMap parameter.  This additional
>>>>>>>> header is "Content-Disposition" with an example value of
>>>>>>>> "attachment; filename=My_Report.xlsx".  The example code
looks
>>>>>>>> something like:
>>>>>>>>
>>>>>>>>                     Representation representation = ...
>>>>>>>>                     httpHeaders.add("Content-Disposition",
>>>>>>>> contentDispositionValue(representation.fileName()));
>>>>>>>>                     try {
>>>>>>>>
>>>>>>>> IOUtils.copyLarge(representation.content(),
>>>>>>>> entityOutputStream);
>>>>>>>>                     } catch (Exception e) {
>>>>>>>>                         ...
>>>>>>>>                     }
>>>>>>>>
>>>>>>>> Note this is all within a Hibernate transaction.  The
>>>>>>>> Representation object is contains a file name and a Blob.
>>>>>>>> Representation.content() calls Blob.getBinaryStream().
>>>>>>>>
>>>>>>>> In the browser, I'm prompted to download the content (in
this
>>>>>>>> case an excel file), but the file name is unknown.  However,
the
>>>>>>>> application log does show that the response includes the
content
>>>>>>>> disposition.
>>>>>>>>
>>>>>>>> Now say if I hard code the content-disposition value as in
this code:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>> Response.ok(myObjectThatGetsMarshalledViaMessageBodyWriter).heade
>>>>>>>> r("Content-Disposition", "attachment; filename=foo.xlsx").build()
>>>>>>>>
>>>>>>>>
>>>>>>>> The browser now knows the file name (fool.xlsx).
>>>>>>>>      "myObjectThatGetsMarshalledViaMessageBodyWriter" is
the
>> same
>>>>>>>> code that I have above.
>>>>>>>>
>>>>>>>> The javadoc for MessageBodyWriter.writeTo() states:
>>>>>>>>
>>>>>>>> "The message header map is mutable but any changes must be
>> made
>>>>>>>> before writing to the output stream since the headers will
be
>>>>>>>> flushed prior to writing the message body."
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>> http://docs.oracle.com/javaee/7/api/javax/ws/rs/ext/MessageBodyWr
>>>>>>>> iter.html#writeTo-T-java.lang.Class-java.lang.reflect.Type-java.l
>>>>>>>> ang.annotation.Annotation:A-javax.ws.rs.core.MediaType-
>> javax.ws.r
>>>>>>>> s.core.MultivaluedMap-java.io.OutputStream-
>>>>>>>>
>>>>>>>> Is there anything I can do to ensure the header value created
>>>>>>>> within
>>>>>>>> MessageBodyWriter.writeTo() is seen before the body is?
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>> Sergey Beryozkin
>>>>>>>
>>>>>>> Talend Community Coders
>>>>>>> http://coders.talend.com/
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>> --
>>>>> Sergey Beryozkin
>>>>>
>>>>> Talend Community Coders
>>>>> http://coders.talend.com/
>>>>>
>>>>>
>>>>
>>>
>>> --
>>> Sergey Beryozkin
>>>
>>> Talend Community Coders
>>> http://coders.talend.com/
>>>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Mime
View raw message