feel free to email me at

Web server in 58 lines of C

Working proof-of-concept web server in C with dynamic url handlers.

You could compile it with:

gcc -o ws ws.c -ldl
gcc -shared -o dump.so dump.c

Run ./ws and point your browser to http://localhost:8085/dump/hello

Sources: ws.c and dump.c.

It will take first part of uri between slashes, load shared library with this name from current directory and invoke void req(int socket, char *alreadyread, int nobytes) in it.

Request parsing is tricky and fast.

   int c = accept(s,0,0), o = 0, h[2], hi = 0;
   char b[1024];
   while(hi<2&&o<1024) {
      int n = read(c,b+o,sizeof(b)-o);
      if(n<=0) { break; }
      else {
         int i = o;
         o+=n;
         for(;i<n&&hi<2;i++) {
            if(b[i] == '/' || (hi==1&&b[i] == ' ')) { h[hi++] = i; }
         }
      }
   }

Loading and invoking handler

   char mn[80] = "./";
   void *m = 0;
   void (*f)(int,char *,int) = 0;
   int l = h[1] - h[0] - 1;

   memmove(mn+2,b+h[0]+1,l);
   mn[l+2] = '.'; mn[l+3] = 's'; mn[l+4] = 'o'; mn[l+5] = 0;

   m = dlopen(mn,RTLD_NOW);
   f = dlsym(m, "req");
   if(m&&f) { f(c,b,o); }
   if(m) dlclose(m);
   shutdown(c,SHUT_RDWR);
   close(c);

Sample module

#include <unistd.h>

int req(int s, char *b, int n) {
   char h[] = "HTTP/1.1 200 OKrnContent-Type: text/htmlrnrn<html><style>h1 { font-family: arial; }</style><body><h1>Admin Module</h1><p>We got from you this http request:</p><pre>";
   char t[] = "</pre></body></html>";
   write(s,h,sizeof(h)-1);
   write(s,b,n);
   { char b[1024]; int n = read(s,b,0); while(n>0) { write(s,b,n); }}
   write(s,t,sizeof(t)-1);
}

There is a buffer overflow. I know.