Duplicate `<changes>` entry in PrimeFaces PartialResponseWriter
Closed this issue · 7 comments
Describe the bug
Original Report: primefaces/primefaces#12189
in PrimeFaces 14.0.0 we made this change per @BalusC recommendation: primefaces/primefaces#9518
When using ajax="true"
and primefaces.CSP
enabled the FileDownload is executed twice. I have debugged it and it seems to be Mojarra is writing the <changes>
entry twice and MyFaces is only writing it once.
Mojarra 4.0.7
<?xml version='1.0' encoding='UTF-8'?>
<partial-response>
<changes>
<update id="j_id1:jakarta.faces.ViewState:0"><![CDATA[1583319729054827418:-7566133317078344421]]></update>
<eval><![CDATA[if(window.PrimeFaces){PrimeFaces.csp.init('MjAzM2FlNWUtMzk3Ny00OWRlLWJjMGMtYjBkZmYwOTI2YmU4');};;PrimeFaces.download('/jakarta.faces.resource/dynamiccontent.properties.xhtml?ln=primefaces&v=14.0.1&pfdrid=c07524ce314cee24b9418afbab32a60f&pfdrt=sc&pfdrid_c=false&uid=2dc9d154-ce3e-4490-951b-6c624acfde8e', 'text/plain', 'default.txt', 'primefaces.download_test');]]></eval>
</changes>
<changes>
<eval><![CDATA[if(window.PrimeFaces){PrimeFaces.csp.init('MjAzM2FlNWUtMzk3Ny00OWRlLWJjMGMtYjBkZmYwOTI2YmU4');};;PrimeFaces.download('/jakarta.faces.resource/dynamiccontent.properties.xhtml?ln=primefaces&v=14.0.1&pfdrid=c07524ce314cee24b9418afbab32a60f&pfdrt=sc&pfdrid_c=false&uid=2dc9d154-ce3e-4490-951b-6c624acfde8e', 'text/plain', 'default.txt', 'primefaces.download_test');]]></eval>
</changes>
</partial-response>
MyFaces 4.0.2
<?xml version="1.0" encoding="UTF-8"?>
<partial-response id="j_id__v_0">
<changes>
<update id="jakarta.faces.Resource"><![CDATA[]]></update>
<update id="j_id__v_0:jakarta.faces.ViewState:1"><![CDATA[N2RiOTM1NWQ5ZDA5YjJjODAwMDAwMDAx]]></update>
<eval><![CDATA[if(window.PrimeFaces){PrimeFaces.csp.init('MmE5MTA0ZWQtNTJkMC00OTExLTkyYmQtOTkyYjNhYWY1NmRk');};;PrimeFaces.download('/jakarta.faces.resource/dynamiccontent.properties.xhtml?ln=primefaces&v=14.0.1&pfdrid=c07524ce314cee24b9418afbab32a60f&pfdrt=sc&pfdrid_c=false&uid=1a422c9b-b912-4c60-a18b-0523361238f6', 'text/plain', 'default.txt', 'primefaces.download_test');]]></eval>
</changes>
</partial-response>
Reproducer
- Open the Dialog and press Download or Download AJAX.
- With non-ajax download it works fine.
- With AJAX download you will see two duplicate files download default.txt and default(1).txt.
Expected behavior
Only 1 file downloaded.
PrimeFaces edition
Community
PrimeFaces version
14.0.1
Theme
No response
JSF implementation
Mojarra
JSF version
2.3
Java version
11
Found a workaround but can't explain why...
It's because CspPartialResponseWriter extends PrimePartialResponseWriter
so PrimePartialResponseWriter#endDocument()
impl, which adds eval scripts, is invoked twice. Make it extend PartialResponseWriter
instead and the problem will go away.
let me test that. thank you.
OK so that fixes Mojarra and break MyFaces. The new result is this...
Mojarra
<?xml version='1.0' encoding='utf-8'?>
<partial-response>
<changes>
<update id="j_id1:javax.faces.ViewState:0"><![CDATA[-8888652108271766523:-9198939220272553376]]></update>
</changes>
<changes>
<eval><![CDATA[if(window.PrimeFaces){PrimeFaces.csp.init('N2QyNTFlYWYtOGM5MS00NjBkLWFkN2EtODExOWVlMDkyMDU4');};;PrimeFaces.download('/javax.faces.resource/dynamiccontent.properties.xhtml?ln=primefaces&v=15.0.0-SNAPSHOT&pfdrid=c07524ce314cee24b9418afbab32a60f&pfdrt=sc&pfdrid_c=false&uid=b4ffba85-2f08-4766-9001-f3fed0f52ba1', 'text/plain', 'default.txt', 'primefaces.download_test');]]></eval>
</changes>
</partial-response>
MyFaces (missing eval script)
<?xml version="1.0" encoding="UTF-8"?>
<partial-response id="j_id__v_0">
<changes>
<update id="javax.faces.Resource"><![CDATA[]]></update>
<update id="j_id__v_0:javax.faces.ViewState:1"><![CDATA[ODM4NzY3MzRCMTc2RUY4RDAwMDAwMDAx]]></update>
</changes>
</partial-response>
OK with your help got to the bottom of it the real problem was in PrimePartialViewContent passing the writer into a writer.
Hmm ok probably MyFaces still has a wrapped-vs-getWrapped bug in its ResponseWriter(Wrapper) impl that it fails to invoke the PrimePartialResponseWriter#endDocument when given a wrapped writer.
Agreed I will take a look at MyFaces