Archive for June, 2009
Really checking the content-type/mime_type of a file in OSX and Linux
I have came across many projects where checking file uploads and content-type (mime-type) is poorly implemented or heavy in resource.
Methods I have seen so far:
1. Checking content-type from file name: this inefficient, a user can just rename a file and you are fooled, or the file can have a different file format and you will not get the expected result.
2. Using Rmagick to check if the file is an image. This is so slow and uses so much Ram. You can try to initialize an rmagick object from an image file, then rescue when the file is not an image.
3. Using mini_magick to check if a file. This method is faster than rmagick. Implemen ted same way as rmagick.
A Better method for OSX and Linux, is to use the command line tool “file” included in most UNIX operating systems.
It is very fast and very accurate.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | file = "/path/to/file.ext" if RUBY_PLATFORM.match(/darwin|linux|unix|solaris|bsd/) content_type = `file --raw --brief "#{file}"`.chomp case when content_type.match(/image|png|jpg|jpeg|gif/) real_type = "image" when content_type.match(/pdf/) real_type = "pdf" when content_type.match("Microsoft Word|Microsoft Office Document") real_type = "doc" else # This can go on and on real_type = "Unknown" end end |
Some examples of content types:
.doc = Microsoft Word document data
.doc = Microsoft Office Document
.pdf = PDF document, version 1.4
.pdf = PDF document, version 1.3
.psd = Adobe Photoshop Image
.png = PNG image data, 3508 x 4961, 8-bit/color RGBA, non-interlaced
.gif = GIF image data, version 89a, 195 x 109
.jpg = JPEG image data, EXIF standard
etc…
I hope this can be useful to someone.
Easy installing Nginx + mod_rails passenger OSX
Requirements:
1. XCODE you can download xcode from http://developer.apple.com/tools/xcode/index.html
2. OSX 10.4, 10.5 or 10.6
Procedures:
1. Install Passenger
$ sudo gem install passenger
now check where is passenger installed:
$ passenger-config --root
in my case is: /opt/local/lib/ruby/gems/1.8/gems/passenger-2.2.5
2. Install nginx
If you have nginx from macports, deactivate it in case of conflicts.
You can activate anytime later
$ sudo port deactivate nginx
$ wget http://sysoev.ru/nginx/nginx-0.7.59.tar.gz
$ wget http://sysoev.ru/nginx/nginx-0.7.62.tar.gz
$ tar xpf nginx-0.7.62.tar.gz
$ cd nginx-0.7.62
I Recommend using nginx 0.6 series because I had a lot of “502 Bad Gateway” with 0.7 series. $ wget http://sysoev.ru/nginx/nginx-0.6.37.tar.gz $ tar xpf nginx-0.6.37.tar.gz $ cd nginx-0.6.37
$ sudo ./configure --add-module=/opt/local/lib/ruby/gems/1.8/gems/passenger-2.2.5/ext/nginx/ \ --with-http_ssl_module --user=nobody --group=nobody --with-http_gzip_static_module \ --with-poll_module --prefix=/opt/local --with-pcre
Configuration summary + using system PCRE library + using system OpenSSL library + md5: using OpenSSL library + sha1 library is not used + using system zlib library nginx path prefix: "/opt/local" nginx binary file: "/opt/local/sbin/nginx" nginx configuration prefix: "/opt/local/conf" nginx configuration file: "/opt/local/conf/nginx.conf" nginx pid file: "/opt/local/logs/nginx.pid" nginx error log file: "/opt/local/logs/error.log" nginx http access log file: "/opt/local/logs/access.log" nginx http client request body temporary files: "client_body_temp" nginx http proxy temporary files: "proxy_temp" nginx http fastcgi temporary files: "fastcgi_temp"
$ sudo make
$ sudo make install
$ cd /opt/local/conf
$ sudo cp mime.types.default mime.types
$ sudo cp nginx.conf.default nginx.conf
Edit nginx.conf
$ mate nginx.conf
or
$ sudo vi nginx.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | user nobody; worker_processes 2; #error_log logs/error.log; #error_log logs/error.log notice; error_log logs/error.log info; # Pid pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; gzip on; # if a precompiled gzip of the file exists, use it and force http proxies # to use separate cache's based on User-Agent gzip_static on; gzip_min_length 2000; gzip_buffers 16 8k; gzip_types text/plain text/html text/css image/x-icon application/xml application/xml+rss text/javascript; gzip_disable "MSIE [1-6] \."; gzip_vary on; gzip_comp_level 2; gzip_proxied any; server { listen 80; server_name localhost; location / { root /Users/fred/Sites ; autoindex on; index index.html index.htm; } } passenger_root /opt/local/lib/ruby/gems/1.8/gems/passenger-2.2.2; passenger_max_pool_size 8; passenger_max_instances_per_app 1; # The maximum number of seconds that an application instance may be idle. # That is, if an application instance hasn’t received any traffic after the given number of seconds, # then it will be shutdown in order to conserve memory. passenger_pool_idle_time 3600; # Project 1 server { listen 80; client_max_body_size 250M; server_name project1.local; root /Users/fred/rails/project1/public; passenger_enabled on; rails_env development; access_log /Users/fred/rails/project1/log/nginx.access.log; error_log /Users/fred/rails/project1/log/nginx.error.log info; } # Project 2 server { listen 80; client_max_body_size 250M; server_name project2.local; root /Users/fred/rails/project2/public; passenger_enabled on; rails_env development; access_log /Users/fred/rails/project2/log/nginx.access.log; error_log /Users/fred/rails/project2/log/nginx.error.log info; } # Project 3 server { listen 80; client_max_body_size 250M; server_name project3.local; root /Users/fred/rails/project3/public; passenger_enabled on; rails_env development; access_log /Users/fred/rails/project3/log/nginx.access.log; error_log /Users/fred/rails/project3/log/nginx.error.log info; } # And so on... as many projects as you want } |
Now edit your /etc/hosts and add the hosts for your local project
$ mate /etc/hosts
127.0.0.1 project1.local 127.0.0.1 project2.local 127.0.0.1 project3.local
3. Start nginx
sudo nginx
4. go to your browser and open project1.local
5. Easy start/restart/stop
add this to your ~/.bash_profile file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | function nginx_reload() { FILE="/opt/local/logs/nginx.pid" if [ -e $FILE ]; then echo "Reloading NGINX..." PID=`cat /opt/local/logs/nginx.pid` sudo kill -HUP $PID else echo "Nginx pid file not found" return 0 fi } function nginx_stop() { FILE="/opt/local/logs/nginx.pid" if [ -e $FILE ]; then echo "Stopping NGINX..." PID=`cat /opt/local/logs/nginx.pid` sudo kill -INT $PID else echo "Nginx pid file not found" return 0 fi } function nginx_restart() { FILE="/opt/local/logs/nginx.pid" if [ -e $FILE ]; then echo "Stopping NGINX..." PID=`cat /opt/local/logs/nginx.pid` sudo kill -INT $PID sleep 1 echo "Starting NGINX..." sudo nginx else echo "Nginx pid file not found" return 0 fi } |
Troubleshooting
1. Nginx is not running
- check the logs
- check if it is really not running:
$ ps aux | grep nginx
2. you see the nginx error “502 Bad Gateway”
- may there is a problem with the /var/folders/ permissions on OSX:
2009/06/13 16:14:33 [crit] 1106#0: *1 connect() to unix:/var/folders/xl/xlSRYvzFHH8Fcehc51ciyE+++TI/-Tmp-//passenger.1091/master/helper_server.sock failed (13: Permission denied) while connecting to upstream, client: 127.0.0.1, server: hassan.local, request: "GET / HTTP/1.1", upstream: "unix:/var/folders/xl/xlSRYvzFHH8Fcehc51ciyE+++TI/-Tmp-//passenger.1091/master/helper_server.sock:", host: "hassan.local"
to fix it I did this:
$ sudo find /var/folders/xl/ -name “master” -exec chmod 755 {} \;
$ sudo find /var/folders/xl/ -name “-Tmp-” -exec chmod 755 {} \;
everytime I reboot my mac I had to do that… I still dont know how to fix it…
anybody knows?
That is it for now.

