Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import javax.faces.event.PreRenderViewEvent;
import javax.faces.view.ViewDeclarationLanguage;

import org.apache.myfaces.shared.config.MyfacesConfig;

/**
* Implements the render response phase (JSF Spec 2.2.6)
*
Expand All @@ -44,6 +46,7 @@ class RenderResponseExecutor extends PhaseExecutor
{

private static final Logger log = Logger.getLogger(RenderResponseExecutor.class.getName());
private MyfacesConfig _myfacesConfig;

public boolean execute(FacesContext facesContext)
{
Expand All @@ -61,7 +64,9 @@ public boolean execute(FacesContext facesContext)
{
throw new ViewNotFoundException("A view is required to execute "+facesContext.getCurrentPhaseId());
}


forceSessionCreation(facesContext);

try
{
// do-while, because the view might change in PreRenderViewEvent-listeners
Expand Down Expand Up @@ -154,4 +159,35 @@ public PhaseId getPhase()
{
return PhaseId.RENDER_RESPONSE;
}

/**
* Create a session if the ALWAYS_FORCE_SESSION_CREATION param is set to true, or if the
* current view is not transient and server side state saving is in use.
*
* Note: if the current view is transient or client side state saving is in use, it is
* not technically correct to create a session here, since a session should not be
* required for those cases and creating one will cause undesirable memory usage.
* However, if we do not create a session before rendering begins and view or session
* scope beans are created later on, then the response might be committed before those
* scopes have a chance to create a session and so the session cookie will not be set.
* See MYFACES-4309
*
* @param FacesContext
*/
private void forceSessionCreation(FacesContext context)
{
if (context.getExternalContext().getSession(false) == null)
{
if (_myfacesConfig == null)
{
_myfacesConfig = MyfacesConfig.getCurrentInstance(context.getExternalContext());
}
if (_myfacesConfig.isAlwaysForceSessionCreation()
|| (!context.getViewRoot().isTransient()
&& !context.getApplication().getStateManager().isSavingStateInClient(context)))
{
context.getExternalContext().getSession(true);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,19 @@ public class MyfacesConfig
"org.apache.myfaces.STRICT_JSF_2_ORIGIN_HEADER_APP_PATH";
public final static boolean STRICT_JSF_2_ORIGIN_HEADER_APP_PATH_DEFAULT = false;

/**
* Defines if a session should be created (if one does not exist) before response rendering.
* When this parameter is set to true, a session will be created even when client side state
* saving or stateless views are used, which can lead to unintended resource consumption.
* When this parameter is set to false, a session will only be created before response
* rendering if a view is not transient and server side state saving is in use.
*/
@JSFWebConfigParam(since="2.2.13", defaultValue="true", expectedValues="true,false")
protected static final String ALWAYS_FORCE_SESSION_CREATION =
"org.apache.myfaces.ALWAYS_FORCE_SESSION_CREATION";
public final static boolean ALWAYS_FORCE_SESSION_CREATION_DEFAULT = true;


private boolean _prettyHtml;
private boolean _detectJavascript;
private boolean _allowJavascript;
Expand Down Expand Up @@ -598,6 +611,7 @@ public class MyfacesConfig
private Integer _numberOfFacesFlowClientWindowIdsInSession;
private boolean _supportEL3ImportHandler;
private boolean _strictJsf2OriginHeaderAppPath;
private boolean _alwaysForceSessionCreation;

private static final boolean TOMAHAWK_AVAILABLE;
private static final boolean MYFACES_IMPL_AVAILABLE;
Expand Down Expand Up @@ -712,6 +726,7 @@ public MyfacesConfig()
INIT_PARAM_NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION_DEFAULT)+1);
setSupportEL3ImportHandler(SUPPORT_EL_3_IMPORT_HANDLER_DEFAULT);
setStrictJsf2OriginHeaderAppPath(STRICT_JSF_2_ORIGIN_HEADER_APP_PATH_DEFAULT);
setAlwaysForceSessionCreation(ALWAYS_FORCE_SESSION_CREATION_DEFAULT);
}

private static MyfacesConfig createAndInitializeMyFacesConfig(ExternalContext extCtx)
Expand Down Expand Up @@ -915,6 +930,10 @@ else if (refreshTransientBuildOnPSS.equalsIgnoreCase("true") ||
myfacesConfig.setStrictJsf2OriginHeaderAppPath(WebConfigParamUtils.getBooleanInitParameter(extCtx,
STRICT_JSF_2_ORIGIN_HEADER_APP_PATH,
STRICT_JSF_2_ORIGIN_HEADER_APP_PATH_DEFAULT));

myfacesConfig.setAlwaysForceSessionCreation(WebConfigParamUtils.getBooleanInitParameter(extCtx,
ALWAYS_FORCE_SESSION_CREATION,
ALWAYS_FORCE_SESSION_CREATION_DEFAULT));

if (TOMAHAWK_AVAILABLE)
{
Expand Down Expand Up @@ -1593,4 +1612,17 @@ public void setStrictJsf2OriginHeaderAppPath(boolean strictJsf2OriginHeaderAppPa
{
this._strictJsf2OriginHeaderAppPath = strictJsf2OriginHeaderAppPath;
}

public boolean isAlwaysForceSessionCreation()
{
return _alwaysForceSessionCreation;
}

/**
* @param alwaysForceSessionCreation the _alwaysForceSessionCreation to set
*/
public void setAlwaysForceSessionCreation(boolean alwaysForceSessionCreation)
{
this._alwaysForceSessionCreation = alwaysForceSessionCreation;
}
}