Problems with Media Temple and post requests

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:

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!

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

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 :slight_smile:

  • Trevor

Hey~

On Apr 4, 2007, at 5:07 PM, Trevor T. 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 Z.
– Lead Rails Evangelist
[email protected]
– Engine Y., Serious Rails Hosting
– (866) 518-YARD (9273)

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

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

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

Another possible fix is to add the following to controllers/
application.rb:

def default_url_options(options)
{ :trailing_slash => true }
end

  • Trevor

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

Alexey V. 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.

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:

… 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 :slight_smile:

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

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

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 T. <ruby-forum-incom…@andreas-

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

I am very satisfied with Unlimitedgb.com’s service. It have very fast
moving servers…It doen’t take much much time to upgrade my ads into it.