Why does grails URL params decoding behave differently on server vs. local - url

Let's say I have the following entry in my grails URLMappings.groovy:
"/actionName/param1"(controller:'myController', action:'myAction')
When I call an URL where param1 includes + as a special character, the URL is encoded correctly to /actionName/my%2Bparam for example, both in my local and in my server environment.
In my local environment - also using "prod" as the environment parameter - this is correctly resolved to my+param in the controller. However in my "real" production environment (Amazon Web Service EC2 instance), the URL is resolved to "my param" which is wrong.
I have no idea what the reason for this could be. Both environments use TomCat, and as stated above I'm even using the prod environment settings in my local environment so it can't be a differing configuration between development and production.
Does anybody have an idea where I could dig deeper to identify the problem?

Is the EC2 instance running Apache in front of Tomcat? I've had issues before with params being decoded twice, once by Apache and then again by Tomcat. From memory, I think I adjusted the configuration of the ProxyPass directive in Apache to correct it.
EDIT:
I found the following instructions I'd left with the source code for my app :)
Apache httpd.conf additions
AllowEncodedSlashes On
ProxyTimeout 3600
We also upgraded apache 2.2.12+ to fix HEAD > GET rewrite bug using a startup shell script.
I also added 'nocanon' option to ProxyPass directive to stop auto decoding by mod_proxy in /etc/httpd/conf.d/cluster.conf
I think I had to do this on the server as you can't modify this using the GUI. I also have a note that says it causes they query string to be encoded. Perhaps I had to add an extra decode in my app to handle this (sorry can't remember for sure!)
Tomcat startup parameters
-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
-Dorg.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH=true
I think this was to get tomcat to handle slashes correctly
cheers
Lee

That's a known bug that has been introduced in Groovy 1.3.4 or few build versions before. It has been fixed in current version 1.3.5.
this is correctly resolved to my+param
in the controller
No, the expected resolution is "my param" (with a space).
As that works at the Amazon host, you'd upgrade Grails to 1.3.5, locally.

Related

Capistrano and XSendFile configuration

I am trying to configure Rails production server with Apache 2.2, Passenger 4.0.59 and XSendFile 0.12. Application is deployed via Capistrano.
Deployed application produces (maybe large) PDF to #{Rails.root}/tmp and serves this file using send_file.
The problem is that Capistrano uses symlinks to point to currently deployed version of application. XSendFile on the other hand dereferences symlinks and refuses to serve a file if its real location is outside document root even if it is allowed by XSendFilePath. Apache's error.log states:
(20023)The given path was above the root path: xsendfile: unable to find file: /resolved/path/to/file.pdf
Everything works well when I set PassengerAppRoot and XSendFilePath to the real location of current version of application, without symlinks on the path. But it's OK until next deploy, which requires apache reconfiguration. Not very useful.
How should I configure Capistrano deploy and XSendFile parameters to make it work together?
I tried solutions with ln -nFs described in Capistrano & X-Sendfile and in mod_xsendfile with symbolic links but none works.
I finally managed to make it work. A few tips for the ones who will have problems with XSendFile
I set XSendFilePath to user's $HOME, there are no symlinks on the path to $HOME, so it works. I can accept this from functional and security point of view, but it is obviously a workaround.
Be aware that XSendFilePath is sensitive to paths containing multiple slashes /like//this. I am using apache macros and while concatenatingXSendFilePath parameter from a few macro parameters I put some obsolete slashes. This caused XSendFile to refuse to send files.
Good luck!

How to configure Rails app for deployment to Tomcat

I have a Rails app that I package as a war file for deploying to Tomcat using Warbler. And it works, but the problem is I don't know how to configure the runtime properties like secret_key_base. I use the standard setup of using secrets.yml, with production variables coming from environment variables. But I don't know how to set the variables while still keeping them out of source control.
Ideally I'd still like to be able to deploy the war file automatically, by just dropping it into the webapps/ directory, but I suppose I could edit the server config file? Or is there a better way of handling this?
either do it the same way as you would in a Rails server ... let it read from ENV (of course you will need to make sure Tomcat has the environment variable set).
alternatively you can set it in a web.xml if you're packaging and than do a $servlet_context.getAttribute('foo') in secrets.yml ... or read it from a file location that only the server's tomcat username can access etc.
sky is the limit here - you basically need to decide what fits your deployments the best.

Rails application issue after deployment - 404 error

I'm new to RoR.
I was able to install Rails and host it in Webrick (Sample App with "Welcome" controller) in my windows.
Now i have a Unix Weblogic Server along with a dedicated domian.
After exporting the .WAR file using Warbler, i accessed the Oracle Admin Console from where i deployed the .WAR file in the dedicated domain. I did all this for the Sample app with only the Welcome controller in it.
But even after deploying the WAR file, on accessing the Domain along with the Port Number (:9002) i ended up with 404 file not found error On looking at the server logs,there wasn't any records relating to any error. The Application must have been deployed properly. I assume that i must have missed out on some basic configurations in the routes.rb or similar files before deploying. Can anyone Guess what are all the possibilities and if possible can anyone help me by pointing to any tuts that cover the Steps to be carried out for configuration before deployment. do i need to install both JRuby and Rails inside the server before depolyment?
I can't really guess with Eror 404 only.
You can try mapping your rails app rack config to a different base_uri.
All you need to do is wrap the existing 'run' command in a map block
try doing this in your rails 'config.ru' file:
map '/mydepartment' do
run Myapp::Application
end
Now when you 'rails server' the app should be at localhost:3000/mydepartment .
Not sure if this will give you the desired outcome, but worth a try.
One more thing you also add this to your config/environments/production.rb and config/environments/development.rb (if on production mode):
config.action_controller.asset_path = proc { |path| "/abc#{path}" }
otherwise when you call your helpers such as stylesheet_link_tag in your views, they will generate links without the "/abc".
Also, find some guides you may refer for good support.
JRubyOnRailsOnBEAWeblogic.
Use JRuby with JMX for Oracle WebLogic Server 11g
Let me know if it is not resolved.

Running jRuby + Rails inside of Tomcat

I am currently using a platform where multiple web applications must interact with each other in a frameset. This set of web applications and the frameset is hosted on Tomcat.
Now the application we're working on is developed with jRuby and Rails. Is there anyway I can run my development environment inside of Tomcat similar to just running the jRuby -S Rails Server command so I can effectively debug?
The only way I've found is to generate a war using warble and then modifying the exploded war which seems really hacky. Any thoughts?
EDIT: I think my best bet is to generate a war, gut it, use symbolic links and figure out what gems / libs I need to copy from the war generation process. It's the best way I can think of.
one option to explore: deploy a little servlet to Tomcat which returns
HTTP/1.1 301 Moved Permanently
Location: http://localhost:3000
So far the best solution I have found is to setup a reverse proxy with Tomcat and point it to the Rails development server. This allows it to run, as expected on the client side, while still giving me debug control.
When I get a chance to do some more testing I'll edit my answer to include additional information.
go to the webapps folder in tomcat where you have deployed the war file, then find the web.xml file inside the expanded war file
The path to this file is generally /var/lib/tomcat7/webapps/your-project-here/WEB-INF/web.xml and inside this file you should find the
Changing this is one way to go about.
<context-param>
<param-name>rails.env</param-name>
<param-value>production</param-value>
</context-param>

jRuby deployment into a subfolder in Tomcat

While developing a jRuby application using webbrick as the webserver, all my code is written with http://localhost:3000 as the root.
When deploying to Tomcat, I create a WAR file and it creates a subfolder under the webapps/ folder: localhost:8080/project_name/
This causes a load of problems with my code. Is there anything I can do in my ruby routes.rb file to deal with this?
Should I resort to using some sort of virtual host in Tomcat?
Although this question is quite old, we ran into a similar problem with a current project of ours. The project is done with JRuby on Rails, using Tomcat 6.x (7.0.26 in development for testing purposes), needing multiple deployments of the same application on the same servlet container, having individual server names. It took me quite some time to find a good enough solution and I like to share it with you.
Continue reading, if root context is no option for you (as cosmikduster described it above). If it is, use it.
TL;DR
Use virtual hosts for each app provided by Tomcat to give yourself root context for individual apps deployed on the Tomcat servlet container. The explanation provided below is based on this and is just an illustrative example with a step by step solution attached.
The problem
The problem arises when deploying a *.war file to Tomcat, as per default, the deployed app, let's call it awesome_app_uno for now, will live under http://localhost:8080/awesome_app_uno. This is all fine and dandy but can cause problems with the internal path generation of rails, which by default will now use /awesome_app_uno for every path generated.
Explanation & initial setup
Now, JRuby Rack, which is the rack implementation for JRuby is kind enough to include a feature that automatically sets the relative_url_root for you, I quote from the README:
The Rails controller setting ActionController::Base.relative_url_root is set for you automatically according to the context root where your webapp is deployed.
Normally, I would cheer - but in the real world, we'd probably do not want something like this, as we'll have something like a proxy to get ourselves some nice domainname, e.g.
http://awesomeappuno.com/
And now we're screwed. If we take a naive solution for this, we'd probably end up using an Apache (or an nginx, whatever you like) to function as a proxy. We'll want something like
http://awesomeappuno.com/ -> http://localhost:8080/awesome_app_uno
Just for the fun of it, lets look at the configuration for an apache config file:
<VirtualHost *:80>
ServerName awesomeappuno.com
ErrorLog /var/log/apache2/awesomeappuno_error.log
LogLevel warn
CustomLog /var/log/apache2/awesomeappuno_access.log combined
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://localhost:8080/awesome_app_uno
ProxyPassReverse / http://localhost:8080/awesome_app_uno
</VirtualHost>
Kindly stolen from here.
The madness
With that being your configuration, you can now visit http://awesomeappuno.com.
This is where you'll notice, that despite now having a clean root without prefixes, Rails will still generate paths with the /aweseome_app_uno prefix, i.e.
http://awesomeappuno.com/awesome_app_uno/the/path/you/wanted
This is generally undesirable. While some of you could propably live with this, I couldn't. Moreover, there's awesome_app_dos coming up on the horizon which needs to be deployed on the same Tomcat instance, needing it's own domain name http://awesomeappdos.com, along with the two ugly cousins awesome_staging and awesome_integration behind it. The gist is, if you're forced to use the same Tomcat container for all these apps, giving on app root context is not really an option.
You can try some solutions like writing custom initializers, resetting the ENV hash, which gets initially filled by the jruby-rack (see comments and answers above). You might find yourself rewriting the paths manually or using absolute urls. Or you create hacks for a single environment. Or you could try to use rewrites. Or mod_subsitute. You could even try using multiple tomcat instances running everything under root context.
Don't do that.
Please.
Virtual Hosts to the rescue
While reading up on the issue (and trying everything described in the last paragraph), I stumpled on an entry in the ruby forum.
You can create virtual hosts with Tomcat, providing a root context for each app. To get more in depth knowledge, you can start here or here. In short, suppose your Tomcat (7.x) is located under /usr/local/tomcat, this would be the quick and dirty version:
Create a virtual host
The host will have it's appBase within the tomcat installation for this. If this isn't your stale, change it.
(cd /usr/local/tomcat/libexec)
I am using an installation via homebrew here, I am on a mac under OSX 10.7.4 - however with slight alterations this should work on a standard Debian as well.
Open up conf/server.xml and within the engine tag create another host:
<Host name="awesome_app_uno" alias="awesomeappuno" appBase="awesome_app/uno" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Context path="" docBase="ROOT"></Context>
</Host>
After that, create a file called conf/Catalina/awesome_app_uno/ROOT.xml. These are the contents:
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="${catalina.base}/awesome_app/uno/ROOT.war">
</Context>
Afterwards, place the awesomeappuno.war as /usr/local/tomcat/libexec/awesome_app/uno/ROOT.war and restart Tomcat. You can check the virtual host via http://localhost:8080/host-manager/html.
You should be able to visit http://awesome_app_uno:8080 and find your app there. Paths should now be correct, however, port 8080 isn't that user friendly. With slight changes to the previously shown apache config, we can also get a nice name for this:
<VirtualHost *:80>
ServerName awesomeappuno.com
ErrorLog /var/log/apache2/awesomeappuno_error.log
LogLevel warn
CustomLog /var/log/apache2/awesomeappuno_access.log combined
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://awesome_app_uno:8080/
ProxyPassReverse / http://awesome_app_uno:8080/
</VirtualHost>
Reload your apache and you should now have no further problems with pathing, routing, because everything now happens under the root context of the tomcat virtual host.
Rinse and repeat for additional apps on the same tomcat instance.
The end
Hope i could help you with this.
lg,
flo
There is code in JRuby-Rack to deal with this. Depending on the version of Tomcat and/or Rails, it may not be detecting the extra context path correctly.
The environment variable that is supposed to take effect is called ENV['RAILS_RELATIVE_URL_ROOT']. You might print out the value of that expression during boot time and see whether it's getting set when you run in Tomcat.
The code in question is here:
https://github.com/nicksieger/jruby-rack/blob/master/src/main/ruby/jruby/rack/rails.rb#L32-38
The versions of Tomcat, Rails and JRuby-Rack you're using would help diagnose the problem further.
Your app should almost never care about the host/domain/port it will run under. To deploy at the relative path /, instead of /myapp, simply rename the WAR to ROOT.war instead of myapp.war when you copy it to the tomcat/webapps folder.

Resources