[jira] [Comment Edited] (TRINIDAD-2567) Trinidad secret generation is not thread-safe
[ https://issues.apache.org/jira/browse/TRINIDAD-2567?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17283356#comment-17283356 ] Kyle Stiemann edited comment on TRINIDAD-2567 at 2/11/21, 8:40 PM: --- Thanks [~tandraschko], I'm not super worried about this getting fixed as the workaround was trivial for me. I really just wanted to document the issue so that if I ever run into it again (or if someone else does), the problem (and workaround) is googleable. was (Author: stiemann...@gmail.com): Thanks [~tandraschko], I'm not super worried about this getting fixed as the workaround was trivial for me. I really just wanted to document the issue so that if I ever run into it again (or if someone else does), the problem (and workaround) is in google. > Trinidad secret generation is not thread-safe > - > > Key: TRINIDAD-2567 > URL: https://issues.apache.org/jira/browse/TRINIDAD-2567 > Project: MyFaces Trinidad > Issue Type: Bug > Components: Components, Facelets, Infrastructure, Plugins >Affects Versions: 2.2.1-core >Reporter: Kyle Stiemann >Priority: Minor > > Sending multiple requests in rapid succession to a Trinidad application that > has just started will cause multiple different secret keys to be generated. > If multiple {{POST}} s are sent, all but 1 will fail with a > {{ViewExpiredException}}. Trinidad generates the secret keys in > {{StateUtils}} somewhat like this: > {code} > private static SecretKey getSecret(ExternalContext ctx) { > SecretKey secretKey = (SecretKey) > ctx.getApplicationMap().get(INIT_SECRET_KEY_CACHE); > if (secretKey == null) { > secretKey = > createSecretKey(KeyGenerator.getInstance(getAlgorithm(ctx)).generateKey().getEncoded()); > ctx.getApplicationMap().put(INIT_SECRET_KEY_CACHE, secretKey); > } > return secretKey; > } > {code} > {{FormRenderer}} calls {{ViewHandler.writeState()}} which calls the > {{StateUtils.getSecret()}} method on each request. If more than 1 request > calls {{getSecret()}} before the secret key is set in > {{INIT_SECRET_KEY_CACHE}}, each call to {{getSecret()}} has the chance to see > a {{null}} value for {{INIT_SECRET_KEY_CACHE}}, generate a new secret key, > and replace any existing secret in {{INIT_SECRET_KEY_CACHE}}. Any view state > that was generated using the discarded secrets will be unusable and cause a > {{ViewExpiredException}}. > h2. Workarounds > The simplest workaround is to set values for the secret keys as > {{init-param}} s: > https://cwiki.apache.org/confluence/display/MYFACES2/Secure+Your+Application. > For example, in the {{web.xml}} (*note that the provided values are examples > and should not be used in a production application*): > {code:xml} > > org.apache.myfaces.SECRET > > VEVTVF9LRVk= > > > org.apache.myfaces.MAC_SECRET > > VFJJTklEQURfVEVTVF9NQUNfU0VDUkVU > > {code} > h2. Potential Fixes > # Save 1 generated key in the application scope using either > {{Map.putIfAbsent()}} or some other kind of synchronization. Use only the key > from the application scope to generate the {{SecretKey}} object. Even if > secret object caching is disabled, only 1 key would be used to generate the > secret object, so the application would still function. > # Use {{Map.putIfAbsent()}} to ensure only 1 secret is ever cached in the > application. If secret caching is disabled, the application would still not > function (which is the same as the existing behavior). > h2. Steps to Reproduce: > # Create 1 WAR with a simple {{ping.xhtml}} endpoint: > {code:xml} >xmlns:h="http://java.sun.com/jsf/html; > xmlns="http://www.w3.org/1999/xhtml;> > > > pong > > > {code} > # Create another Trinidad WAR with the following view and bean: > *{{hello.xhtml}}:* > {code:xml} > >xmlns:tr="http://myfaces.apache.org/trinidad; > title="hello"> > > required="true" value="#{helloBean.name}" /> > > > > > {code} > *{{HelloBean.java}}:* > {code:java} > @ManagedBean > @RequestScoped > public final class HelloBean { > private String name; > public String getName() { > return name; > } > public void setName(String name) { > this.name = name; > } > } > {code} > # Start up an app server like Tomcat with both WARs deployed. > # Using a script: > ## {{GET}} the {{ping.xhtml}} endpoint to cause the app server to initialize. > ## {{GET}} the {{hello.xhtml}} endpoint to obtain the view state and session > id. > ## Use the view state and session id to {{POST}} a name to the > {{hello.xhtml}} form. > ## Repeat the {{GET}} and {{POST}} 5 times in rapid succession with different > sessions. > Here's an example {{bash}} script which uses {{curl}} to execute the above > steps: > {code:sh} >
[jira] [Commented] (TRINIDAD-2567) Trinidad secret generation is not thread-safe
[ https://issues.apache.org/jira/browse/TRINIDAD-2567?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17283356#comment-17283356 ] Kyle Stiemann commented on TRINIDAD-2567: - Thanks [~tandraschko], I'm not super worried about this getting fixed as the workaround was trivial for me. I really just wanted to document the issue so that if I ever run into it again (or if someone else does), the problem (and workaround) is in google. > Trinidad secret generation is not thread-safe > - > > Key: TRINIDAD-2567 > URL: https://issues.apache.org/jira/browse/TRINIDAD-2567 > Project: MyFaces Trinidad > Issue Type: Bug > Components: Components, Facelets, Infrastructure, Plugins >Affects Versions: 2.2.1-core >Reporter: Kyle Stiemann >Priority: Minor > > Sending multiple requests in rapid succession to a Trinidad application that > has just started will cause multiple different secret keys to be generated. > If multiple {{POST}} s are sent, all but 1 will fail with a > {{ViewExpiredException}}. Trinidad generates the secret keys in > {{StateUtils}} somewhat like this: > {code} > private static SecretKey getSecret(ExternalContext ctx) { > SecretKey secretKey = (SecretKey) > ctx.getApplicationMap().get(INIT_SECRET_KEY_CACHE); > if (secretKey == null) { > secretKey = > createSecretKey(KeyGenerator.getInstance(getAlgorithm(ctx)).generateKey().getEncoded()); > ctx.getApplicationMap().put(INIT_SECRET_KEY_CACHE, secretKey); > } > return secretKey; > } > {code} > {{FormRenderer}} calls {{ViewHandler.writeState()}} which calls the > {{StateUtils.getSecret()}} method on each request. If more than 1 request > calls {{getSecret()}} before the secret key is set in > {{INIT_SECRET_KEY_CACHE}}, each call to {{getSecret()}} has the chance to see > a {{null}} value for {{INIT_SECRET_KEY_CACHE}}, generate a new secret key, > and replace any existing secret in {{INIT_SECRET_KEY_CACHE}}. Any view state > that was generated using the discarded secrets will be unusable and cause a > {{ViewExpiredException}}. > h2. Workarounds > The simplest workaround is to set values for the secret keys as > {{init-param}} s: > https://cwiki.apache.org/confluence/display/MYFACES2/Secure+Your+Application. > For example, in the {{web.xml}} (*note that the provided values are examples > and should not be used in a production application*): > {code:xml} > > org.apache.myfaces.SECRET > > VEVTVF9LRVk= > > > org.apache.myfaces.MAC_SECRET > > VFJJTklEQURfVEVTVF9NQUNfU0VDUkVU > > {code} > h2. Potential Fixes > # Save 1 generated key in the application scope using either > {{Map.putIfAbsent()}} or some other kind of synchronization. Use only the key > from the application scope to generate the {{SecretKey}} object. Even if > secret object caching is disabled, only 1 key would be used to generate the > secret object, so the application would still function. > # Use {{Map.putIfAbsent()}} to ensure only 1 secret is ever cached in the > application. If secret caching is disabled, the application would still not > function (which is the same as the existing behavior). > h2. Steps to Reproduce: > # Create 1 WAR with a simple {{ping.xhtml}} endpoint: > {code:xml} >xmlns:h="http://java.sun.com/jsf/html; > xmlns="http://www.w3.org/1999/xhtml;> > > > pong > > > {code} > # Create another Trinidad WAR with the following view and bean: > *{{hello.xhtml}}:* > {code:xml} > >xmlns:tr="http://myfaces.apache.org/trinidad; > title="hello"> > > required="true" value="#{helloBean.name}" /> > > > > > {code} > *{{HelloBean.java}}:* > {code:java} > @ManagedBean > @RequestScoped > public final class HelloBean { > private String name; > public String getName() { > return name; > } > public void setName(String name) { > this.name = name; > } > } > {code} > # Start up an app server like Tomcat with both WARs deployed. > # Using a script: > ## {{GET}} the {{ping.xhtml}} endpoint to cause the app server to initialize. > ## {{GET}} the {{hello.xhtml}} endpoint to obtain the view state and session > id. > ## Use the view state and session id to {{POST}} a name to the > {{hello.xhtml}} form. > ## Repeat the {{GET}} and {{POST}} 5 times in rapid succession with different > sessions. > Here's an example {{bash}} script which uses {{curl}} to execute the above > steps: > {code:sh} > #!/bin/bash > sendPost() { > ENCODED_VIEW_STATE="$(curl -s --cookie-jar /tmp/cookie-jar-$1 --cookie > /tmp/cookie-jar-$1 \ > 'http://localhost:8080/trinidad-2.2/faces/hello.xhtml' | \ > tr -d '\n' | sed > 's/.*name="javax.faces.ViewState".*value="\([^"][^"]*\)".*/\1/' | \ > sed -e 's|/|\%2F|g' -e 's/+/%2B/g' -e 's/=/%3D/g')" > curl
[jira] [Commented] (TRINIDAD-2567) Trinidad secret generation is not thread-safe
[ https://issues.apache.org/jira/browse/TRINIDAD-2567?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17283183#comment-17283183 ] Kyle Stiemann commented on TRINIDAD-2567: - This bug is particularly nasty when testing a Trinidad application since tests often send multiple requests rapidly or in parallel. Worse yet, if you attempt to debug the test or the Trinidad application, you will likely slow down the requests enough that the first request will cause the key to be generated and cached before any other request is sent/received. So the issue effectively does not show up when debugging. Similarly, if you run a single test, you will not see the issue as the key will be generated and cached correctly. > Trinidad secret generation is not thread-safe > - > > Key: TRINIDAD-2567 > URL: https://issues.apache.org/jira/browse/TRINIDAD-2567 > Project: MyFaces Trinidad > Issue Type: Bug > Components: Components, Facelets, Infrastructure, Plugins >Affects Versions: 2.2.1-core >Reporter: Kyle Stiemann >Priority: Minor > > Sending multiple requests in rapid succession to a Trinidad application that > has just started will cause multiple different secret keys to be generated. > If multiple {{POST}} s are sent, all but 1 will fail with a > {{ViewExpiredException}}. Trinidad generates the secret keys in > {{StateUtils}} somewhat like this: > {code} > private static SecretKey getSecret(ExternalContext ctx) { > SecretKey secretKey = (SecretKey) > ctx.getApplicationMap().get(INIT_SECRET_KEY_CACHE); > if (secretKey == null) { > secretKey = > createSecretKey(KeyGenerator.getInstance(getAlgorithm(ctx)).generateKey().getEncoded()); > ctx.getApplicationMap().put(INIT_SECRET_KEY_CACHE, secretKey); > } > return secretKey; > } > {code} > {{FormRenderer}} calls {{ViewHandler.writeState()}} which calls the > {{StateUtils.getSecret()}} method on each request. If more than 1 request > calls {{getSecret()}} before the secret key is set in > {{INIT_SECRET_KEY_CACHE}}, each call to {{getSecret()}} has the chance to see > a {{null}} value for {{INIT_SECRET_KEY_CACHE}}, generate a new secret key, > and replace any existing secret in {{INIT_SECRET_KEY_CACHE}}. Any view state > that was generated using the discarded secrets will be unusable and cause a > {{ViewExpiredException}}. > h2. Workarounds > The simplest workaround is to set values for the secret keys as > {{init-param}} s: > https://cwiki.apache.org/confluence/display/MYFACES2/Secure+Your+Application. > For example, in the {{web.xml}} (*note that the provided values are examples > and should not be used in a production application*): > {code:xml} > > org.apache.myfaces.SECRET > > VEVTVF9LRVk= > > > org.apache.myfaces.MAC_SECRET > > VFJJTklEQURfVEVTVF9NQUNfU0VDUkVU > > {code} > h2. Potential Fixes > # Save 1 generated key in the application scope using either > {{Map.putIfAbsent()}} or some other kind of synchronization. Use only the key > from the application scope to generate the {{SecretKey}} object. Even if > secret object caching is disabled, only 1 key would be used to generate the > secret object, so the application would still function. > # Use {{Map.putIfAbsent()}} to ensure only 1 secret is ever cached in the > application. If secret caching is disabled, the application would still not > function (which is the same as the existing behavior). > h2. Steps to Reproduce: > # Create 1 WAR with a simple {{ping.xhtml}} endpoint: > {code:xml} >xmlns:h="http://java.sun.com/jsf/html; > xmlns="http://www.w3.org/1999/xhtml;> > > > pong > > > {code} > # Create another Trinidad WAR with the following view and bean: > *{{hello.xhtml}}:* > {code:xml} > >xmlns:tr="http://myfaces.apache.org/trinidad; > title="hello"> > > required="true" value="#{helloBean.name}" /> > > > > > {code} > *{{HelloBean.java}}:* > {code:java} > @ManagedBean > @RequestScoped > public final class HelloBean { > private String name; > public String getName() { > return name; > } > public void setName(String name) { > this.name = name; > } > } > {code} > # Start up an app server like Tomcat with both WARs deployed. > # Using a script: > ## {{GET}} the {{ping.xhtml}} endpoint to cause the app server to initialize. > ## {{GET}} the {{hello.xhtml}} endpoint to obtain the view state and session > id. > ## Use the view state and session id to {{POST}} a name to the > {{hello.xhtml}} form. > ## Repeat the {{GET}} and {{POST}} 5 times in rapid succession with different > sessions. > Here's an example {{bash}} script which uses {{curl}} to execute the above > steps: > {code:sh} > #!/bin/bash > sendPost() { > ENCODED_VIEW_STATE="$(curl -s --cookie-jar
[jira] [Created] (TRINIDAD-2567) Trinidad secret generation is not thread-safe
Kyle Stiemann created TRINIDAD-2567: --- Summary: Trinidad secret generation is not thread-safe Key: TRINIDAD-2567 URL: https://issues.apache.org/jira/browse/TRINIDAD-2567 Project: MyFaces Trinidad Issue Type: Bug Components: Components, Facelets, Infrastructure, Plugins Affects Versions: 2.2.1-core Reporter: Kyle Stiemann Sending multiple requests in rapid succession to a Trinidad application that has just started will cause multiple secret keys to be generated. If multiple {{POST}} s are sent, all but 1 will fail with a {{ViewExpiredException}}. Trinidad generates the secret keys in {{StateUtils}} somewhat like this: {code} private static SecretKey getSecret(ExternalContext ctx) { SecretKey secretKey = (SecretKey) ctx.getApplicationMap().get(INIT_SECRET_KEY_CACHE); if (secretKey == null) { secretKey = createSecretKey(KeyGenerator.getInstance(getAlgorithm(ctx)).generateKey().getEncoded()); ctx.getApplicationMap().put(INIT_SECRET_KEY_CACHE, secretKey); } return secretKey; } {code} {{FormRenderer}} calls {{ViewHandler.writeState()}} which calls the {{StateUtils.getSecret()}} method on each request. If more than 1 request calls {{getSecret()}} before the secret is set in {{INIT_SECRET_KEY_CACHE}}, each call to {{getSecret()}} has the chance to see a {{null}} value for {{INIT_SECRET_KEY_CACHE}}, generate a new secret, and replace any existing secret. Any view state that was generated using the discarded secrets will be unusable and cause a {{ViewExpiredException}}. h2. Workarounds The simplest workaround is to set values for the secrets as {{init-param}} s: https://cwiki.apache.org/confluence/display/MYFACES2/Secure+Your+Application. For example, in the {{web.xml}} (*note that the provided values are examples and should not be used in a production application*): {code:xml} org.apache.myfaces.SECRET VEVTVF9LRVk= org.apache.myfaces.MAC_SECRET VFJJTklEQURfVEVTVF9NQUNfU0VDUkVU {code} h2. Steps to Reproduce: # Create 1 WAR with a simple {{ping.xhtml}} endpoint: {code:xml} http://java.sun.com/jsf/html; xmlns="http://www.w3.org/1999/xhtml;> pong {code} # Create anther Trinidad WAR with the following view and bean: *{{hello.xhtml}}:* {code:xml} http://myfaces.apache.org/trinidad; title="hello"> {code} *{{HelloBean.java}}:* {code:java} @ManagedBean @RequestScoped public final class HelloBean { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } {code} # Start up an app server like Tomcat with both WARs deployed. # Using a script: ## {{GET}} the {{ping.xhtml}} endpoint to cause the app server to initialize. ## {{GET}} the {{hello.xhtml}} endpoint to obtain the view state and session id. ## Use the view state and session id to {{POST}} a name to the {{hello.xhtml}} form. ## Repeat the {{GET}} and {{POST}} 5 times in rapid succession with different sessions. Here's an example {{bash}} script which uses {{curl}} to execute the above steps: {code:sh} #!/bin/bash sendPost() { ENCODED_VIEW_STATE="$(curl -s --cookie-jar /tmp/cookie-jar-$1 --cookie /tmp/cookie-jar-$1 \ 'http://localhost:8080/trinidad-2.2/faces/hello.xhtml' | \ tr -d '\n' | sed 's/.*name="javax.faces.ViewState".*value="\([^"][^"]*\)".*/\1/' | \ sed -e 's|/|\%2F|g' -e 's/+/%2B/g' -e 's/=/%3D/g')" curl --cookie-jar /tmp/cookie-jar-$1 --cookie /tmp/cookie-jar-$1 \ -d "javax.faces.ViewState=$ENCODED_VIEW_STATE=form=submitName=Test" \ -X POST 'http://localhost:8080/trinidad-2.2/faces/hello.xhtml' } rm /tmp/cookie-jar*; until curl -s 'http://localhost:8080/other-app/ping.xhtml'; do :; done && for i in {1..5}; do sendPost $i & done {code} h3. Result: If the bug still exists, 4 of the 5 {{POST}} s will fail with a {{ViewExpiredException}}: {code:html} HTTP Status 500 – Internal Server Error body { font-family: Tahoma, Arial, sans-serif; } h1, h2, h3, b { color: white; background-color: #525D76; } h1 { font-size: 22px; } h2 { font-size: 16px; } h3 { font-size: 14px; } p { font-size: 12px; } a { color: black; } .line { height: 1px; background-color: #525D76; border: none; } HTTP Status 500 – Internal Server Error Type Exception Report Message viewId:hello.xhtml - View hello.xhtml could not be restored. Description The server encountered an unexpected condition that prevented it from fulfilling the request. Exception javax.servlet.ServletException: viewId:hello.xhtml - View hello.xhtml could not be restored. javax.faces.webapp.FacesServlet.service(FacesServlet.java:671)
[jira] [Commented] (MYFACES-4214) The wrong content type of "text/html" is set for Ajax responses
[ https://issues.apache.org/jira/browse/MYFACES-4214?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16459122#comment-16459122 ] Kyle Stiemann commented on MYFACES-4214: [~tandraschko], we ended up fixing this in the bridge since it's not really a bug in the JSF implementations (since the requirements are only for the Portlet Spec). I can't provide a patch for this any time soon, so feel free to either close this as "Won't Fix" or leave the issue open in hopes that I'll be able to provide a patch in the future. > The wrong content type of "text/html" is set for Ajax responses > --- > > Key: MYFACES-4214 > URL: https://issues.apache.org/jira/browse/MYFACES-4214 > Project: MyFaces Core > Issue Type: Improvement > Components: General, Portlet_Support >Affects Versions: 2.2.12, 2.3.1 >Reporter: Kyle Stiemann >Assignee: Thomas Andraschko >Priority: Minor > > h2. Steps to reproduce: > # Clone the > [wrong-content-type-ajax-excecute-all-reproducer|https://github.com/stiemannkj1/wrong-content-type-ajax-excecute-all-reproducer] > project: > {code} > git clone > https://github.com/stiemannkj1/wrong-content-type-ajax-excecute-all-reproducer.git > {code} > # Build the project: > {code} > cd wrong-content-type-ajax-excecute-all-reproducer && mvn clean package -P > myfaces > {code} > # Deploy the project to Tomcat: > {code} > cp target/*.war > $TOMCAT_HOME/webapps/wrong-content-type-ajax-excecute-all-reproducer.war > {code} > # Navigate to the deployed webapp at > [http://localhost:8080/wrong-content-type-ajax-excecute-all-reproducer/|http://localhost:8080/wrong-content-type-ajax-excecute-all-reproducer/]. > # Note that the _External Context Calls:_ show that > \{{setResponseContentType("text/html")}} was correctly called before the > first call to \{{getResponseOutputWriter()}}. > # Click the _Execute (default) Ajax Request_ button. > # Note the _External Context Calls:_. > # Click the _Execute @all Ajax Request_ button. > If the bug still exists, the _External Context Calls:_ will show that > \{{setResponseContentType("text/html")}} was *incorrectly* called before the > first call to \{{getResponseOutputWriter()}} during Ajax requests. > If the bug is fixed, the _External Context Calls:_ will show that > \{{setResponseContentType("text/xml")}} was called immediately before the > first call to \{{getResponseOutputWriter()}}. > h2. Additional Information: > This issue does not affect Servlets but it does affect portlets which do not > allow changing the content type after the first call to > {{ExternalContext.getResponseOutputWriter()}} (Portlet Spec 3.0 Section > _15.5.1 Content Type_): > {quote} > The {{setContentType}} method must be called before the {{getWriter}} or > {{getPortletOutputStream}} methods. Otherwise, the method will have no effect. > {quote} -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Commented] (MYFACES-4214) The wrong content type of "text/html" is set for Ajax requests
[ https://issues.apache.org/jira/browse/MYFACES-4214?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16419295#comment-16419295 ] Kyle Stiemann commented on MYFACES-4214: A similar bug exists in Mojarra but only for {{execute="@all"}} Ajax requests/responses: https://github.com/javaserverfaces/mojarra/issues/4358. > The wrong content type of "text/html" is set for Ajax requests > -- > > Key: MYFACES-4214 > URL: https://issues.apache.org/jira/browse/MYFACES-4214 > Project: MyFaces Core > Issue Type: Bug > Components: General, Portlet_Support >Affects Versions: 2.2.12, 2.3.0 >Reporter: Kyle Stiemann >Priority: Minor > > h2. Steps to reproduce: > # Clone the > [wrong-content-type-ajax-excecute-all-reproducer|https://github.com/stiemannkj1/wrong-content-type-ajax-excecute-all-reproducer] > project: > {code} > git clone > https://github.com/stiemannkj1/wrong-content-type-ajax-excecute-all-reproducer.git > {code} > # Build the project: > {code} > cd wrong-content-type-ajax-excecute-all-reproducer && mvn clean package -P > myfaces > {code} > # Deploy the project to Tomcat: > {code} > cp target/*.war > $TOMCAT_HOME/webapps/wrong-content-type-ajax-excecute-all-reproducer.war > {code} > # Navigate to the deployed webapp at > [http://localhost:8080/wrong-content-type-ajax-excecute-all-reproducer/|http://localhost:8080/wrong-content-type-ajax-excecute-all-reproducer/]. > # Note that the _External Context Calls:_ show that > \{{setResponseContentType("text/html")}} was correctly called before the > first call to \{{getResponseOutputWriter()}}. > # Click the _Execute (default) Ajax Request_ button. > # Note the _External Context Calls:_. > # Click the _Execute @all Ajax Request_ button. > If the bug still exists, the _External Context Calls:_ will show that > \{{setResponseContentType("text/html")}} was *incorrectly* called before the > first call to getResponseOutputWriter()` during Ajax requests. > If the bug is fixed, the _External Context Calls:_ will show that > \{{setResponseContentType("text/xml")}} was called immediately before the > first call to \{{getResponseOutputWriter()}}. > h2. Additional Information: > The Servlet 3.1 Specification states (in section _5.5 Internationalization_): > {quote} > The \{{setCharacterEncoding}}, \{{setContentType}}, and \{{setLocale}} > methods can be called repeatedly to change the character encoding. Calls made > after the servlet response’s \{{getWriter}} method has been called or after > the response is committed have no effect on the character encoding. > {quote} > Therefore, before the first call to > \{{externalContext.getResponseOutputWriter()}}, > \{{externalContext.setResponseContentType()}} must be called with the correct > content type. > Although this bug does not seem to break anything, that's likely because > servlet implementations do not perfectly implement the requirements of the > servlet spec. This does cause issues in Servlet and Portlet Containers (such > as Liferay) that correctly implement their respective specs. -- This message was sent by Atlassian JIRA (v7.6.3#76005)
[jira] [Created] (MYFACES-4214) The wrong content type of "text/html" is set for Ajax requests
Kyle Stiemann created MYFACES-4214: -- Summary: The wrong content type of "text/html" is set for Ajax requests Key: MYFACES-4214 URL: https://issues.apache.org/jira/browse/MYFACES-4214 Project: MyFaces Core Issue Type: Bug Components: General, Portlet_Support Affects Versions: 2.3.0, 2.2.12 Reporter: Kyle Stiemann h2. Steps to reproduce: # Clone the [wrong-content-type-ajax-excecute-all-reproducer|https://github.com/stiemannkj1/wrong-content-type-ajax-excecute-all-reproducer] project: {code} git clone https://github.com/stiemannkj1/wrong-content-type-ajax-excecute-all-reproducer.git {code} # Build the project: {code} cd wrong-content-type-ajax-excecute-all-reproducer && mvn clean package -P myfaces {code} # Deploy the project to Tomcat: {code} cp target/*.war $TOMCAT_HOME/webapps/wrong-content-type-ajax-excecute-all-reproducer.war {code} # Navigate to the deployed webapp at [http://localhost:8080/wrong-content-type-ajax-excecute-all-reproducer/|http://localhost:8080/wrong-content-type-ajax-excecute-all-reproducer/]. # Note that the _External Context Calls:_ show that \{{setResponseContentType("text/html")}} was correctly called before the first call to \{{getResponseOutputWriter()}}. # Click the _Execute (default) Ajax Request_ button. # Note the _External Context Calls:_. # Click the _Execute @all Ajax Request_ button. If the bug still exists, the _External Context Calls:_ will show that \{{setResponseContentType("text/html")}} was *incorrectly* called before the first call to getResponseOutputWriter()` during Ajax requests. If the bug is fixed, the _External Context Calls:_ will show that \{{setResponseContentType("text/xml")}} was called immediately before the first call to \{{getResponseOutputWriter()}}. h2. Additional Information: The Servlet 3.1 Specification states (in section _5.5 Internationalization_): {quote} The \{{setCharacterEncoding}}, \{{setContentType}}, and \{{setLocale}} methods can be called repeatedly to change the character encoding. Calls made after the servlet response’s \{{getWriter}} method has been called or after the response is committed have no effect on the character encoding. {quote} Therefore, before the first call to \{{externalContext.getResponseOutputWriter()}}, \{{externalContext.setResponseContentType()}} must be called with the correct content type. Although this bug does not seem to break anything, that's likely because servlet implementations do not perfectly implement the requirements of the servlet spec. This does cause issues in Servlet and Portlet Containers (such as Liferay) that correctly implement the respective specs. -- This message was sent by Atlassian JIRA (v7.6.3#76005)