Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #918 (closed defect: fixed)

Opened 5 years ago

Last modified 5 years ago

Bad POST in Rails4Days.pdf examples (was Apache + Safari + AJAX == problem)

Reported by: Michael Schubert <michael@schubert.cx> Assigned to: David
Priority: high Milestone: 1.0
Component: ActionPack Version: 0.11.0
Severity: major Keywords: Safari, AJAX
Cc: michael@schubert.cx

Description

This only seems to occur when using Apache and Safari, If I use Firefox, the problem goes away, and if I use webrick and Safari, it's okay. sam- in IRC said this might be due to a workaround with the AJAX to deal with Safari. The crucial bit is in the apache.log output.

development.log:
Processing AccountController#preferences (for 127.0.0.1 at Wed Mar 23 12:57:10 PST 2005)
  Parameters: {"action"=>"preferences", "preferences.html"=>nil, "controller"=>"account"}
Rendering account/preferences within layouts/application
Rendering layouts/application (200 OK)
Completed in 0.251110 (3 reqs/sec) | Rendering: 0.242287 (96%) | DB: 0.014209 (5%)

apache.log:

/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.6.0/lib/action_controller/cgi_ext/raw_post_data_fix.rb:40:in `[]=': bad environment variable value (ArgumentError)
        from /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.6.0/lib/action_controller/cgi_ext/raw_post_data_fix.rb:40:in `read_query_params'
        from /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.6.0/lib/action_controller/cgi_ext/raw_post_data_fix.rb:14:in `initialize_query'
        from /usr/local/lib/ruby/1.8/cgi.rb:2269:in `initialize'
        from /usr/local/lib/ruby/gems/1.8/gems/rails-0.11.0/lib/dispatcher.rb:28:in `new'
        from /usr/local/lib/ruby/gems/1.8/gems/rails-0.11.0/lib/dispatcher.rb:28:in `dispatch'
        from /Users/schubert/Sites/weird/public/dispatch.cgi:10
[Wed Mar 23 12:57:26 2005] [error] [client 127.0.0.1] Premature end of script headers: /Users/schubert/Sites/weird/public/dispatch.cgi

preferences.rhtml:

    <%= form_remote_tag(:url => {:controller => 'account', :action => 'update_with_ajax'},
                        :html => {:class => 'user'},
                        :update => 'users',
                        :loading => "Toggle.display('flash-message');
                          $('flash-message').innerHTML = 'Saving Preferences...'",
                        :complete => "Toggle.display('flash-message');
                          $('flash-message').innerHTML = 'Preferences Saved'") %>
      <label for="user_login"><b>Username:</b> </label>
      <%=h @user.login %><br /><br />
      <%= hidden_field "user", "login" %>
      <label for="user_email"><b>Email Address</b></label><small> (Required)</small><br />
      <%= text_field "user", "email" %><br />
      <label for "user_first_name"><b>First Name</b></label><small> (Optional)</small><br />
      <%= text_field "user", "first_name" %><br />
      <label for "user_last_name"><b>Last Name</b></label><small> (Optional)</small><br />
      <%= text_field "user", "last_name" %><br />
      <%= submit_tag "Save", :onclick => "Toggle.display('flash-message');" %>
    <%= end_form_tag %>

AccountController:

  def update_with_ajax
    @user = find_user
    @user.attributes = @params['user']
    @user.email = load_email_attribute # Protected attribute, explicit assignment
      if @user.save
        render_action 'preferences'
      else
        render_action 'preferences'
      end
    end   
  end

Change History

03/25/05 06:54:24 changed by Michael Schubert <michael@schubert.cx>

Known issue with Safari apparently.

A temporary solution can be found here: http://wiki.rubyonrails.com/rails/show/HowToUseUnicodeStrings

03/25/05 06:56:38 changed by Michael Schubert <michael@schubert.cx>

I take it back, that fix doesn't solve this problem. Grmble grmble grmble.

03/25/05 08:01:59 changed by Michael Schubert <michael@schubert.cx>

  • priority changed from normal to high.
  • severity changed from normal to major.

The line in question is:

            env_table['RAW_POST_DATA'] = content.freeze

Basically my rails app is unusable with apache+safari right now for anything AJAX.

03/27/05 00:10:56 changed by david

  • status changed from new to closed.
  • resolution set to fixed.

04/05/05 17:32:10 changed by Jim Moy <web@jimmoy.com>

  • status changed from closed to reopened.
  • resolution deleted.
  • summary changed from Apache + Safari + AJAX == problem to Bad POST in Rails4Days.pdf examples (was Apache + Safari + AJAX == problem).

The last change breaks a number of examples for me in the "Four Days on Rails" tutorial by John McCreesh. Two form method=post pages in that example app cause an exception downstream in CGI::parse.

Environment: WinXP, Apache 2.0.53, FastCGI, MySQL 4.0.1, Firefox 1.0.2. Causes exception that exits the fcgi ruby instance. Also happens running under WEBrick. I put the right side back to "= content.freeze" and everything's fine.

04/08/05 16:05:01 changed by MichaelSchubert <michael@schubert.cx>

So we have a situation where without the fix, its broken under OS X, Apache 1.3.x and Safari. And with the patch its broken on WinXP, Apache 2.x and Firefox. Wonderful. Any suggestions? Some kind of exception for whichever one is the anomaly? Is it only broken with Firefox on winxp? what about IE? Opera?

04/09/05 15:09:44 changed by nzkoz

  • milestone set to 1.0.

06/30/05 21:46:37 changed by minam

Jim, what is the exception that you get in CGI::parse?

07/10/05 06:31:17 changed by kkaempf@suse.de

Hmm, it worked with rails 0.12.1 + apache2 + konqueror, after update to rails-0.13.0.1772 it fails again. No problem with using the mozilla firefox browser.

08/19/05 10:51:55 changed by Dan A. Dickey

Ditto here - failing at the env_tableRAW_POST_DATA? line in raw_post_data_fix.rb using konqueror. Works using Mozilla. BTW - isn't this in ActionPack (1.9.1) ? Not in ActiveRecord.

08/19/05 11:27:04 changed by michael@schubert.cx

  • component changed from ActiveRecord to ActionPack.

Indeed it should be.

08/19/05 11:30:17 changed by Dan A. Dickey

  • component changed from ActionPack to ActiveRecord.

Ok, with some judicious use of logging - I figured out what the line:

env_tableRAW_POST_DATA? = content.split("&_").first.to_s.freeze # &_

is a fix for Safari Ajax postings that always append \000 was trying to do. Simply remove a trailing null character if one was at the end of content. It looks like the author was trying to use the feature of split to leave off trailing nulls. However, if the content has no parameters - this was a problem. I changed the line to the following:

if content[content.length-1] == 0

content.chop!

end env_tableRAW_POST_DATA? = content.freeze

And now konqueror is happy, as is Mozilla. Perhaps someone can get this into the code...

08/19/05 11:31:29 changed by Dan A. Dickey

  • component changed from ActiveRecord to ActionPack.

Whoops. Modification collision.

08/19/05 12:12:14 changed by Dan A. Dickey

Make that:

    if content[content.length-1] == 0
        content.chop!
    end
    env['RAW_POST_DATA'] = content.freeze

Someone better at ruby than me may possibly tighten that up a bit.

09/02/05 14:41:31 changed by minam

  • status changed from reopened to closed.
  • resolution set to fixed.

A trivial variation on Dan's solution has been added [2106]