PHP, FileReference, and sessions: a bug from hell

Posted on Tuesday 31 October 2006

Oh, I had fun debugging this one. I was using FileReference to build an interface for users to upload their resumes on an agency site. Once the user pressed the send button, the following happened:

  1. File is sent using FileReference to upload.php. The location of the file is remembered using a session.
  2. Second file is sent using same scheme as above.
  3. LoadVars call to portfolio.php sent to trigger email with two files as attachments.

The scheme above was used because files 1 and 2 are optional, FileReference can’t read the return from the server, the location of the uploaded file is determined by the server to ensure a unique name, and additional info needs to be sent along with the email. Now it worked fine in IE but it failed in Firefox. I received the email but no files were attached. Darn. 4 hours and a lot of frustation later, here’s what I found:

When the two files are sent, I get a Set-Cookie header back with the appropriate session id. But when portfolio.php is called, I get another Set-Cookie with a different ID. Both upload.php and portfolio.php use session_start() at the top of the files. Now I tried first starting a session from the container html file. The result in ServiceCapture looked like this:

  1. container.php: Set-Cookie PHPSESSID=a0d…
  2. upload.php: Set-Cookie PHPSESSID=cd3…
  3. upload.php: Set-Cookie PHPSESSID=cd3…
  4. portfolio.php: Set-Cookie PHPSESSID=a0d…

So for some reason a session id was created only for the upload.php calls. It’s like the sessions belonged to a different namespace. So obviously when I tried to create the email with the attachments the data wasn’t in the a0d session but rather in the cd3 session so it failed. What’s more interesting is that if I run the same thing in IE I see BOTH session ids in the cookie. The cookie string looked like “PHPSESSID=a0d…; PHPSESSID=cd3…” WTF? So apparently it only worked in IE because of a bug in the browser!

So I tried to make a call to upload.php?PHPSESSID=a0d… instead. I lifted the session id from FlashVars and appended it to the URL. But PHP still wouldn’t take it. The URL was telling one thing and the cookie was telling another story. So I had to use session_id($_GET['PHPSESSID']) before session_start to get sessions properly working at all. Why the two namespaces anyway? Well, I can only speculate that because the User-Agent is listed as “Shockwave Flash” when using FileReference instead of “Mozilla 4.0″ as it when using LoadVars, PHP believes that the user agent is fraudulent and therefore restarts another session for security reasons. Again only speculating.

In retrospect: if you plan to use sessions in conjunction with FileReference, do the following:

  • Use session_start() in the container html file and pass the session id using echo session_id() in the FlashVars to the Flash file
  • Append the session id to the url for any and all calls to the server made within Flash
  • Call session_id($_GET['PHPSESSID']) before session_start() in any of the php files which Flash communicates with

WordPress database error: [Can't open file: 'wp_comments.MYD'. (errno: 145)]
SELECT * FROM wp_comments WHERE comment_post_ID = '220' AND comment_approved = '1' ORDER BY comment_date

No comments have been added to this post yet.

Leave a comment




Your e-mail address is never displayed. If you run into issues with SpamKarma blocking you, email me at $patrick->5etdemi(com)


RSS feed for comments on this post | TrackBack URI