Will,

Yes it's the case that a front-end web server (nginx) is sitting in  
front of the mongrels but no it's not the case that it is misconfigured.

As I hoped my example was illustrating, the web server knows about  
different virtual hosts but mongrel doesn't.


Let me try and give another example with even more detail:


Assume:

* Mongrel (without patch), which serves any static files it finds in  
it's doc root (RAILS_ROOT/public)

* Web server  (WS) virtual host mapping:

*    example.com => /var/www/apps/example.com/public             (web  
server's doc root for virtual host 1)

*    es.example.com => /var/www/apps/example.com/public/es  (web  
server's doc root for virtual host 2)


directory structure (DS) when cache is cleared:

RAILS_ROOT/public
RAILS_ROOT/public/es


Steps on 1st request: http://example.com

1. WS: can't find index.html in /var/www/apps/example.com/public
2. WS forwards request to mongrel process (M)
3. M can't find index.html in /var/www/apps/example.com/public
4. Mongrel creates a rails process to handle request for /
5. Rails, sees example.com host and / path and renders index.html in / 
var/www/apps/example.com/public
6. Mongrel serves /var/www/apps/example.com/public/index.html back

There's no problem at this point. But bear with me...

DS is now:

RAILS_ROOT/public
RAILS_ROOT/public/index.html
RAILS_ROOT/public/es

Steps on 2nd request: http://example.com

1. WS: finds index.html in /var/www/apps/example.com/public
2. WS serves request

Again, no problem...just served up previously cached file from same  
domain.


DS is still:

RAILS_ROOT/public
RAILS_ROOT/public/index.html
RAILS_ROOT/public/es


Steps on 3rd request: http://es.example.com

1. WS: can't find index.html in /var/www/apps/example.com/public/es <=  
Note the doc root is different
2. WS forwards request to mongrel process (M)
3. M finds index.html in /var/www/apps/example.com/public
4. Mongrel serves /var/www/apps/example.com/public/index.html which is  
the page associated with the http://example.com domain.
5. This is NOT the required behaviour as it's serving the cached file  
for http://example.com rather than http://es.example.com as was  
requested.

DS is still:

RAILS_ROOT/public
RAILS_ROOT/public/index.html
RAILS_ROOT/public/es


Alternative 3rd request (http://es.example.com) with * patched mongrel  
* (mongrel set NOT to serve any static files):

1. WS: can't find index.html in /var/www/apps/example.com/public/es
2. WS forwards request to mongrel process (M)
3. M ignores index.html in /var/www/apps/example.com/public as it  
directly forwards request to rails
4. Mongrel creates a rails process to handle request
5. Rails, sees es.example.com host and / path and renders index.html  
in /var/www/apps/example.com/public/es
6. Mongrel serves /var/www/apps/example.com/public/es/index.html back

DS is now:

RAILS_ROOT/public
RAILS_ROOT/public/index.html
RAILS_ROOT/public/es
RAILS_ROOT/public/es/index.html

Note: Now the right page has been served for the right domain. After  
the file has been cached for http://es.example.com, the WS will  
happily serve that up.

Phew, I hope this finally illustrates the problem with more clarity.

:)

Regards,

Saimon

On Jan 25, 2008, at 3:32 PM, Will Green wrote:

> SO, it sounds like you have Apache (or another web server) in front  
> of a pack of Mongrels, which should be serving static files. It  
> sounds like your front-end web server is passing requests back to  
> mongrel when this is not your intent. If so, it sounds like you have  
> a misconfiguration in your front-end web server configuration.
>
> Is this the case?
>
> ==
> Will Green
>
> Saimon Moore wrote ..
>> Hi Nathan,
>>
>> The problem is that mongrel is serving the static file long before
>> rails knows anything about it.
>>
>> e.g. As I mention in the patch, you have a web server setup with
>> multiple virtual hosts each mapped to a separate doc root.
>>
>> example.com => /var/www/apps/example.com/public
>>
>> es.example.com => /var/www/apps/example.com/public/es
>>
>> Rails is using page caching and the cache is clean.
>>
>> 1st request:
>>
>> http://example.com =>
>>
>> 1. web server looks for /var/www/apps/example.com/public/index.html
>> 2. passes request to mongrel which does the same thing, doesn't find
>> it and calls rails to render it.
>> 3. Now /var/www/apps/example.com/public/index.html exists as was
>> cached by rails.
>>
>> 2nd request:
>>
>> http://es.example.com =>
>>
>> 1. web server looks for /var/www/apps/example.com/public/es/ 
>> index.html
>> 2. passes request to mongrel which looks for /var/www/apps/ 
>> example.com/
>> public/index.html
>> (which unlike the web server, has only one doc root),
>> finds the file under /var/www/apps/example.com/public/index.html
>> (from the previous request) and serves that back before rails has  
>> even
>> got a chance to know about it. It has served the wrong file.
>>
>> I hope this example makes it clearer.
>>
>> With the ability to force mongrel to forward all requests it receives
>> to rails, on the second request rails (using the host info) would  
>> then
>> cache the index.html file into /var/www/apps/example.com/public/es/
>> index.html.
>>
>> As I was writing this, I just thought of another possibility being
>> writing a custom mongrel handler, but as mongrel_rails is a handler
>> itself, it seems a bit pointless so I still think my patch has  
>> merits.
>>
>> Thoughts?
>>
>> Regards,
>>
>> Saimon
>>
>>
>> On Jan 24, 2008, at 4:42 PM, Nathan Vack wrote:
>>
>>> On Jan 24, 2008, at 6:13 AM, Saimon Moore wrote:
>>>
>>>> Hi all,
>>>>
>>>> I've just added a patch that I'd appreciate some feedback on:
>>>>
>>>> http://rubyforge.org/tracker/index.php?
>>>> func=detail&aid=17446&group_id=1306&atid=5147
>>>
>>> I'll admit by cold-addled brain isn't following logic perfectly this
>>> morning, but I feel like this really would be better handled by the
>>> upstream HTTP handler giving enough information to your app so it
>>> serves the right cached file (or runs the right controller, or
>>> whatever).
>>>
>>> I think passing the Host: header along with the request_routing
>>> plugin (assuming you're on Rails) will make everything happy:
>>>
>>> http://agilewebdevelopment.com/plugins/request_routing
>>>
>>> Or am I missing something?
>>>
>>> -Nate
>>> _______________________________________________
>>> Mongrel-users mailing list
>>> Mongrel-users@rubyforge.org
>>> http://rubyforge.org/mailman/listinfo/mongrel-users
>>
>> -- 
>> Saimon Moore
>> Freelance Web Developer
>> (Available for hire - For details visit http://saimonmoore.net)
>>
>> Skype: saimonmoore
>> Yahoo IM: saimonmoore
>> Google IM: saimonmoore
>>
>>
>>
>> _______________________________________________
>> Mongrel-users mailing list
>> Mongrel-users@rubyforge.org
>> http://rubyforge.org/mailman/listinfo/mongrel-users
>>
> _______________________________________________
> Mongrel-users mailing list
> Mongrel-users@rubyforge.org
> http://rubyforge.org/mailman/listinfo/mongrel-users

-- 
Saimon Moore
Freelance Web Developer
(Available for hire - For details visit http://saimonmoore.net)

Skype: saimonmoore
Yahoo IM: saimonmoore
Google IM: saimonmoore



_______________________________________________
Mongrel-users mailing list
Mongrel-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-users

Reply via email to