String launchId = request.getParameter(LaunchSession.LAUNCH_ID);
if (Util.isNullOrTrimmedBlank(launchId)) {
throw new Exception("No launch ID supplied.");
}
LaunchSession launchSession = LaunchSessionFactory.getInstance().getLaunchSession(launchId);
ReverseProxyWebForward wf = (ReverseProxyWebForward) launchSession.getResource();
/* Remove all other launch sessions for this resource, we can only ever have
* one at a time
*/
Collection<LaunchSession> sessions = LaunchSessionFactory.getInstance().getLaunchSessionsForType(launchSession.getSession(),
WebForwardPlugin.WEBFORWARD_RESOURCE_TYPE);
for (LaunchSession rs : sessions) {
if (rs != launchSession && rs.getResource() instanceof ReverseProxyWebForward && rs.getResource().getResourceId() == wf.getResourceId()) {
LaunchSessionFactory.getInstance().removeLaunchSession(rs);
}
}
if (wf.getActiveDNS() && !isValidForActiveDNS(request.getServerName()))
throw new Exception("Invalid host '" + request.getServerName() + "'; only FQDNs are valid for Active DNS forwarding");
String path;
String url = wf.getDestinationURL();
String hostField = request.getHeader("Host");
HostService hostService = hostField == null ? null : new HostService(hostField);
SessionInfo session = getSessionInfo(request);
try {
launchSession.checkAccessRights(null, session);
/*
* This requires more thought.
*
* 1. We can only have on launch session per resource
* 2. This doesn't take into account other features of reverse proxy
* (authentication, encoding, host headers etc)
*
*/
/**
* Setup other reverse proxies so they have access to each other. Only
* reverse proxies with the same policy attached will be allowed.
List resources = ResourceUtil.getGrantedResource(launchSession.getSession(), WebForwardPlugin.WEBFORWARD_RESOURCE_TYPE);
Resource resource;
for(Iterator it = resources.iterator(); it.hasNext();) {
resource = (Resource) it.next();
if(resource instanceof ReverseProxyWebForward && resource.getResourceId()!=launchSession.getResource().getResourceId()) {
if(PolicyDatabaseFactory.getInstance().isResourceAttachedToPolicy(resource, launchSession.getPolicy(), launchSession.getSession().getRealm())) {
LaunchSession ls = LaunchSessionFactory.getInstance().createLaunchSession(launchSession.getSession(), resource, launchSession.getPolicy());
ls.checkAccessRights(null, session);
}
}
}
*/
VariableReplacement r = new VariableReplacement();
r.setServletRequest(request);
r.setLaunchSession(launchSession);
url = r.replace(url);
CoreEvent evt = new ResourceAccessEvent(this,
WebForwardEventConstants.WEB_FORWARD_STARTED,
wf,
launchSession.getPolicy(),
launchSession.getSession(),
CoreEvent.STATE_SUCCESSFUL).addAttribute(WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_TYPE,
((WebForwardTypeItem) WebForwardTypes.WEB_FORWARD_TYPES.get(wf.getType())).getName())
.addAttribute(WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_URL, url);
CoreServlet.getServlet().fireCoreEvent(evt);
// Get the URL to redirect to
if (wf.getActiveDNS()) {
URL u = new URL(url);
URL adu;
if (Property.getPropertyInt(new SystemConfigKey("webforward.activeDNSFormat")) == 1) {
adu = new URL("https", launchSession.getId() + "." + hostService.getHost(), hostService.getPort() == 0 ? -1
: hostService.getPort(), u.getFile());
} else {
int idx = hostService.getHost().indexOf('.');
adu = new URL("https",
launchSession.getId() + "." + hostService.getHost().substring(idx + 1),
hostService.getPort() == 0 ? -1 : hostService.getPort(),
u.getFile());
}
path = adu.toExternalForm();
} else if (wf.getHostHeader() != null && !wf.getHostHeader().equals("")) {
URL u = new URL(url);
URL adu = new URL("https", wf.getHostHeader(), hostService.getPort() == 0 ? -1 : hostService.getPort(), u.getFile());
path = adu.toExternalForm();
if (adu.getQuery() == null || adu.getQuery().equals("")) {
path += "?" + LaunchSession.LAUNCH_ID + "=" + launchSession.getId();
} else {
path += "&" + LaunchSession.LAUNCH_ID + "=" + launchSession.getId();
}
/**
* Why do we need to use a JSP redirect? Because the new host
* will be created in a new session and we need the JSESSIONID
* which is only set once the first response has been returned
* to the browser. This redirect allows the browser to load a
* page on the new host and set the session cookie before an
* automatic redirect takes the user to the correct reverse
* proxy page.
*/
URL adu2 = new URL("https",
/**
* LDP Not sure why this was using hostService.getHost because my comment above
* clearly indicates that we have to redirect from the new host
*/
wf.getHostHeader(),
hostService.getPort() == 0 ? -1 : hostService.getPort(),
"/reverseProxyRedirect.jsp?redirectURL=" + Util.urlEncode(path));
return new ActionForward(adu2.toExternalForm(), true);
} else {
URL u = new URL(url);
path = u.getPath();
if (u.getQuery() == null || u.getQuery().equals("")) {
path += "?" + LaunchSession.LONG_LAUNCH_ID + "=" + launchSession.getId();
} else {
path += "?" + u.getQuery() + "&" + LaunchSession.LONG_LAUNCH_ID + "=" + launchSession.getId();
}
URL redir = new URL("https",
hostService.getHost(),
hostService.getPort() == 0 ? -1 : hostService.getPort(),
path);
path = redir.toExternalForm();
}
} catch (NoPermissionException npe) {
CoreEvent evt = new ResourceAccessEvent(this,
WebForwardEventConstants.WEB_FORWARD_STARTED,
wf,
launchSession.getPolicy(),
launchSession.getSession(),
npe).addAttribute(WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_TYPE,
((WebForwardTypeItem) WebForwardTypes.WEB_FORWARD_TYPES.get(wf.getType())).getName())
.addAttribute(WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_URL, url);
CoreServlet.getServlet().fireCoreEvent(evt);