Grails and Subdomains - grails

Does Grails know anything about sub-domains (i.e. subdomain.domain.com) ? I don't see it discussed in the manual. Is this purely an app server/web server issue? Can be tied into grails controllers, either statically or dynamically?

It does not matter which host is accessed for a java web application.
Supposing you have multiple clients separated on one host, e.g. customer1.yourhost.com, customer2.yourhost.com, etc. and all clients will have same functionalities.
In the simplest case I propse, that you just use write a filter, which will always put some request variable, like this:
def filters = {
all(controller:'*', action:'*') {
before = {
if (request.serverName.contains(".")) {
def clientName =
request.serverName.substring(0, request.serverName.indexOf("."))
request.currentClient = Client.findByClientName(clientName) // e.g.
}
}
}
}
Then at any place you can check request.currentClient for the current accessed subdomain.
However if it gets more complicated have a look at some multi-tenant plugins for grails.
If you want to have different functionalities for each subdomain e.g. help.yourhost.com and www.yourhost.com, I would propose that you write independent grails applications. You then setup a NGINX server to redirect those requests to the appropriate application running on your application server.

We run a few Grails apps on a single host using various sub domains. In all cases we use Apache to front the Tomcat server and use mod jk or forward proxy to handle the applications to the different Grails app. Most of it is rather straight forward, what we have not figured out is running the applications at the root level for the various domains, for instance -
http://app1.domain.com instead of http://app1.domain.com/app1

The only place I'm aware of subdomains being considered is for tenant resolution when using the multi-tenant plugin. See http://tinyurl.com/6tuxwvs.

Related

How can I use Domain-based routing?

I have a simple web server running Windows 2012 with IIS. I have half a dozen domains linked to this server that are basically not in use yet. I have a few more domains which are used but they could all have various subdomains that aren't supported by any site yet. So I have a default site in IIS set to catch all incoming requests that aren't handled by any other site on the server or any other server. And it's main purpose is to show a "Page not in use yet" message.
That's easy to set up but I want these pages to be a bit more fancy. So I want to have some kind of routing based on the domain name so example.com and sub.example.com and sub.sub.example.com would all be handled by the same view, but anotherexample.com would be handled by a different view and thirdexample.com by yet another view. And any domain that is not caught by this routing system would go to the default view.
And I wonder if there's a simple way to do this. Something like [route("example.com")] as a controller attribute which the system would recognize as the controller for a specific domain and it's subdomains. (And the URL path can be ignored.) I don't know if something like this already exists and have used Google but found nothing yet.
I can create a custom route, of course. But this tends to result in an if-then-else situation for all potential domain names. I need to know if there's a better method.
Use the URL rewrite module for IIS:
https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/using-the-url-rewrite-module

Working with dynamic sub-domains with struts2

How do I create a sub-domain on my application server/container using Struts2.
For example, if I have a user called john15 I would like to dynamically create the sub-domain: john15.abc.com, after the user has signed in to my application at abc.com.
In general you can't. There are ways to achieve this but sub-domains are controlled by the application server and so any programmatic control over them are limited by what the container/application server offers and would probably not be portable.
Another solution (which acheives the desired effect but without trying to use struts2/application server interaction) is to use struts2 to develop a custom url tag which builds your desired urls. Then using something that re-writes urls (software such as squid, and like: http://en.wikipedia.org/wiki/Proxy_server#Web_proxy_servers). You can rewrite the URL into a format which is more acceptable to struts, possibly as a url parameter, or make it appear as part of the path which can then be parsed.
If you must do this I would advise the proxy server solution. Implement urls to reach your actions following the template:
abc.com/user/additional_path_and_parameters
then use the web proxy to rewrite user.abc.com/additional_path_and_parameters into the above.
Finally in creating that magical stuts2 url tag and possibly a reimplementation of the action tag too: You'll probably want to reuse the existing tag(s) and have it implement urls for "production" and "development" modes. In development the tag would behave exactly as the existing struts2 url tag does, but during deployment mode it will write your urls as you need them. This is important because you don't want to waste time setting up a proxy on your development machines, that would be a pain.

Rails app for multiple domains

I need to create a service with the same five sites and one that will unite them, but everyone has to live on a separate domain. Maybe somehow run one instance Rails app redirect users depending on the domain? Or is it better to start on a new Rails app per instance?
Why not just set up one instance of the rails app, and configure your http server (Apache, Nginx or whatever) to listen to connections on all of those domains?
Genarally, there are two ways you can do that with one rails instance.
redirect the comming requests to diffrent uri path ('/site1', '/site2' etc) from the http server based on the domain names. I'm not a pro on setting up this. But i'm sure this is do-able.
redirect the comming requests to different path from the application controller in a before filter based on the value of request.url.host variable.
redirect_to my_site1_path if request.url.host == 'www.site1.com'
You can choose either of them, it's up to you :).

How do I serve multiple rails apps on one domain (and sub)?

This is kind of weird but I'd like to serve multiple websites on the same domain. If possible, we want to avoid subdomains to keep urls simple for our users - no need for them to know it's two separate apps. This is purely for keeping the code bases separate. Any ideas?
For example:
Rails App 1 (Refinery CMS) serves:
http://example.com/
http://example.com/about
http://example.com/pricing
Rails App 2 (our real App) serves:
http://example.com/account
http://example.com/store
http://example.com/listings
We use ruby 1.9.2, ruby on rails, refinery cms, apache and passenger.
If you're using Passenger, check out the Deploying to a sub URI portion of the manual - it's quite simple to set up an app on a sub-URI. You may need to set config.action_controller.relative_url_root in your app configuration, as well.
Edit: I misread the question; not one app per URI, but one app serving some (but not all) endpoints. This is actually moderately easy to do with some basic rewrites, as well.
Deploy your Rails app to, let's say, /railsapp (but without setting relative_url_root). Now, in .htaccess:
RewriteRule ^account/(.*)$ railsapp/account/$1 [L]
This will internally remap /account/* to /railsapp/account/*, so as long as you set up a rewrite per path your Rails app handles, it should work fine.
Subdomains make it easier (thus why most sites have shop.example.com), but you could probably use rewrite rules with name based virtual host routing. How exactly to do that I'm not sure. More of a Apache rewrite question for SuperUser.
A word of warning if you are using SSL you might have issues arise.
You could set it up to first hit one app where you expect most URLs would work and if it 404s you could instruct it to try the other app next, though this will be slower than routing per route but it will work without having to hardcode a route for every page that is created on say, Refinery CMS.
Currently I'm also working on a same kind of CMS. In my case also I need multiple sub domains, like
www.test1.mydomain.com
www.test2.mydomain.com
www.test3.mydomain.com
www.test4.mydomain.com
here is what I did
in rails 3 (if you are on rails3) you can get the sub domain by using request object. (If you are on rails 2.x you can use sub domain_fu plugin)
In my case I have used a before filter to get the sub domain, after that I load the site according to the sub domain
For development use the following public domain "lvh.me"
http://tbaggery.com/2010/03/04/smack-a-ho-st.html
this was very useful for me http://railscasts.com/episodes/221-subdomains-in-rails-3
let users have their domains forwarded to your subdomain (with masking)
ex : www.clientdomain.com --> http://client.mydomain.com
hope this helps
cheers
sameera

Account based lookup in ASP.NET

I'm looking at using ASP.NET for a new SaaS service, but for the love of me I can't seem to figure out how to do account lookups based on subdomains like most SaaS applications (e.g. 37Signals) do.
For example, if I offer yourname.mysite.com, then how would I use ASP.NET (MVC specifically) to extract the subdomain so I can load the right template (displaying your company's name and the like)? Can it be done with regular routing?
This seems to be a common thing in SaaS so there has to be an easy way to do it in ASP.NET; I know there are plugins that do it for other frameworks like Ruby on Rails.
This works for me:
//--------------------------------------------------------------------------------------------------------------------------
public string GetSubDomain()
{
string SubDomain = "";
if (Request.Url.HostNameType == UriHostNameType.Dns)
SubDomain = Regex.Replace(Request.Url.Host, "((.*)(\\..*){2})|(.*)", "$2");
if (SubDomain.Length == 0)
SubDomain = "www";
return SubDomain;
}
I'm assuming that you would like to handle multiple accounts within the same web application rather than building separate sites using the tools in IIS. In our work, we started out creating a new web site for each subdomain but have found that this approach doesn't scale well - especially when you release an update and then have to modify dozens of sites! Thus, I do recommend this approach rather than the server-oriented techniques suggested above based on several years worth of experience doing exactly what you propose.
The code above just makes sure that this is a fully formed URL (rather, say, than an IP address) and returns the subdomain. It has worked well for us in a fairly high-volume environment.
You should be able to pick this up from the ServerVariables collection, but first you need to configure IIS and DNS to work correctly. So you know 37Signals probably use Apache or another open source, unix web server. On Apache this is referred to as VirtualHosting.
To do this with IIS you would need to create a new DNS entry (create a CNAME yourname.mysite.com to application.mysite.com) for each domain that points to your application in IIS (application.mysite.com).
You then create a host header entry in the IIS application (application.mysite.com) that will accept the header yourname.mysite.com. Users will actually hit application.mysite,com but the address is the custom subdomain. You then access the ServerVariables collection to get the value to decide on how to customize the site.
Note: there are several alternative implementations you could follow depending on requirements.
Handle the host header processing at a hardware load balancer (more likely 37Signals do this, than rely on the web server), and create a custom HTTP header to pass to the web application.
Create a new web application and host header for each individual application. This is probably an inefficient implementation for a large number of users, but could offer better isolation and security for some people.
You need to configure your DNS to support wildcard subdomains. It can be done by adding an A record pointing to your IP address, like this:
* A 1.2.3.4
Once its done, whatever you type before your domain will be sent to your root domain, where you can get by splitting the HTTP_HOST server variable, like the user buggs said above:
string user = HttpContext.Request.ServerVariables["HTTP_HOST"].Split(".")
//use the user variable to query the database for specific data
PS. If you are using a shared hosting you're probably going to have to by a Unique IP addon from them, since it's mandatory for the wildcard domains to work. If you're using a dedicated hosting you already have your own IP.
The way I have done it is with HttpContext.Request.ServerVariables["HTTP_HOST"].Split(".").
Let me know if you need more help.

Resources