I'm not certain, but I think I'm having a problem with my app receiving post requests in production. I've got two distinct problems that only manifest themselves in production on a Media Temple Grid Server plan. I'm using Capistrano to deploy and I'm running Rails 1.2.3. The first problem is that I've got a form that auto-submits when a select menu is changed. The form submits, but doesn't appear to submit a post request. I've got an if statement checking if request.post? that returns false, and I don't see anything indicating a post request in the production.log file. It works perfectly on my development machine, though. The second problem is that my create actions aren't being invoked in certain cases where I'm using attachment_fu. It's a similar problem, where post requests don't seem to be processed correctly in production. Basically, I submit a form using RESTful conventions and the index action is invoked instead of the create action. I'm wondering if these two problems are related in that they both involve improper handling of post request in production. I posted some additional detail here as well: http://www.railsweenie.com/forums/6/topics/1378 If somebody has experienced this, or thinks they know what's going on, I'd appreciate any help you can provide. I can't seem to track down the problem, and I'm completely out of ideas. Thanks much!
on 03.04.2007 12:54
on 05.04.2007 02:08
I've gotten a response from Media Temple on this, although I'm still not sure how I'll resolve the issue. I'm sure I'm not the first or last person who'll try to do what I'm doing, so I'm hopeful that I'll find a solution. Here's what they said: --- The problem you are running into is not caused by code or configuration, but coincidence. Your controller is exposed as "/files" and you have a directory in your public folder called files. When your form is created, the action is "/files". When this post request hits the Grid, Apache sees that request (http://app.com/files) and that there is a directory there, and so appends a slash (http:// app.com/files/) and redirects the browser to the new URL. This is standard Apache behavior since most requests for a directory name are usually for the directory's contents rather than the directory itself. Since Apache does the redirect, the post turns into a get before your Rails application even has a chance to see it. To test this out, rename your files directory to any other name and you will see that the post request starts working again. And, seeing that you are also having issues with the /headers and / avatars and that there are matching directories in your public directory, the same issue is probably happening there. ---- If anyone has an idea of how to work around this behavior (changing the Apache config?) please let me know. Otherwise, I'll update this post when I figure out a solution. - Trevor
on 05.04.2007 02:21
Hey~ On Apr 4, 2007, at 5:07 PM, Trevor Turk wrote: > and you have a directory in your public folder called files. > the post request starts working again. > > - Trevor > Sounds like they don't have apache configured right for serving rails apps. Having directories in your public/ dir named after controllers is how rails page caching works and is a fundemantal part of how the rewrites are setup to serve rails apps. You should grab the apache2.2 config from mongrel.rubyforge.org or from the railsmachine gem and show it to them. Cheers -- Ezra Zygmuntowicz -- Lead Rails Evangelist -- ez@engineyard.com -- Engine Yard, Serious Rails Hosting -- (866) 518-YARD (9273)
on 05.04.2007 05:03
Thanks so much for your reply, Ezra. I'll get in touch with them right away with that info. Not to sound too silly, but I was staring at http://www.engineyard.com/ the other day wishing I could afford to sign up! I figured you guys would have all of this stuff sorted already. Maybe someday soon, though :) - Trevor
on 05.04.2007 17:38
Hi all. I have a Capistrano recipe that is deploying great to my test
server and 3 production servers. On the test server I have mySQL and
Rails
running together. Deploy_with_migrations works great on this machine.
My
produciton servers are Rails app only and I have a dedicated mySQL
server.
Deploy works great without a :db value but if I add the :db to the list
then
the deployment chokles while trying to write the app files to that
server.
I didn't even have ruby on rails installed on that machine. So I tried
to
create a new task with only the :db value and run that task with a
simple
migrate just to get my database tables in place (the database itself is
already created) and it still chokes. Task "test" works like a dream,
"production1" fails, "production2" and "production3 " work. I had all
the
production machines in one task at first as :web, :web2 and :web3 but it
didn't seem to like that. In any case, seperating them confirmed that
access and connectivity are working. Here's my capistrano recipe, which
can
probably use a ton of improvement anyway:
require "mongrel_cluster/recipes"
set :application, "bankspower"
set :repository, "svn://172.16.1.23:48000/#{application}/trunk"
set :deploy_to, "/website/#{application}"
set :mongrel_conf, "#{current_path}/config/mongrel_cluster.yml"
set :user, "rrubio"
set :checkout, "export"
set :keep_releases, "3"
task :test do
set :rails_env, :test
role :web, "172.16.1.23"
role :app, "172.16.1.23"
role :db, "172.16.1.23", :primary => true
end
task :production1 do
set :rails_env, :production
set :mongrel_conf,
"#{current_path}/config/production/mongrel_cluster.yml"
role :web, "192.168.168.31"
role :app, "192.168.168.31"
role :db, "172.16.1.30" , :primary => true
end
task :production3 do
set :rails_env, :production
set :mongrel_conf,
"#{current_path}/config/production/mongrel_cluster.yml"
role :web, "192.168.168.33"
role :app, "192.168.168.33"
end
task :production_db, :roles => :db do
set :rails_env, :production
role :db, "172.16.1.30", :primary => true
end
Thanks for any assistance!
Raul
on 12.04.2007 04:01
I got some more responses from Media Temple on the issues I've been
having with routes and post requests not being picked up. It seems
that they're not going to be able to do anything to fix my problem,
and I'm totally lost as to how I should proceed.
In short, posting a form to something like avatars_url in an attempt
to invoke a create action will be (wrongly) redirected to the index
action if there is a public/avatars directory (or, more specifically,
a symlink in that location that points to shared/system/avatars). MT
says that Apache is picking up the request and redirecting it to the
index action before Rails sees it because of the existence of this
folder/symlink in the public directory. Apparently, this is the
intended behavior, which strikes me as odd.
I told them what Ezra said (quoted below), and here's the summary of
my conversation with them since then:
MT:
I am skeptical that this is a misconfiguration of our server. I think
it has more to do with the fact that the form is submitting to the
bare controller name (that is also a directory) and not an action in
that controller. Most Rails caching schemes involve more than just the
controller name (i.e. the name of the action called).
I also noticed in my testing that if I change the action of the form
to '/files/' rather than '/files' that the form posts correctly.
ME:
The thing is that I'm using standard Rails routes like so:
map.resources :avatars
So, my forms are like this:
<% form_for(:avatar, :url => avatars_path, :html => { :multipart =>
true }) do |f| -%>
Which means (to me, at least) that I'm doing things the "right way"
for Rails, and I shouldn't have to change way the forms are submitted.
MT:
I've done more testing and I am able to reproduce your problem on my
DV using Apache 2.0.52 and Mongrel 1.0.1. This means that it's not a
problem with the Grid and any special software we run there.
I also verified that Rails caching works (both on the Grid and my DV),
so nothing about our setup prevents caching.
Here are a couple of suggestions to solve your problem:
1. Try using a different URL to post to rather than /files. I changed
it in my tests to /files/index and the posting works.
2. Perhaps getting the proxy to happen earlier in the Apache request
processing might work around it appending the slash to the URL. This
is not possible on the Grid but may be possible on a DV.
...
They go on to suggest that I might need a greater level of
customization than they can provide on the Grid Server plan I've got
with them.
My issue still remains, though, and I'm 99% sure that I'm not doing
anything "wrong" here or anything that should require customization.
It seems to me that this is a fairly normal thing to do (wanting to
have routes and a public folder with the same name). Should I change
the url value in my form_for call? I would think that using
"avatars_path" for the url SHOULD work fine in any deployment
scenario.
I'm not sure if there is a workaround that might solve my problem
(.htaccess or something?), but it seems to me that there is something
wrong with their environment.
Any comments or suggestions would be very helpful and very much
appreciated.
Thanks,
- Trevor
on 12.04.2007 08:39
The people at Media Temple helped me find a workaround for this
problem. I've gotten everything working with this fix:
<% form_for(:avatar, :url => '/avatars/', :html => { :multipart =>
true }) do |f| -%>
... instead of:
<% form_for(:avatar, :url => avatars_path, :html => { :multipart =>
true }) do |f| -%>
The "avatars" path generates the action URL as "/avatars" without a
trailing slash. Apparently, adding this trailing slash on the URL
helps things work properly.
I'm still convinced that I shouldn't have to change the URL like this,
but I'm not sure if this is a problem with the Media Temple
configuration or something that should be fixed in Rails itself. I'm
going to submit a ticket on the Rails Trac site and continue to
investigate. If anyone has any ideas about this, I'm all ears.
- Trevor
on 12.04.2007 08:55
Another possible fix is to add the following to controllers/
application.rb:
def default_url_options(options)
{ :trailing_slash => true }
end
- Trevor
on 12.04.2007 09:29
Before you go and create that ticket, it may be a good idea to find out what your (or MT's) mod_rewrite rules look like. Otherwise, it's shooting in the dark. -- Alex
on 12.04.2007 09:31
Alexey Verkhovsky wrote: > Before you go and create that ticket, it may be a good idea to find > out what your (or MT's) mod_rewrite rules look like... You're right - I'll do that.
on 13.04.2007 04:10
I got some more replies from Media Temple on this, and it seems like there's an even easier workaround. Here's what they said: --- There are no rewrite rules that cause Apache to append a slash. After inquiring with one of our admins and a little more research, the documentation detailing this feature was found. It is at this page: http://httpd.apache.org/docs/2.0/mod/mod_dir.html And here's the good part. One of the directives on that page will solve your problem. Put this in your .htaccess file and Apache will no longer append slashes: DirectorySlash Off --- It seems as though Apache appends these slashes by default, and I'm unclear as to why the Rails-generated routes would not include this trailing slash. I realize there's a trailing_slash option in ActionController: http://api.rubyonrails.org/classes/ActionController/Base.html ... but is there a good reason why a route like "uploads_path" wouldn't generate the trailing slash? Sorry if I sound naive here, but I am :) I'd just like to help other people avoid this problem in the future, because it's taken a big chunk out of my sanity trying to figure out what's been going on. - Trevor
on 24.10.2007 01:49
Hey Trevor, Thank you so much for taking the time to post this solutions to this problem. I just ran into the same problem at MT, and the 'DirectorySlash Off' fix seem to work like a charm. The reason why Rails doesn't put a trailing slash at the end of the URL is because that compromises the concept of REST. With REST, you want your URL to as much as possible identify the exact resource you're trying to access. For example, in your case a GET request to /files should return a list files uploaded -- the meaning of the document is just more clear when the document name you're trying to retrieve is called 'files' instead of 'index'. This is a pretty big issue with Media Temple, and it doesn't sit well with me that they're pushing it aside like this. More and more of the Rail apps being built today are taking advantage of the REST capabilities that were put into Rails 1.2. Saying that this isn't their problem just shows how low of a priority Rails is to them. -- Calvin
on 24.10.2007 02:13
Calvin Yu wrote: > Saying that this isn't their > problem just shows how low of a priority Rails is to them. I agree, and that's one of the main reasons that I left for the greener pastures of Slicehost. That being said, I wonder if this isn't something that Rails might be better off including in their default apps. Perhaps it would cause some other problems I'm not aware of, though... - Trevor
on 02.03.2008 03:44
this post just helped me solve this same problem which reared its head way back in Oct 07. I was moving a site which had been running on TextDrive for 6 months over to MediaTemple's grid. The site ran fine in development mode on my machine. When I put it on MT, all my flash[] calls were not working.. and then I realized that no data was being posted either... I pulled my hair out for a day or so now and then, and finally just got back to working on it today. We'll most importantly I wanted to verify to you that all the crap about symlinks and directories being named this or that has nothing to do with the problem. It's simply MT's apache config screwing up the http post data with custom routes. The only thing unique to my app was custom routing. I added the DirectorySlash Off to my .htaccess, did a cap deploy, and voila... everything was finally back to normal. you may want to add that information to the thread for other's sake. On Oct 23 2007, 6:13 pm, Trevor Turk <ruby-forum-incom...@andreas-