The Dev Blog

Putting Family Management on Rails!

Rotating the Rails logs with FastCGI

Posted by Guy Naor Fri, 23 Jun 2006 15:47:00 GMT

Deploying a rails app will eventually lead to the need to manage the rails log files. They get pretty big fast, and if the log level also include the SQL queries, they grow EXTREMLY fast.

Though there is some information about it in the Rails Wiki, it's missing restarting the FastCGI processes. If you are using dynamicaly launched FastCGI processes from lighty or apache, the web server log rotation will restart the FastCGI processes and you will be covered. But if you are using FastCGI processes you launch (using spinner/spawner or a similar solution) the log file will be rotated, but the newly created log file won't be used by the ruby app until it is restarted.

Here is my logrotate configuration:

# Assume the the rails app is installed to /app/my_blog/current
# And that the user we running the app with is called rails
/app/my_blog/current/log/*.log {
  daily
  missingok
  rotate 7
  compress
  delaycompress
  notifempty
  create 0660 rails rails
  postrotate
     /app/my_blog/current/script/process/reaper -a graceful -d /app/my_blog/current/public/dispatch.fcgi 1>/dev/null 2>&1 || true
  endscript
}

The main change from the rails wiki version is the postrotate call that causes the fastCGI processes to restart and reopen the log file.

Posted in , ,  | no comments | no trackbacks

del.icio.us:Rotating the Rails logs with FastCGI digg:Rotating the Rails logs with FastCGI spurl:Rotating the Rails logs with FastCGI wists:Rotating the Rails logs with FastCGI simpy:Rotating the Rails logs with FastCGI newsvine:Rotating the Rails logs with FastCGI blinklist:Rotating the Rails logs with FastCGI furl:Rotating the Rails logs with FastCGI reddit:Rotating the Rails logs with FastCGI fark:Rotating the Rails logs with FastCGI blogmarks:Rotating the Rails logs with FastCGI Y!:Rotating the Rails logs with FastCGI smarking:Rotating the Rails logs with FastCGI magnolia:Rotating the Rails logs with FastCGI segnalo:Rotating the Rails logs with FastCGI

Lighttpd with SSL

Posted by Guy Naor Mon, 01 May 2006 03:51:00 GMT

I need SSL (https) support for famundo - it is our expectation that almost everything on famundo will be accessed through https, as the information our customers will put on it might be sensitive, and in any case, there are always privacy issues that need to be taken care of.

My web server of choice is lighttpd, and while implementing the SSL (https) part, I had two problems and finding the solution took some digging. So here's what I did to get it to work.

  1. Listening to both http and https on the same server process - once ssl is activated in lighty using: ssl.engine = "enable", the server start listening on port 443 only. It's the SSL port, and now I can connect with https. But no more http connections are accepted. To solve this, the server needs to be instructed to bind to the SSL port as well as the regular port. In the config:

    $SERVER["socket"] == "0.0.0.0:443" {
        ssl.engine = "enable"
        ssl.pemfile = "/etc/lighttpd/server.pem"
    

    }

  2. Using a chained certificate will not work correctly with this setting. You will get https communications, but the browser will complain that the certificate isn't authorizing correctly. To fix that, add the following line to thew config file:

    ssl.ca-file = "/etc/lighttpd/YourCACert.crt"

The ceret file you point to, is of the certification authority that signed your certificate. The client will then authenticate fully.

Posted in  | no comments | no trackbacks

del.icio.us:Lighttpd with SSL digg:Lighttpd with SSL spurl:Lighttpd with SSL wists:Lighttpd with SSL simpy:Lighttpd with SSL newsvine:Lighttpd with SSL blinklist:Lighttpd with SSL furl:Lighttpd with SSL reddit:Lighttpd with SSL fark:Lighttpd with SSL blogmarks:Lighttpd with SSL Y!:Lighttpd with SSL smarking:Lighttpd with SSL magnolia:Lighttpd with SSL segnalo:Lighttpd with SSL

Smart Caching and mod_rewrite Black Magic

Posted by Guy Naor Wed, 22 Mar 2006 20:06:00 GMT

To be able to serve large amount of data, especially pictures and similar files, I needed it to be served by the web server directly. Web servers are so optimized to serve this kind of files that anything developed in rails (or any other framework/language) will always be slower. But there is a problem with serving those files in a system requiring authentication. Putting them anywhere the server can get at, will make them available to anyone knowing the URL - not good at all. Using caching (like the one built into rails) is possible, but becomes impractical for large number of files, and require cache management in the application. So I decided to handle the different access modes for famundo in two separate ways. The private files requiring authentication for access will be delivered directly from the controllers of famundo, using send_file(). The public files will be served directly by the web server. To make sure I don't have to copy and duplicate every file I want to share, I just symlink from the public area into the private area files. A note here: NEVER EVER point to a directory this way - only to files. If you point to a directory you open yourself up to directory traversal attacks. So for a simple system, this wil be it. But for a system hosting large number of distinct users, each with his/her own data, some more changes are needed. Each family hosted in famundo will have it's own files and directories, and we need to keep them separate. And because we don't want to keep the files with the original file name, but only with some internal ID (keeps managemet MUCH easier, and obliviates the need for file name sanitation), we need an easy way to get at the file but still return the correct name to the browser. Enter mod_rewrite. Please note that I'm describing lighttpd mod_rewrite and not apache's. A similar thing can be done with apache, but the syntax is different.

For this example, we will have a family hosted as smith3.famundo.com. And the files we publish for this family will we internaly stored at: /data/private_data/families/s/m/smith3/files/ (Side note: the s and m before the full family name serve to distribute the families over multiple directories - I can explain the reasoning if there's an interest). Files are also distributed using part of the file ID. The file my_amazing_picture.png, that has ID 835 in the database, will be stored under /3/5/835.png. So the full path to the file will be: /data/private_data/families/s/m/smith3/files/3/5/835.png. In the public direcotry of rails, we add a directory structure for the files: public/family_files/s/m/smitsh3/files, and in it we store the symlinks to the private files. So our famous picture will be a symlink:

public/family_files/s/m/smitsh3/files/3/5/835.png ->
/data/private_data/families/s/m/smith3/files/3/5/835.png.

But now we want a nice URL. We don't want to point every picture at this long ugly URL. mod_rewrite to the rescue! First thing first, enable mod_rewrite in the lighttpd config. Then add the following "black-magic" entry to the config file:

# Incoming URL: http://smith3.famundo.com/pub/file/835/my_file.png
# translated to: /published_files/s/m/smith3/file/3/5/835.png
$HTTP["host"] =~ "((.)(.)(.*)).famundo.com" {
    url.rewrite-once = ( "/pub/(.+)/(\d*(\d)(\d))/.*(..*)$" => 
                         "/published_files/%2/%3/%1/$1/$3/$4/$2$5" )
}

A nice side effect of this trick is that we can give the file the true name in the URL. We don't even need to sanitize it, because we discard it when we retrieve the file. We retrieve the ID based name, but to the browser it appeared named correctly.

Some things to keep in mind:

  1. The family name need to be atleast 2 characters long.
  2. The file name based on the ID need to be atleast 2 digits. You can always use sprintf "%02d", id for that.
  3. Sharing a file is only creating a symlink in the published structure. Unsharing is just a delete of the same symlink.
  4. Different mappings can be created as long as the mapping can be represented in a regular expression.
  5. A more advanced mapping can be created by using the Lua language with lighttpd config file.

Posted in ,  | no comments | no trackbacks

del.icio.us:Smart Caching and mod_rewrite Black Magic digg:Smart Caching and mod_rewrite Black Magic spurl:Smart Caching and mod_rewrite Black Magic wists:Smart Caching and mod_rewrite Black Magic simpy:Smart Caching and mod_rewrite Black Magic newsvine:Smart Caching and mod_rewrite Black Magic blinklist:Smart Caching and mod_rewrite Black Magic furl:Smart Caching and mod_rewrite Black Magic reddit:Smart Caching and mod_rewrite Black Magic fark:Smart Caching and mod_rewrite Black Magic blogmarks:Smart Caching and mod_rewrite Black Magic Y!:Smart Caching and mod_rewrite Black Magic smarking:Smart Caching and mod_rewrite Black Magic magnolia:Smart Caching and mod_rewrite Black Magic segnalo:Smart Caching and mod_rewrite Black Magic
Subscribe to The Dev Blog