Grails

Using absolute="true" with g:link / g:createLink always includes context path

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 1.0.1
  • Fix Version/s: 1.0.5, 1.1.1
  • Component/s: None
  • Labels:
    None

Description

<g:link> et al with absolute="true" should take the URL stem from serverURL and not include the current contextpath as part of the URL it produces.

Issue Links

Activity

Hide
Marc Palmer added a comment -

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

Show
Marc Palmer added a comment - 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
Hide
Loïc Elineau added a comment -

Same problem with g:createLinkTo (ApplicationTagLib):

[...]
writer << grailsAttributes.getApplicationUri(request)
[...]

and with controller's redirect method RedirectDynamicMethod.invoke:

// line 120
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 }
}
Show
Loïc Elineau added a comment - Same problem with g:createLinkTo (ApplicationTagLib):
[...]
writer << grailsAttributes.getApplicationUri(request)
[...]
and with controller's redirect method RedirectDynamicMethod.invoke:
// line 120
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 }
}
Hide
Graeme Rocher added a comment -

I'm not sure I agree with this issue, if we changed this behaviour then someone else would raise another JIRA saying it should include the context path. You could argue both ways. Moving to 1.0.4 for future debate

Show
Graeme Rocher added a comment - I'm not sure I agree with this issue, if we changed this behaviour then someone else would raise another JIRA saying it should include the context path. You could argue both ways. Moving to 1.0.4 for future debate
Hide
Dmitriy Kopylenko added a comment -

I absolutely would like that behavior to be added. We (Michael Kimsal mostly) are trying to set up grailscrowd behind Apache with multiple vhosts and the whole thing is 'broken' as URLMapping (link taglib, createLink, etc.) appends the 'grailscrowd' context path to all the URIs it produces. Not good. So, I really wish there was some kind of a solution for different real world deployment scenarios.

Show
Dmitriy Kopylenko added a comment - I absolutely would like that behavior to be added. We (Michael Kimsal mostly) are trying to set up grailscrowd behind Apache with multiple vhosts and the whole thing is 'broken' as URLMapping (link taglib, createLink, etc.) appends the 'grailscrowd' context path to all the URIs it produces. Not good. So, I really wish there was some kind of a solution for different real world deployment scenarios.
Hide
Peter Ledbrook added a comment -

Does the solution to GRAILS-3368 resolve anyone's problem? With that change you can specify base as an empty string and rely on URL rewriting.

Show
Peter Ledbrook added a comment - Does the solution to GRAILS-3368 resolve anyone's problem? With that change you can specify base as an empty string and rely on URL rewriting.
Hide
Marc Palmer added a comment - - edited

Guys, the real problem I believe is that the code should NEVER add the context path, but currently the behavior in DEV relies on this to make functioning URLs.

The fix is:

1) Change tag to never add context - grails.serverURL is meant to be the FULL url always - otherwise it is useless as a concept for reuse elsewhere eg in emails. The whole point is to remove the dependency on context path

2) Change the default serverURL that the tag uses for localhost dev access to include the application context - at the point of using that default value - not in the taglib.

I've spent a lot of time with the problem, and that is the solution I'm quite sure. I implemented it badly in the first place vis the localhost URL not including the context path by default

Show
Marc Palmer added a comment - - edited Guys, the real problem I believe is that the code should NEVER add the context path, but currently the behavior in DEV relies on this to make functioning URLs. The fix is: 1) Change tag to never add context - grails.serverURL is meant to be the FULL url always - otherwise it is useless as a concept for reuse elsewhere eg in emails. The whole point is to remove the dependency on context path 2) Change the default serverURL that the tag uses for localhost dev access to include the application context - at the point of using that default value - not in the taglib. I've spent a lot of time with the problem, and that is the solution I'm quite sure. I implemented it badly in the first place vis the localhost URL not including the context path by default
Hide
Graeme Rocher added a comment -

Bulk closing bunch of resolved issues

Show
Graeme Rocher added a comment - Bulk closing bunch of resolved issues

People

Vote (5)
Watch (8)

Dates

  • Created:
    Updated:
    Resolved: