#include #include #include #include #include #include #include #include #include #include #include #include "http.h" #include "memory.h" #include "plugin.h" #include "util.h" #define PORT 8080 static int num_threads=0; static pthread_mutex_t num_threads_mutex; typedef struct Plugin{ char *name; Handler handler; struct Plugin *next; } Plugin; // Will only be read once threading starts, so no mutex needed static Plugin *pluginlist=NULL,*pluginlist_last=NULL; static void plugin_register_callback(const char *name,Handler handler){ if(pluginlist==NULL){ pluginlist=pluginlist_last=malloc(1,Plugin); pluginlist->name=copy_str(name); pluginlist->handler=handler; pluginlist->next=NULL; } else { Plugin *newplugin=malloc(1,Plugin); newplugin->name=copy_str(name); newplugin->handler=handler; newplugin->next=NULL; pluginlist_last->next=newplugin; pluginlist_last=newplugin; } printf("Registered plugin '%s' (handler %p)\n",name,handler); } typedef void (*register_function)(register_callback_t callback); static void load_plugin(const char *name){ void *lib=dlopen(name,RTLD_NOW|RTLD_LOCAL); if(lib==NULL){ fprintf(stderr,"dlopen(%s): %s\n",name,dlerror()); exit(1); } register_function regfunc=(register_function)dlsym(lib,"plugin_register_yourself"); if(regfunc==NULL){ fprintf(stderr,"Cannot find plugin_register_yourself symbol in library '%s'\n",name); exit(1); } regfunc(&plugin_register_callback); } static void* thread_entry_connection_handler(void *sock_){ int sock=(int)(uintptr_t)sock_; Headers *headers=http_get_headers(sock); if(headers==NULL){ goto cleanup_exit; } for(Plugin *pl=pluginlist;pl!=NULL;pl=pl->next){ switch(pl->handler(sock,headers)){ case HR_HANDLED: printf("Request handled by %s\n",pl->name); break; case HR_NEXT: continue; case HR_ERROR: printf("Request handler '%s' threw error\n",pl->name); break; } break; } cleanup_exit: close(sock); PTHREAD_CHECK(pthread_mutex_lock,&num_threads_mutex); num_threads--; PTHREAD_CHECK(pthread_mutex_unlock,&num_threads_mutex); return NULL; } int main(int argc,char **argv){ if(argc==1){ printf("Loading no plugin files\n"); } else { for(int i=1;isin_addr, str,sizeof(str)); printf("Accept from %s; %d thread%s still left\n",str,num_threads,num_threads==1?"":"s"); PTHREAD_CHECK(pthread_mutex_lock,&num_threads_mutex); num_threads++; PTHREAD_CHECK(pthread_mutex_unlock,&num_threads_mutex); pthread_t th; PTHREAD_CHECK(pthread_create,&th,NULL,thread_entry_connection_handler,(void*)(uintptr_t)clientsock); PTHREAD_CHECK(pthread_detach,th); } }