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
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.