#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_log.h"
#include "http_protocol.h"
#define MAX_COUNT 128
#define DEFAULT_ENCTYPE "application/x-www-form-urlencoded"
static int chunk_reader(request_rec *r, const char **rbuf)
{
int ret;
if(OK != (ret = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) {
return ret;
}
if(ap_should_client_block(r)) {
char argsbuffer[HUGE_STRING_LEN];
int rsize, len_read, rpos=0;
long length = r->remaining;
*rbuf = apr_pcalloc(r->pool, length + 1);
while(0 < (len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer)))) {
if ((rpos + len_read) > length) {
rsize = length - rpos;
}
else {
rsize = len_read;
}
memcpy((char*)*rbuf + rpos, argsbuffer, rsize);
rpos += rsize;
}
}
return ret;
}
static int read_post(request_rec *r, apr_table_t **tab)
{
const char *data;
const char *key, *val, *type;
int ret = OK;
if(r->method_number != M_POST) {
return ret;
}
type = apr_table_get(r->headers_in, "Content-Type");
if(strcasecmp(type, DEFAULT_ENCTYPE) != 0) {
return DECLINED;
}
if((ret = chunk_reader(r, &data)) != OK) {
return ret;
}
if(*tab) {
apr_table_clear(*tab);
}
else {
*tab = apr_table_make(r->pool, 8);
}
while(*data && (val = ap_getword(r->pool, &data, '&'))) {
key = ap_getword(r->pool, &val, '=');
ap_unescape_url((char*)key);
ap_unescape_url((char*)val);
apr_table_merge(*tab, key, val);
}
return OK;
}
int get_value(request_rec *r, const char *name)
{
apr_table_t *post_values = NULL;
apr_array_header_t *arr;
apr_table_entry_t *elt;
int i, ret, value;
if(OK != (ret = read_post(r, &post_values))) {
return -1;
}
if(NULL == post_values) {
return -1;
}
arr = apr_table_elts(post_values);
elt = (apr_table_entry_t*)arr->elts;
for(i = 0; i < arr->nelts; ++i) {
if(strcmp(elt[i].key, name) == 0
&& LONG_MIN != (value = strtol(elt[i].val, NULL, 10))) {
return value;
}
}
return -1;
}
static int mod_randomint_method_handler (request_rec *r)
{
int ret = OK, i, count = 8, new_count;
unsigned int random_value;
if(strcmp(r->handler, "randomint-handler")) {
return DECLINED;
}
new_count = get_value(r, "count");
if(new_count > 0 && new_count < MAX_COUNT) {
count = new_count;
}
ap_set_content_type(r, "text/plain");
int random_fd = open("/dev/urandom", O_RDONLY);
for(i = 0; i < count; i ++) {
read(random_fd, (void*)&random_value, sizeof(random_value));
ap_rprintf(r, "%u\n", random_value);
}
close(random_fd);
// fprintf(stderr, "Count: %d\n", count);
// fflush(stderr);
return ret;
}
static void mod_randomint_register_hooks (apr_pool_t *p)
{
ap_hook_handler(mod_randomint_method_handler, NULL, NULL,APR_HOOK_LAST);
}
module AP_MODULE_DECLARE_DATA randomint_module =
{
STANDARD20_MODULE_STUFF,
NULL,
NULL,
NULL,
NULL,
NULL,
mod_randomint_register_hooks, /* callback for registering hooks */
};