/* ** mod_random.c */ #include "httpd.h" #include "http_config.h" #include "http_protocol.h" #include "ap_config.h" typedef struct { int num_of_urls; array_header *urls; } random_conf; module MODULE_VAR_EXPORT random_module; static void *mkconfig(pool *p) { } /* The sample content handler */ static int random_handler(request_rec *r) { int token; random_conf *cfg = ap_get_module_config(r->per_dir_config, &random_module); char **members = (char**)cfg->urls->elts; token = (random() % cfg->num_of_urls); ap_table_setn(r->headers_out, "Location", members[token]); return HTTP_MOVED_TEMPORARILY; } /* Dispatch list of content handlers */ static const handler_rec random_handlers[] = { { "random", random_handler }, { NULL, NULL } }; static void *mconfig_for_directory(pool *p, char *dir) { random_conf *cfg = ap_pcalloc(p, sizeof(random_conf)); int timz; struct tm *t; cfg->urls = ap_make_array(p, 5, sizeof(char*)); cfg->num_of_urls = 0; t = ap_get_gmtoff(&timz); srandom(t->tm_sec); return (void *)cfg; } static const char * add_random_file (cmd_parms *cmd, void *mconfig, char *file) { FILE *file_ptr; char buf[1024]; random_conf *cfg = (random_conf *) mconfig; if (!(file_ptr = ap_pfopen(cmd->pool, file, "r"))) { printf("Could not open %s \n", file); exit(1); } while(fgets(buf, sizeof(buf),file_ptr)){ *(char **)ap_push_array(cfg->urls) = ap_pstrdup(cmd->pool, buf); cfg->num_of_urls++; } ap_pfclose(cmd->pool,file_ptr); return NULL; } static const char * add_random_url (cmd_parms *cmd, void *mconfig, char *url) { random_conf *cfg = (random_conf *) mconfig; *(char **)ap_push_array(cfg->urls) = ap_pstrdup(cmd->pool, url); cfg->num_of_urls++; return NULL; } static const command_rec random_module_cmds[] = { { "RandomFile", add_random_file, NULL, OR_ALL, TAKE1, "A filename with one URL per-line." }, { "RandomURL", add_random_url, NULL, OR_ALL, TAKE1, "A filename with one URL per-line." }, { NULL }, }; /* Dispatch list for API hooks */ module MODULE_VAR_EXPORT random_module = { STANDARD_MODULE_STUFF, NULL, /* module initializer */ mconfig_for_directory, /* create per-dir config structures */ NULL, /* merge per-dir config structures */ NULL, /* create per-server config structures */ NULL, /* merge per-server config structures */ random_module_cmds, /* table of config file commands */ random_handlers, /* [#8] MIME-typed-dispatched handlers */ NULL, /* [#1] URI to filename translation */ NULL, /* [#4] validate user id from request */ NULL, /* [#5] check if the user is ok _here_ */ NULL, /* [#3] check access by host address */ NULL, /* [#6] determine MIME type */ NULL, /* [#7] pre-run fixups */ NULL, /* [#9] log a transaction */ NULL, /* [#2] header parser */ NULL, /* child_init */ NULL, /* child_exit */ NULL /* [#0] post read-request */ };