send_file resets my session cookies!

I'm experiencing a serious problem where the responses of my GET
requests keep reseting my session cookie.

Basically my initial request to www.vidmap.de sets a session cookie on
variable _vm_session_prod which is undesirably overwritten with
different value by a second request.

The second request inside the delivered html document is loading a
jpeg image through http://www.vidmap.de/web/image?image=bikecam_julierpass.jpg.
The image is delivered through send_file(PATH_XYZ, :type => 'image/
jpeg', :disposition => 'inline', :filename => 'video.jpeg', :stream =>
false) on server side.

My problem is that, for what reason ever, the second response sets a
new session cookie (which causes heavy trouble at an other stage). No
other server side responses (render :json / :text) are causing this
strange effect.

Help anyone?

I'm experiencing a serious problem where the responses of my GET
requests keep reseting my session cookie.

Basically my initial request towww.vidmap.desets a session cookie on
variable _vm_session_prod which is undesirably overwritten with
different value by a second request.

The second request inside the delivered html document is loading a
jpeg image throughhttp://www.vidmap.de/web/image?image=bikecam_julierpass.jpg.
The image is delivered through send_file(PATH_XYZ, :type => 'image/
jpeg', :disposition => 'inline', :filename => 'video.jpeg', :stream =>
false) on server side.

My problem is that, for what reason ever, the second response sets a
new session cookie (which causes heavy trouble at an other stage). No
other server side responses (render :json / :text) are causing this
strange effect.

The data in the session cookie actually looks identical (since hashes
aren't guaranteed to have the same order, the second time around some
of the keys are in a different order when the session hash is
serialized)
What is the problem happening later on ?

Fred

> I'm experiencing a serious problem where the responses of my GET
> requests keep reseting my session cookie.

> Basically my initial request towww.vidmap.desetsa session cookie on
> variable _vm_session_prod which is undesirably overwritten with
> different value by a second request.

Should have said before: in real use, it is entirely possible that
you are running into a race condition with sessions, as described
here: http://www.paulbutcher.com/2007/05/race-conditions-in-rails-sessions-and-how-to-fix-them/

Fred

Thanks for your quick response!

Unfortunately the cookies set are not identical. Please look at the
last bit of the two strings:
First response: _vm_session_prod=BAh7xxxx--8afcxxx
Second response: _vm_session_prod=BAh7xxxx--c173xxx (!!!)

The problem later on is that one of my flash files tries to authorize
itself (it sends the session cookie to the server) using the cookie
which was current when the flash file was loaded. BUT meanwhile (in
between flash file was loaded and first flash file request to server)
those images sent by send_file are changing the session cookie. As a
result of this, the requests out of the flash file are refused by the
server (Error 401).

Mario

Thanks for your quick response!

Unfortunately the cookies set are not identical. Please look at the
last bit of the two strings:
First response: _vm_session_prod=BAh7xxxx--8afcxxx
Second response: _vm_session_prod=BAh7xxxx--c173xxx (!!!)

I know they are not bit for bit equal. But if you debase64 them you
can see they represent the same hash.

The problem later on is that one of my flash files tries to authorize
itself (it sends the session cookie to the server) using the cookie
which was current when the flash file was loaded. BUT meanwhile (in
between flash file was loaded and first flash file request to server)
those images sent by send_file are changing the session cookie. As a
result of this, the requests out of the flash file are refused by the
server (Error 401).

does this only happen in production ?

Fred

I'm not sure it's really due to a race condition. All requests are
coming from he same page. Those requests for jpeg images which are
served through send_file are called one after another and still, they
are changing the session cookie all the time.

On the other hand, the problem only occurs when loading the page for
the first time after I cleared all cookies client-side. And btw, I set
cookie :domain => ".vidmap.de" in production environment.

I'm perplexed.

Yes, only in production mode.

Yes, only in production mode.

Have you played with your production environment settings to see if it
happens only if you have several mongrels, passenger instances or
whatever app server you use ?

Fred

I'm using a cluster of several mongrels. Nothing else.

Do you think the cluster is causing the problem?

You mean this

BAh7CDoOcmV0dXJuX3RvIgYvOhB2bV9sYW5ndWFnZSIHZGUiCmZsYXNoSUM6%0AJ0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhhc2h7AAY6CkB1c2Vk
%0AewA%3D--8afcd7d5a8f2f64804ca01de1d32b2129152ece8

is de-based the same as this

BAh7CDoOcmV0dXJuX3RvIgYvIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy
%0AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsAOhB2bV9sYW5ndWFnZSIH%0AZGU
%3D--c173d4fdc20a0a81eefa9969a83b335f436098a9

??

This decoder tells me otherwise!?

http://www.motobit.com/util/base64-decoder-encoder.asp

On the otherhand, I'm using one single mongrel in dev mode. I will
play a bit with the number of mongrels in dev & prod mode!

You mean this

BAh7CDoOcmV0dXJuX3RvIgYvOhB2bV9sYW5ndWFnZSIHZGUiCmZsYXNoSUM6%0AJ0FjdGlvbkNv bnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhhc2h7AAY6CkB1c2Vk
%0AewA%3D--8afcd7d5a8f2f64804ca01de1d32b2129152ece8

is de-based the same as this

BAh7CDoOcmV0dXJuX3RvIgYvIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy
%0AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsAOhB2bV9sYW5ndWFnZSIH%0AZGU
%3D--c173d4fdc20a0a81eefa9969a83b335f436098a9

Yes, but you need to not include the -- and what follows (that's a
signature) and turn the %0A into carriage returns, strip the spaces
and turn the %3D into = signs. with that I get

BAh7CDoOcmV0dXJuX3RvIgYvOhB2bV9sYW5ndWFnZSIHZGUiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhhc2h7AAY6CkB1c2VkewA=

=> ["\004\b{\b:\016return_to\"\006/:\020vm_language\"\ade
\"\nflashIC:'ActionController::Flash::FlashHash{\000\006:\n@used
{\000"]

BAh7CDoOcmV0dXJuX3RvIgYvIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVyOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsAOhB2bV9sYW5ndWFnZSIHZGU=

=> ["\004\b{\b:\016return_to
\"\006/\"\nflashIC:'ActionController::Flash::FlashHash{\000\006:\n@used
{\000:\020vm_language\"\ade"]

This is a marshaled ruby object , and they look the same to me: it's a
hash so ordering of key-value pairs does not matter

Fred

Oh my... a signature! Didn't know this one. Thanks very much!

So basically the situation is that send_file is sending the same
cookie with different signatures over and over again, but does no harm
to the rest of the application, right?

My question then is, why do I receive Error 401 when the flash file is
timely loaded in between (I'm using firebug to verify that) other
send_file responses.

This is a debug sample page where such a flash file is included:
http://www.vidmap.de/?dev_route=true

"Unfortunately" it's working 100% from were I'm at the moment (fast
internet connection) because all Images (send_file) are already
delivered before the flash starts loading itself.

Oh my... a signature! Didn't know this one. Thanks very much!

So basically the situation is that send_file is sending the same
cookie with different signatures over and over again, but does no harm
to the rest of the application, right?

In the traces that you have captured, yes.

My question then is, why do I receive Error 401 when the flash file is
timely loaded in between (I'm using firebug to verify that) other
send_file responses.

This is a debug sample page where such a flash file is included:http://www.vidmap.de/?dev_route=true

"Unfortunately" it's working 100% from were I'm at the moment (fast
internet connection) because all Images (send_file) are already
delivered before the flash starts loading itself.

This really does make it sound like a race condition to me - the
cookies loaded by some requests are overwriting the cookie set by the
page generating the authenticity token (there is a random identifier
stored in the session that is used to create the authenticity token).
You may be able to work around this by forcing this bit of the session
to get earlier, by making the requests that are currently getting 401
use gets (if csrf is not a problem) or by turning off the session for
some requests

Fred

God point Fred. I will play a bit with the things you told me to do
and come back to you later.

How do I actually turn off the session for certain requests?

Found it out myself: session :off, :only => [:xyz]

Turning off the session for one action was the solution for me
finally. I'm very happy!

In the future, would your smart_session_store plugin also be an option
here?

Thanks again Fred,
Mario

Turning off the session for one action was the solution for me
finally. I'm very happy!

In the future, would your smart_session_store plugin also be an option
here?

That's what it's designed to do. It's easier to just not use a session
if you don't need it though (and the cookie store is inherently pretty
speedy too)

Fred

Ok then.

Have a good time!