}
@Override
public void forward(final ServletRequest request, final ServletResponse response) throws ServletException, IOException {
final ServletRequestContext servletRequestContext = SecurityActions.requireCurrentServletRequestContext();
ThreadSetupAction.Handle handle = null;
ServletContextImpl oldServletContext = null;
HttpSessionImpl oldSession = null;
if (servletRequestContext.getCurrentServletContext() != this.servletContext) {
//cross context request, we need to run the thread setup actions
oldServletContext = servletRequestContext.getCurrentServletContext();
oldSession = servletRequestContext.getSession();
servletRequestContext.setSession(null);
handle = this.servletContext.getDeployment().getThreadSetupAction().setup(servletRequestContext.getExchange());
servletRequestContext.setCurrentServletContext(this.servletContext);
}
try {
final HttpServletRequestImpl requestImpl = servletRequestContext.getOriginalRequest();
final HttpServletResponseImpl responseImpl = servletRequestContext.getOriginalResponse();
if (!servletContext.getDeployment().getDeploymentInfo().isAllowNonStandardWrappers()) {
if (servletRequestContext.getOriginalRequest() != request) {
if (!(request instanceof ServletRequestWrapper)) {
throw UndertowServletMessages.MESSAGES.requestWasNotOriginalOrWrapper(request);
}
}
if (servletRequestContext.getOriginalResponse() != response) {
if (!(response instanceof ServletResponseWrapper)) {
throw UndertowServletMessages.MESSAGES.responseWasNotOriginalOrWrapper(response);
}
}
}
response.resetBuffer();
final ServletRequest oldRequest = servletRequestContext.getServletRequest();
final ServletResponse oldResponse = servletRequestContext.getServletResponse();
Map<String, Deque<String>> queryParameters = requestImpl.getQueryParameters();
if (!named) {
//only update if this is the first forward
if (request.getAttribute(FORWARD_REQUEST_URI) == null) {
requestImpl.setAttribute(FORWARD_REQUEST_URI, requestImpl.getRequestURI());
requestImpl.setAttribute(FORWARD_CONTEXT_PATH, requestImpl.getContextPath());
requestImpl.setAttribute(FORWARD_SERVLET_PATH, requestImpl.getServletPath());
requestImpl.setAttribute(FORWARD_PATH_INFO, requestImpl.getPathInfo());
requestImpl.setAttribute(FORWARD_QUERY_STRING, requestImpl.getQueryString());
}
int qsPos = path.indexOf("?");
String newServletPath = path;
if (qsPos != -1) {
String newQueryString = newServletPath.substring(qsPos + 1);
newServletPath = newServletPath.substring(0, qsPos);
Map<String, Deque<String>> newQueryParameters = QueryParameterUtils.mergeQueryParametersWithNewQueryString(queryParameters, newQueryString);
requestImpl.getExchange().setQueryString(newQueryString);
requestImpl.setQueryParameters(newQueryParameters);
}
String newRequestUri = servletContext.getContextPath() + newServletPath;
requestImpl.getExchange().setRelativePath(newServletPath);
requestImpl.getExchange().setRequestPath(newRequestUri);
requestImpl.getExchange().setRequestURI(newRequestUri);
requestImpl.getExchange().getAttachment(ServletRequestContext.ATTACHMENT_KEY).setServletPathMatch(pathMatch);
requestImpl.setServletContext(servletContext);
responseImpl.setServletContext(servletContext);
}
try {
try {
servletRequestContext.setServletRequest(request);
servletRequestContext.setServletResponse(response);
if (named) {
servletContext.getDeployment().getServletDispatcher().dispatchToServlet(requestImpl.getExchange(), chain, DispatcherType.FORWARD);
} else {
servletContext.getDeployment().getServletDispatcher().dispatchToPath(requestImpl.getExchange(), pathMatch, DispatcherType.FORWARD);
}
if (!request.isAsyncStarted()) {
if (response instanceof HttpServletResponseImpl) {
responseImpl.closeStreamAndWriter();
} else {
try {
final PrintWriter writer = response.getWriter();
writer.flush();
writer.close();
} catch (IllegalStateException e) {
final ServletOutputStream outputStream = response.getOutputStream();
outputStream.flush();
outputStream.close();
}
}
}
} catch (ServletException e) {
throw e;
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
} finally {
servletRequestContext.setServletRequest(oldRequest);
servletRequestContext.setServletResponse(oldResponse);
}
} finally {
if (handle != null) {
servletRequestContext.setSession(oldSession);
servletRequestContext.setCurrentServletContext(oldServletContext);
handle.tearDown();
}
}
}