Thursday, May 17, 2007

mod_ruby and HTTP POST

I was installing a single-sign-on mechanism that used mod_ruby. It worked great protecting pages, until I hit an area that tried to do HTTP POST. The application I was protecting used the comparison of a form field token and a cookie with the same token to prevent spoofing and complained.
I did some investigating and found out that the POST variables were flat-out missing after running through my mod_ruby authentication handler. I wrote a dummy handler and found that you have to run request.send_http_header before sending the Apache::OK to get the variables to go through. Great, but my real handler was still giving me problems.
It turns out that mod_ruby consumes the header as soon as you do a read of a cookie or a header. For a GET that's not a form, this isn't an issue and you wouldn't notice in most cases. For forms, particularly POST, it's a real problem.
I solved this by doing the following:
  • Added request.send_http_header before all my returns
  • Used req2 = request.lookup_uri("/known_nonexistent_page") to effectively clone the request.
  • Changed my cookie read to point to req2. If you want to read cookies, the cookies will go to this secondary request, so you can read them from there and consume that request while leaving your original one alone.

This seems to have fixed the problem in my tests, and POSTs and file uploads work fine, but I'll know for sure when I roll it out.

Monday, May 14, 2007

PySQLite 2.3.3 installation issue

I was trying to install PySQLite on my RHEL 4 box and ran into an error of the form:
libsqlite3.so.0: cannot open shared object file: No such file
> or directory

Internet research led me to discover that this means that the directory where your SQLite is installed is not in your /etc/ld.so.conf. You can add it there and run ldconfig, or add LD_LIBRARY_PATH=/path/to/SQLiteLibs temporarily to get it to build right. I added my /usr/local/lib to ld.so.conf, ran ldconfig, and then reran the python setup.py install for PySQLite and all was well.

Configuring Trac on Mac OS X - One for the books

I needed to get Trac running locally on my Mac OS X box. There's some info over at the Trac site about it, but I had some extra complications that made my problem stranger. Things like this make me believe more in ProjectLocker, where we can at least save our customers from headaches like this.

Bad Python
I had MacPython installed in /Library/Frameworks/Python.framework. It modifies your .profile to put itself in front of your /usr/local/bin. This was confusing my ClearSilver installation among other things and made a bad situation worse. I removed MacPython by removing:
  • /Library/Frameworks/Python.framework
  • /Applications/MacPython 2.4
and built Python 2.4.4 from source. If you're extra paranoid like me, you can just move the above directories to .old.

ClearSilver Version
Version 0.10.4 still didn't want to play nice (and over at Trac they say it won't) so I went ahead and ran 0.9.14. It gave me a bunch of endedness warnings but ran cleanly. I still had a couple of issues with neo_cgi.so (/usr/bin/install didn't seem to want to copy it over and was even giving me a usage message from the command line), so I went into the python directory of the install and ran python setup.py install to shove it in.

PySQLite
Of course reinstalling Python broke my PySQLite installation, because it was all pointed at the old one at /Macs/Dirty/Secret/LongPath/Whatever. I got PySQLite 2.2.3 and reinstalled it, but then I got error messages on the import talking about it couldn't find _sqlite3_enable_shared_cache. A little research told me this means that it's linked to a different set of SQLite3 drivers than the ones that are loaded, so I went back and reinstalled agin, making sure my setup.cfg pointed to /usr/local/include and /usr/local/lib where my good SQLite3 headers were.

After all that, I ran tracd pointed at a single instance and it worked out fine.

Multiple Subdomain Cookies in Rails, Part 2

You may recall in my previous post that I was having some issues getting a Rails cookie to be viewable across multiple servers in a domain. After rolling out the changes for that and patting myself on the back, I found myself this morning unable to log in to my development instance of my Rails app.

After some thinking and rebooting, I determined that this was due to the fact that I was always forcing the domain, and in development mode the domain was completely different. I wrapped my domain setting statements in a check of the form:

if (["production"].include?(ENV["RAILS_ENV"]))
#Do the domain things from the previous post
end

This seems to work and now my local instance is fine.

The Duh Files - Getting AJAX working in Rails

Last night I was trying to get some simple AJAX working in Rails. I used my form_remote_tag, I had my DIV ready, wrote my controller action, and nothing was working. I called my colleague and realized that I had forgotten to include the Javascript required using:

<%= javascript_include_tag :defaults %>

Duh.

Friday, May 11, 2007

Multiple subdomain cookies in Rails

We needed to share a a cookie generated by Rails across multiple subdomains. I ended up solving the problem with this code, added to my ApplicationController:

DOMAINS = ['mydomain.com'].freeze

DOMAINS.each do |domain|
session :session_domain => ".#{domain}", :if => lambda { |request| request.host.dup.chomp!(domain) }
end

I haven't verified if this is also necessary, but you may need:

ActionController::Base.session_options[:session_key] = 'my_cookie_name'
ActionController::Base.session_options[:session_domain] = '.mydomain.com'


Thanks to RailsWeenie for that one.

Installing Instiki on Mac OS X

I was trying to get Instiki running on my Mac OS X machine, but was getting mysterious errors, where the directories to be created weren't being created. I looked closer and discovered that my initial Web object wasn't saving because the color attribute had a value of '008B26' (including the quotes). I fudged the correct value in to test, and then noticed that it couldn't find a template called "'textile'_help", again with the single quotes.
This led me to believe that something was wrong with my SQLite installation, or with the one that Instiki was using. A little more research and I discovered that Instiki has sqlite3-ruby 1.1.0 embedded. I'm running SQLite 3.3.17 on this machine, so there may be some compatibility problems, such as the one that warranted the upgrade to sqlite3-ruby 1.2.1 for users of SQLite 3.3.8 and above mentioned over at RubyForge.
I punted and solved this by switching to MySQL in the database.yml and running "rake migrate". More ambitious souls may want to figure out how to get Instiki to point to a gem installation of sqlite3-ruby instead of a shipped one.

Introduction

A friend of mine mentioned that he posts all the errors he experiences in his computing life to the Web so that others can Google them. I'm in a particularly giving mood these days, and I think I need to pay forward all the help I get from the geniuses out there solving Web problems, so I created this blog to do the same thing. Each post will be some funky error I'm experiencing and how I got around it.

I don't promise comprehensive details and stack traces, or even successful resolutions, but I hope that this eventually becomes something useful. Enjoy.