However, I think there might be a place that this change missed, or I'm doing something wrong. Overall, looking at the code I'm not sure why it doesn't work. The problem is when using RedirectResponse -- it seems like RedirectResponses are not subject to the new exclusion check, and I can't figure out where in the Lift code they're being rewritten.
I have this code in Boot:
LiftRules.excludePathFromContextPathRewriting.default.set(() => path => {
...
path.startsWith("/login") ||
...
})
And then elsewhere, I have a SiteMap LocParam called NeedAnyRole (here, along with the supporting functions):
val unauthorized: Loc.FailMsg = () => RedirectResponse("/login/errorauth.jsp")
/** Wrap the given If failure message with logging statements if debug logging is enabled */
def maybeWrapForLogging(reason: String, fail: Loc.FailMsg): Loc.FailMsg = logger.isDebugEnabled match {
case true => () => { logger.debug("Failing SiteMap check (" + reason + ") for " + SPx.loggedInUser.pxuser.map(_.getUsername).openOr("<anonymous user>")); fail() }
case false => fail
}
/** Test for a role and if it is not found bounces out with a Unauthorized (well, redirect to /login/errorauth.jsp) */
object NeedAnyRole {
def apply(fail: Loc.FailMsg, roleNames: String*): If = If(() => roleNames.findIndexOf(roleName => SPx.hasRole(roleName)) >= 0, maybeWrapForLogging("NeedAnyRole(" + roleNames + ")", fail))
def apply(roleNames: String*): If = apply(unauthorized, roleNames: _*)
}
When I fail this LocParam, here is what gets sent back to the browser (as seen by tcpdump)
HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
P3P: policyref="/w3c/p3p.xml", CP="CAO DSP COR CURa ADMa DEVa CONo OUR IND PHY ONL UNI PUR FIN COM NAV DEM STA"
Location: /emailwizard/login/errorauth.jsp
X-Lift-Version: 1.1-SNAPSHOT
Content-Type: text/html;charset=utf-8
Content-Length: 1
Date: Wed, 14 Oct 2009 15:33:36.GMT
The Location: field should be /login/errorauth.jsp since I have it excluded from context rewriting. This works with normal links and other things in HTML, just this redirect isn't working as expected.
I did try to do a quick spelunk in the lift code, and it looks like it should be generating a correct InMemoryResponse with the location header set to whatever I pass in, however there's a comment there that indicates something later will touch it up:
case class RedirectResponse(uri: String, cookies: HTTPCookie*) extends LiftResponse {
// The Location URI is not resolved here, instead it is resolved with context path prior of sending the actual response
def toResponse = InMemoryResponse(Array(0), List("Location" -> uri), cookies toList, 302)
}
Any ideas on where the problem is?
-Ross