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

"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!