Same problem with g:createLinkTo (ApplicationTagLib):
[...]
writer << grailsAttributes.getApplicationUri(request)
[...]
and with controller's redirect method RedirectDynamicMethod.invoke:
if(uri != null) {
actualUri = attrs.getApplicationUri(request) + uri.toString();
}
[...]
Concerning a solution, wouldn't it be better to separate contextPath inclusion from use of attribute absolute?
For example, using a grails app on a tomcat behind an apache with mod_ajp &mod_proxy, we don't want the contextPath to be added at all, because multiple virtualhosts can redirect to the same tomcat context, making absolute attribute unusable in this case.
In a simpler case, we may want to use relative paths without having to show the contextPath at apache's level.
So it could be a good idea to add a grails.config.includeContextPath?
environments {
production { grails.includeContextPath = false }
}
Investigating this, it seems this code in createLink in ApplicatonTagLib is the problem:
def mapping = urlMappings.getReverseMapping(controller,action,params) url = mapping.createURL(controller, action, params, request.characterEncoding, frag) if (attrs.base) { out << attrs.remove('base') } else { handleAbsolute(attrs) }The mapping.createURL call does not tell the url creator to exclude the servlet context path, which it needs to do if handleAbsolute or "base" attributes take effect.
so this code needs to run before, and we need a createURL variant that takes a "includeContextPath" boolean parameter
def mapping = urlMappings.getReverseMapping(controller,action,params) url = mapping.createURL(controller, action, params, request.characterEncoding, frag) if (attrs.base) { out << attrs.remove('base') } else { handleAbsolute(attrs) }