[jira] [Comment Edited] (TRINIDAD-2567) Trinidad secret generation is not thread-safe

2021-02-11 Thread Kyle Stiemann (Jira)


[ 
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

2021-02-11 Thread Kyle Stiemann (Jira)


[ 
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

2021-02-11 Thread Kyle Stiemann (Jira)


[ 
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

2021-02-10 Thread Kyle Stiemann (Jira)
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

2018-04-30 Thread Kyle Stiemann (JIRA)

[ 
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

2018-03-29 Thread Kyle Stiemann (JIRA)

[ 
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

2018-03-29 Thread Kyle Stiemann (JIRA)
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)