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.