dynamic grails.serverURL

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

dynamic grails.serverURL

ideasculptor
I have always run enterprise apps under a variety of hostnames, often attaching functionality to the specific hostname that a request arrives at.  For example, I may use a url of the form http://<customer>.portal.mycompany.com/ in order to preserve infomation about the currently selected customer in the URL in a manner that doesn't require that I play games with path manipulation on every request in order to keep it there.  It requires storing cookies on a wildcard domain of *.portal.mycompany.com so that a user's auth credentials and session state aren't lost when the hostname changes, but that is easy enough to arrange.  

However, I now have a grails app in which I simply want to be able to install it under a variety of names without regenerating a war every time.  It seems crazy to me that I have to hardcode the serverURL into the war or a properties file when all of the information about the current hostname and servlet context are available in the request.  It completely eliminates my ability to access a single app from a variety of hostnames or to install the same war under a variety of names without externalizing the config.  Is there not some way to tell grails to compute the serverURL based on the hostname in the request and the servlet context?  Heck, it sort of looks like I even have to hardcode the protocol to either http or https, which is simply not acceptable since I have some content that requires https and other content which does not - and spring-security is perfectly happy to switch channels as needed, but that won't work if grails generates urls that don't use the correct protocol.

Is there a way to dynamically generate serverURL? Is there a good reason for requiring a hardcoded value at all, actually?  Isn't the whole point of including the wealth of information available in an HttpServletRequest precisely so that such things can be computed dynamically so that variables like hostnames, port numbers, protocols, and servlet contexts don't have to be hardcoded into applications?
Reply | Threaded
Open this post in threaded view
|

Re: dynamic grails.serverURL

bksaville
Try just not setting the grails.serverURL property.  Does that do what you are looking for?

-Brian

On Tue, Apr 10, 2012 at 11:47 AM, Samuel Gendler <[hidden email]> wrote:
I have always run enterprise apps under a variety of hostnames, often attaching functionality to the specific hostname that a request arrives at.  For example, I may use a url of the form http://<customer>.portal.mycompany.com/ in order to preserve infomation about the currently selected customer in the URL in a manner that doesn't require that I play games with path manipulation on every request in order to keep it there.  It requires storing cookies on a wildcard domain of *.portal.mycompany.com so that a user's auth credentials and session state aren't lost when the hostname changes, but that is easy enough to arrange.  

However, I now have a grails app in which I simply want to be able to install it under a variety of names without regenerating a war every time.  It seems crazy to me that I have to hardcode the serverURL into the war or a properties file when all of the information about the current hostname and servlet context are available in the request.  It completely eliminates my ability to access a single app from a variety of hostnames or to install the same war under a variety of names without externalizing the config.  Is there not some way to tell grails to compute the serverURL based on the hostname in the request and the servlet context?  Heck, it sort of looks like I even have to hardcode the protocol to either http or https, which is simply not acceptable since I have some content that requires https and other content which does not - and spring-security is perfectly happy to switch channels as needed, but that won't work if grails generates urls that don't use the correct protocol.

Is there a way to dynamically generate serverURL? Is there a good reason for requiring a hardcoded value at all, actually?  Isn't the whole point of including the wealth of information available in an HttpServletRequest precisely so that such things can be computed dynamically so that variables like hostnames, port numbers, protocols, and servlet contexts don't have to be hardcoded into applications?

Reply | Threaded
Open this post in threaded view
|

Re: dynamic grails.serverURL

ideasculptor


On Tue, Apr 10, 2012 at 11:01 AM, Brian Saville <[hidden email]> wrote:
Try just not setting the grails.serverURL property.  Does that do what you are looking for?

That was the first thing I tried.  To be honest, this just looks like a straight up bug in grails.  The controller in question is as basic as it gets:

def index = { // TODO put any pre-logout code here 

    log.debug("redirecting to ${SpringSecurityUtils.securityConfig.logout.filterProcessesUrl}") 

    redirect uri: SpringSecurityUtils.securityConfig.logout.filterProcessesUrl // '/j_spring_security_logout' 

}


Yet the redirect that is generated looks like this: https://webapp1.prod.ecorithm.com/grails_portal/j_spring_security_logout

However, that hostname is NOT the configured serverURL nor is it the hostname on the request (https://demo.ecorithm.com/logout).  It is the internal hostname configured on the host, coupled with the value of app.name in application.properties as servlet context.  In reality, the war file is running as ROOT.war, so the servlet context should be '/' and the hostname should be demo.ecorithm.com if it uses the incoming hostname.  The configured grails.serverURL is also as follows:

    demo {
      grails.serverURL = "https://demo.ecorithm.com/"
    }

So the fact that grails is generating a redirect using the internal hostname of the host rather than the request hostname or the serverURL hostname has got to be a big fat bug.  A critical, showstopping bug since anyone running on a host with an external hostname different from what is configured on the host will have a broken application if they use the dynamic redirect() method in their controllers - and that is absolutely anyone running behind a load balancer.

It is possible that the intent is for serverURL to be dynamically generated from the request if there is no configured value, but that is not what is happening.

--sam


-Brian


On Tue, Apr 10, 2012 at 11:47 AM, Samuel Gendler <[hidden email]> wrote:
I have always run enterprise apps under a variety of hostnames, often attaching functionality to the specific hostname that a request arrives at.  For example, I may use a url of the form http://<customer>.portal.mycompany.com/ in order to preserve infomation about the currently selected customer in the URL in a manner that doesn't require that I play games with path manipulation on every request in order to keep it there.  It requires storing cookies on a wildcard domain of *.portal.mycompany.com so that a user's auth credentials and session state aren't lost when the hostname changes, but that is easy enough to arrange.  

However, I now have a grails app in which I simply want to be able to install it under a variety of names without regenerating a war every time.  It seems crazy to me that I have to hardcode the serverURL into the war or a properties file when all of the information about the current hostname and servlet context are available in the request.  It completely eliminates my ability to access a single app from a variety of hostnames or to install the same war under a variety of names without externalizing the config.  Is there not some way to tell grails to compute the serverURL based on the hostname in the request and the servlet context?  Heck, it sort of looks like I even have to hardcode the protocol to either http or https, which is simply not acceptable since I have some content that requires https and other content which does not - and spring-security is perfectly happy to switch channels as needed, but that won't work if grails generates urls that don't use the correct protocol.

Is there a way to dynamically generate serverURL? Is there a good reason for requiring a hardcoded value at all, actually?  Isn't the whole point of including the wealth of information available in an HttpServletRequest precisely so that such things can be computed dynamically so that variables like hostnames, port numbers, protocols, and servlet contexts don't have to be hardcoded into applications?


Reply | Threaded
Open this post in threaded view
|

Re: dynamic grails.serverURL

rlovtangen
grails.serverURL bugged me as well in Grails 1.3.x where the code generated by 'grails create-app' had grails.serverURL set to some default value, so you need to commented it out.
But in Grails 2.0 it is commented out by default. Which to me sound like it is not strictly needed, and that's a good thing.
I have simply left it commented out, and haven't run into any problems yet.

Our two use cases for not having a hard coded value is:

1) We have two environments; staging and production, running on two different tomcats at the same time with Apache in front. When staging becomes production, we simply switch the production vhost to point to the other tomcat and vice versa.

2) Having multiple URL's to one application, with some differences in functionallity.


Ronny


On Apr 10, 2012, at 8:18 PM, Samuel Gendler wrote:



On Tue, Apr 10, 2012 at 11:01 AM, Brian Saville <[hidden email]> wrote:
Try just not setting the grails.serverURL property.  Does that do what you are looking for?

That was the first thing I tried.  To be honest, this just looks like a straight up bug in grails.  The controller in question is as basic as it gets:

def index = { // TODO put any pre-logout code here 
    log.debug("redirecting to ${SpringSecurityUtils.securityConfig.logout.filterProcessesUrl}") 
    redirect uri: SpringSecurityUtils.securityConfig.logout.filterProcessesUrl // '/j_spring_security_logout' 
}

Yet the redirect that is generated looks like this: https://webapp1.prod.ecorithm.com/grails_portal/j_spring_security_logout

However, that hostname is NOT the configured serverURL nor is it the hostname on the request (https://demo.ecorithm.com/logout).  It is the internal hostname configured on the host, coupled with the value of app.name in application.properties as servlet context.  In reality, the war file is running as ROOT.war, so the servlet context should be '/' and the hostname should be demo.ecorithm.com if it uses the incoming hostname.  The configured grails.serverURL is also as follows:

    demo {
      grails.serverURL = "https://demo.ecorithm.com/"
    }

So the fact that grails is generating a redirect using the internal hostname of the host rather than the request hostname or the serverURL hostname has got to be a big fat bug.  A critical, showstopping bug since anyone running on a host with an external hostname different from what is configured on the host will have a broken application if they use the dynamic redirect() method in their controllers - and that is absolutely anyone running behind a load balancer.

It is possible that the intent is for serverURL to be dynamically generated from the request if there is no configured value, but that is not what is happening.

--sam


-Brian


On Tue, Apr 10, 2012 at 11:47 AM, Samuel Gendler <[hidden email]> wrote:
I have always run enterprise apps under a variety of hostnames, often attaching functionality to the specific hostname that a request arrives at.  For example, I may use a url of the form http://<customer>.portal.mycompany.com/ in order to preserve infomation about the currently selected customer in the URL in a manner that doesn't require that I play games with path manipulation on every request in order to keep it there.  It requires storing cookies on a wildcard domain of *.portal.mycompany.com so that a user's auth credentials and session state aren't lost when the hostname changes, but that is easy enough to arrange.  

However, I now have a grails app in which I simply want to be able to install it under a variety of names without regenerating a war every time.  It seems crazy to me that I have to hardcode the serverURL into the war or a properties file when all of the information about the current hostname and servlet context are available in the request.  It completely eliminates my ability to access a single app from a variety of hostnames or to install the same war under a variety of names without externalizing the config.  Is there not some way to tell grails to compute the serverURL based on the hostname in the request and the servlet context?  Heck, it sort of looks like I even have to hardcode the protocol to either http or https, which is simply not acceptable since I have some content that requires https and other content which does not - and spring-security is perfectly happy to switch channels as needed, but that won't work if grails generates urls that don't use the correct protocol.

Is there a way to dynamically generate serverURL? Is there a good reason for requiring a hardcoded value at all, actually?  Isn't the whole point of including the wealth of information available in an HttpServletRequest precisely so that such things can be computed dynamically so that variables like hostnames, port numbers, protocols, and servlet contexts don't have to be hardcoded into applications?



Reply | Threaded
Open this post in threaded view
|

Re: dynamic grails.serverURL

ideasculptor


On Tue, Apr 10, 2012 at 12:08 PM, Ronny Løvtangen <[hidden email]> wrote:
grails.serverURL bugged me as well in Grails 1.3.x where the code generated by 'grails create-app' had grails.serverURL set to some default value, so you need to commented it out.
But in Grails 2.0 it is commented out by default. Which to me sound like it is not strictly needed, and that's a good thing.
I have simply left it commented out, and haven't run into any problems yet.

Our two use cases for not having a hard coded value is:

1) We have two environments; staging and production, running on two different tomcats at the same time with Apache in front. When staging becomes production, we simply switch the production vhost to point to the other tomcat and vice versa.

2) Having multiple URL's to one application, with some differences in functionallity.


Yeah, I was under the impression tyhat that was how it SHOULD work but wasn't how it was working, but it turns out that the script that deploys the built war file got broken such that the updated code wasn't getting deployed, so my test without a grails.serverURL never actually got run and I was just repeatedly running the same old broken code with a hardcoded grails.serverURL (we are running a grails2 app that was upgraded from 1.3.x).  The whole thing was a false alarm.  When I dropped the serverURL and actually ran the correct war file, it works correctly.

--sam