Erik's blog

Code, notes, recipes, general musings

Archive for December 2009

setting up nginx and mochiweb on centos 5

with one comment

  1. Install nginx on centos using cyberciti’s tutorial
  2. update default iptables to allow http traffic:
    # ref:
    # ref:
    # Firewall configuration written by system-config-securitylevel
    # Manual customization of this file is not recommended.
    :INPUT ACCEPT [0:0]
    :OUTPUT ACCEPT [0:0]
    :RH-Firewall-1-INPUT - [0:0]
    -A INPUT -j RH-Firewall-1-INPUT
    -A FORWARD -j RH-Firewall-1-INPUT
    -A RH-Firewall-1-INPUT -i lo -j ACCEPT
    -A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
    -A RH-Firewall-1-INPUT -p 50 -j ACCEPT
    -A RH-Firewall-1-INPUT -p 51 -j ACCEPT
    -A RH-Firewall-1-INPUT -p udp --dport 5353 -d -j ACCEPT
    -A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
    -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
    -A RH-Firewall-1-INPUT -m tcp -p tcp --dport 80 -j ACCEPT
    -A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
    -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
  3. install mochiweb using BeeBole’s tutorial.  For ease of use while testing, launch dev server using separate screen, as the mochiweb shell will own the terminal used to launched it by default, and add the following line to iptables so we can hit the server directly:
    -A RH-Firewall-1-INPUT -m tcp -p tcp --dport 8000 -j ACCEPT # allow access to mochiweb

    Test that mochiweb is available to localhost by running the following from the command line on the server:


    You should get something back like:

    <title>It Worked</title>
    MochiWeb running.

  4. Configure nginx to proxy api calls to mochiweb.  Put this in /etc/nginx/nginx.conf:
    user              nginx;
    worker_processes  1;
    error_log         /var/log/nginx/error.log;
    pid               /var/run/;
    events {
        worker_connections  1024;
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
        log_format  main  '$remote_addr - $remote_user [$time_local] $request '
                          '"$status" $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
        access_log  /var/log/nginx/access.log  main;
        sendfile        on;
        keepalive_timeout  65;
        include /etc/nginx/conf.d/*.conf;
        server {
            listen       80;
            server_name  localhost;
            location ~ api { # <-- pass requests for 'api...' to mochiweb
            location / {
                root   /usr/share/nginx/html;
                index  index.html index.htm;
            error_page  404              /404.html;
            location = /404.html {
                root   /usr/share/nginx/html;
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   /usr/share/nginx/html;

    As per BeeBole’s tutorial, edit the mochiweb request handler to handle requests for ‘api’:

    %% @author author <>
    %% @copyright YYYY author.
    %% @doc Web server for myapp.
    -author('author <>').
    -export([start/1, stop/0, loop/2]).
    %% External API
    start(Options) ->
        {DocRoot, Options1} = get_option(docroot, Options),
        Loop = fun (Req) ->
                       ?MODULE:loop(Req, DocRoot)
        mochiweb_http:start([{name, ?MODULE}, {loop, Loop} | Options1]).
    stop() ->
    loop(Req, DocRoot) ->
        "/" ++ Path = Req:get(path),
        case Req:get(method) of
            Method when Method =:= 'GET'; Method =:= 'HEAD' ->
                case Path of
                    "api" -> Req:ok({"text/html", [],["<h1>Congratulation</h1>"]}); % <-- the 'api' request handler
                    _ -> Req:serve_file(Path, DocRoot)
            'POST' ->
                case Path of
                    _ ->
            _ ->
                Req:respond({501, [], []})
    %% Internal API
    get_option(Option, Options) ->
        {proplists:get_value(Option, Options), proplists:delete(Option, Options)}.

    As per James Gardner’s post Streaming File Upload with Erlang and Mochiweb Multipart Post, rebuild the request handler by running make in the myapp directory. The mochiweb server will automatically restart

  5. confirm the proxy is working by hitting http://domain/ and http://domain/api.  The former should return the nginx install confirmation page, and the latter should return the simple “Congratulation” page.

Written by Erik

December 26, 2009 at 9:51 pm

Posted in tutorial

Tagged with , ,

steps for merging changes from a remote clone of a git repo

leave a comment »

I’m a fan of github, but I don’t know how to apply changes made to a clone of my repo, usually announced via a pull request. The goal of this post, then, is to define these steps. Note: the steps below pulled in the changes as desired, but also auto-committed them despite the —no-commit flag, so these steps need refinement.


  • a git repo named origin
  • committer has issued a pull request. For this example, I’ll use a committer named FooBaz


  1. add commiter’s repo as a remote
    • copy clone url for pull requester’s repo, eg git://
    • define remote repo: git remote add FooBaz git://
    • view list of remotes as sanity check: git remote show
  2. pull in FooBaz’s changes:
    • run: git pull --no-commit FooBaz master
    • note: this actually committed the changes for me 😐
  3. push changes to origin repo: git push origin master


Written by Erik

December 24, 2009 at 11:43 am

Posted in tutorial

Tagged with ,

Dav Glass’ YQL module for YUI 3 is awesome

leave a comment »

sample app:

<script type="text/javascript" src=""></script>
<script type="text/javascript" src=""></script>
YUI().use('yql', 'node', function(Y) {
 var q1 = new Y.yql('select source from where photo_id in (select id from where text="panda" and safe_search="true")');
 q1.on('query', function(r) {
     var li = Y.get('li');
     for (var i = 0; i < r.results.size.length; i++) {
         if (-1 !== r.results.size[i].source.indexOf('_s')) {
             var clone = li.cloneNode(true);
             clone.query('img').set('src', r.results.size[i].source);



Update 12/13/10 YUI 3 now supports YQL natively:

Written by Erik

December 24, 2009 at 2:51 am

Posted in code

Tagged with , ,

centos 5 yum update error & resolution

leave a comment »

I just tried to update my centos 5 install via yum and got the following error messages:

filelists.sqlite.bz2                                                                                                                                                                 | 1.5 MB     00:01 [Errno -1] Metadata file does not match checksum
Trying other mirror.
filelists.sqlite.bz2                                                                                                                                                                 | 1.1 MB     00:00 [Errno -1] Metadata file does not match checksum
Trying other mirror.

I searched on line for “yum update Metadata file does not match checksum” and found a helpful blog post. Following the post suggestion, I ran yum clean all, which seems to have fixed the problem.

Written by Erik

December 23, 2009 at 6:36 pm

Posted in Uncategorized