<commit_before>#include "uvbserver.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <event2/buffer.h>

/**
 * Get the number of tokens created using strtok on a string
 */


uint64_t ntok(char* str, const char* delim) {
    //XXX(rossdylan) I'm really tired, there is probably a better way to this
    size_t size = strlen(str)+1;
    char* copied;
    if((copied = calloc(size, sizeof(char))) == NULL) {
        perror("calloc: ntok");
        exit(EXIT_FAILURE);
    }
    memmove(copied, str,  sizeof(char) * size);

    uint64_t num = 0;
    char* token = strtok(copied, delim);
    while(token != NULL) { 
        if(UINT64_MAX - 1 < num) {
            fprintf(stderr, "Some one tried to overflow tokenizer\n");
            num = 0;
            break;
        }
        num++;
        token = strtok(NULL, delim);
    }
    free(copied);
    copied = NULL;
    return num;
}

/**
 * Make an array of strings holding all tokens in a string
 */
char** split(char* str, const char* delim, uint64_t n) {
    //XXX(rossdylan) I'm really tired, there is probably a better way to this
    size_t size = strlen(str)+1;
    char* copied;
    if((copied = calloc(size, sizeof(char))) == NULL) {
        perror("calloc: ntok");
        exit(EXIT_FAILURE);
    }
    memmove(copied, str,  sizeof(char) * size);

    char** tokens;
    if((tokens = calloc(n, sizeof(char*))) == NULL) {
        perror("calloc: split");
        exit(EXIT_FAILURE);
    }
    char* token = strtok(copied, delim);
    int index = 0;
    while(token != NULL) {
        size_t tsize = (strlen(token) + 1);
        if((tokens[index] = calloc(tsize, sizeof(char))) == NULL) {
            perror("calloc: split: token");
            exit(EXIT_FAILURE);
        }
        memmove(tokens[index], token, tsize);
        index++;
        token = strtok(NULL, delim);
    }
    free(copied);
    copied = NULL;
    return tokens;
}

/**
 * Free an array of strings of the given size
 */
void free_split(char** s, uint64_t size) {
    for(uint64_t i=0; i<size; i++) {
        free(s[i]);
        s[i] = NULL;
    }
    free(s);
    s = NULL;
}

/**
 * Take a freshly allocated UVBServer struct and fill it up and set all the values to their defaults
 * This includes:
 *  making the evhttp struct
 *  setting the default route handler to uvb_unknown_route
 *  tell evhttp where to listen
 */
void new_uvbserver(UVBServer* serv, struct event_base* base, char* addr, uint16_t port, CounterDB* db) {
    serv->database = db;
    serv->http = evhttp_new(base);
    evhttp_set_cb(serv->http, "/", uvb_route_display, serv->database);
    evhttp_set_gencb(serv->http, uvb_route_dispatch, serv->database);
    serv->handle = evhttp_bind_socket_with_handle(serv->http, addr, port);
    struct timeval rps_timer = {1, 0};
    struct event* rpsevent = event_new(base, -1, EV_PERSIST, calculate_rps, db);
    event_add(rpsevent, &rps_timer);
    if(!serv->handle) {
        exit(EXIT_FAILURE);
    }
}


/**
 * Free all the evhttp structs contained within UVBServer and then free the UVBServer struct
 */
void free_uvbserver(UVBServer* serv) {
    free(serv->handle);
    serv->handle = NULL;
    free(serv->http);
    serv->http = NULL;
    free(serv->addr);
    serv->addr = NULL;
    free(serv);
    serv = NULL;
}


void uvb_route_dispatch(struct evhttp_request* req, void* arg) {
    CounterDB* db = (CounterDB* )arg;
    enum evhttp_cmd_type cmdtype = evhttp_request_get_command(req);
    if(cmdtype == EVHTTP_REQ_POST) {
        const char* strURI = evhttp_request_get_uri(req);
        struct evhttp_uri* uri;
        if((uri = evhttp_uri_parse(strURI)) == NULL) {
            evhttp_send_reply(req, 500, "Bad URI", NULL);
            return;
        }
        char* path = (char* )evhttp_uri_get_path(uri);
        uint64_t nsegs = ntok(path, "/");
        //given a weird address or ntok was overflowed
        if(nsegs == 0) {
            evhttp_send_reply(req, 500, "Internal Server Error", NULL);
            evhttp_uri_free(uri);
            uri = NULL;
            return;
        }<commit_msg>fixed the uri decoding patch, need to decode after I parse the uri<commit_after>#include "uvbserver.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <event2/buffer.h>

/**
 * Get the number of tokens created using strtok on a string
 */


uint64_t ntok(char* str, const char* delim) {
    //XXX(rossdylan) I'm really tired, there is probably a better way to this
    size_t size = strlen(str)+1;
    char* copied;
    if((copied = calloc(size, sizeof(char))) == NULL) {
        perror("calloc: ntok");
        exit(EXIT_FAILURE);
    }
    memmove(copied, str,  sizeof(char) * size);

    uint64_t num = 0;
    char* token = strtok(copied, delim);
    while(token != NULL) { 
        if(UINT64_MAX - 1 < num) {
            fprintf(stderr, "Some one tried to overflow tokenizer\n");
            num = 0;
            break;
        }
        num++;
        token = strtok(NULL, delim);
    }
    free(copied);
    copied = NULL;
    return num;
}

/**
 * Make an array of strings holding all tokens in a string
 */
char** split(char* str, const char* delim, uint64_t n) {
    //XXX(rossdylan) I'm really tired, there is probably a better way to this
    size_t size = strlen(str)+1;
    char* copied;
    if((copied = calloc(size, sizeof(char))) == NULL) {
        perror("calloc: ntok");
        exit(EXIT_FAILURE);
    }
    memmove(copied, str,  sizeof(char) * size);

    char** tokens;
    if((tokens = calloc(n, sizeof(char*))) == NULL) {
        perror("calloc: split");
        exit(EXIT_FAILURE);
    }
    char* token = strtok(copied, delim);
    int index = 0;
    while(token != NULL) {
        size_t tsize = (strlen(token) + 1);
        if((tokens[index] = calloc(tsize, sizeof(char))) == NULL) {
            perror("calloc: split: token");
            exit(EXIT_FAILURE);
        }
        memmove(tokens[index], token, tsize);
        index++;
        token = strtok(NULL, delim);
    }
    free(copied);
    copied = NULL;
    return tokens;
}

/**
 * Free an array of strings of the given size
 */
void free_split(char** s, uint64_t size) {
    for(uint64_t i=0; i<size; i++) {
        free(s[i]);
        s[i] = NULL;
    }
    free(s);
    s = NULL;
}

/**
 * Take a freshly allocated UVBServer struct and fill it up and set all the values to their defaults
 * This includes:
 *  making the evhttp struct
 *  setting the default route handler to uvb_unknown_route
 *  tell evhttp where to listen
 */
void new_uvbserver(UVBServer* serv, struct event_base* base, char* addr, uint16_t port, CounterDB* db) {
    serv->database = db;
    serv->http = evhttp_new(base);
    evhttp_set_cb(serv->http, "/", uvb_route_display, serv->database);
    evhttp_set_gencb(serv->http, uvb_route_dispatch, serv->database);
    serv->handle = evhttp_bind_socket_with_handle(serv->http, addr, port);
    struct timeval rps_timer = {1, 0};
    struct event* rpsevent = event_new(base, -1, EV_PERSIST, calculate_rps, db);
    event_add(rpsevent, &rps_timer);
    if(!serv->handle) {
        exit(EXIT_FAILURE);
    }
}


/**
 * Free all the evhttp structs contained within UVBServer and then free the UVBServer struct
 */
void free_uvbserver(UVBServer* serv) {
    free(serv->handle);
    serv->handle = NULL;
    free(serv->http);
    serv->http = NULL;
    free(serv->addr);
    serv->addr = NULL;
    free(serv);
    serv = NULL;
}


void uvb_route_dispatch(struct evhttp_request* req, void* arg) {
    CounterDB* db = (CounterDB* )arg;
    enum evhttp_cmd_type cmdtype = evhttp_request_get_command(req);
    if(cmdtype == EVHTTP_REQ_POST) {
        const char* strURI = evhttp_request_get_uri(req);
        struct evhttp_uri* uri;
        if((uri = evhttp_uri_parse(strURI)) == NULL) {
            evhttp_send_reply(req, 500, "Bad URI", NULL);
            return;
        }
        char* path = evhttp_decode_uri((char* )evhttp_uri_get_path(uri));
        uint64_t nsegs = ntok(path, "/");
        //given a weird address or ntok was overflowed
        if(nsegs == 0) {
            evhttp_send_reply(req, 500, "Internal Server Error", NULL);
            evhttp_uri_free(uri);
            uri = NULL;
            return;
        }
{'fraction_non_alphanumeric': 0.13180272108843538, 'fraction_numerical': 0.008503401360544218, 'mean_word_length': 2.6738063364569387, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2830672', 'n_tokens_mistral': 2837, 'n_tokens_neox': 2772, 'n_words': 744}