<commit_before>/* Aranea
 * Copyright (c) 2011, <NAME>
 * See LICENSE file for copyright and license details.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "aranea.h"

static A_INLINE
int hex_to_int(const char c) {
    if (c >= '0' && c <= '9') {
        return c - '0';
    }
    if (c >= 'A' && c <= 'F') {
        return c - 'A' + 10;
    }
    if (c >= 'a' && c <= 'f') {
        return c - 'a' + 10;
    }
    return 0;
}

/**
 * Only get the first range if a list is given
 */
static
void http_parse_range(struct request_t *self, char *val) {
    char *delim;
    if (strncmp(val, "bytes ", 6) != 0) {
        A_ERR("ranges are not in bytes: %s", val);
        return;
    }
    val += 6;
    delim = strchr(val, '-');
    if (delim == NULL) {
        A_ERR("no hyphen: %s", val);
        return;
    }
    if (delim == val) {  /* range_from is not given */
        self->range_from = NULL;
    } else {
        self->range_from = val;
    }
    self->range_to = delim + 1;
}

static
void http_save_header(struct request_t *self, char *key, char *val) {
    if (strcasecmp(key, "Content-Type") == 0) {
        self->content_type = val;
    } else if (strcasecmp(key, "Content-Length") == 0) {
        self->content_length = val;
    } else if (strcasecmp(key, "Connection") == 0) {
        self->connection = val;
    } else if (strcasecmp(key, "Content-Range") == 0) {
        http_parse_range(self, val);
    } else if (strcasecmp(key, "If-Modified-Since") == 0) {
        self->if_mod_since = val;
    } else {
        A_LOG("header: %s %s", key, val);
    }
}

static
char *http_parse_querystring(char *url) {
    char *p;

    p = strchr(url, '?');
    if (p == NULL) {
        return NULL;
    }
    *p = '\0';
    return p + 1;
}

/** Parse the initial request line
 * Also modify data of client (padding NULL)
 * @return position of the last char parsed
 *         NULL on error
 */
static
char *http_parse_request(struct request_t *self, char *data, int len) {
    char *end;

    /* method */
    end = memchr(data, ' ', len);
    if (end == NULL) {
        A_ERR("no method %d: %.*s", len, len, data);
        return NULL;
    }
    *end = '\0';
    self->method = data;
    /* url */
    len -= end - data + 1;
    if (len <= 0) {
        A_ERR("no url %d", len);
        return NULL;
    }
    data = end + 1;
    end = memchr(data, ' ', len);
    if (end == NULL) {
        A_ERR("no url %d: %.*s", len, len, data);
        return NULL;
    }
    *end = '\0';
    self->url = data;
    /* query string in url */
    self->query_string = http_parse_querystring(self->url);
    /* version */
    len -= end - data + 1;
    if (len <= 0) {
        A_ERR("no version %d", len);
        return NULL;
    }
    data = end + 1;
    end = memchr(data, '\n', len);<commit_msg>The first char in url must be /<commit_after>/* Aranea
 * Copyright (c) 2011, <NAME>
 * See LICENSE file for copyright and license details.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "aranea.h"

static A_INLINE
int hex_to_int(const char c) {
    if (c >= '0' && c <= '9') {
        return c - '0';
    }
    if (c >= 'A' && c <= 'F') {
        return c - 'A' + 10;
    }
    if (c >= 'a' && c <= 'f') {
        return c - 'a' + 10;
    }
    return 0;
}

/**
 * Only get the first range if a list is given
 */
static
void http_parse_range(struct request_t *self, char *val) {
    char *delim;
    if (strncmp(val, "bytes ", 6) != 0) {
        A_ERR("ranges are not in bytes: %s", val);
        return;
    }
    val += 6;
    delim = strchr(val, '-');
    if (delim == NULL) {
        A_ERR("no hyphen: %s", val);
        return;
    }
    if (delim == val) {  /* range_from is not given */
        self->range_from = NULL;
    } else {
        self->range_from = val;
    }
    self->range_to = delim + 1;
}

static
void http_save_header(struct request_t *self, char *key, char *val) {
    if (strcasecmp(key, "Content-Type") == 0) {
        self->content_type = val;
    } else if (strcasecmp(key, "Content-Length") == 0) {
        self->content_length = val;
    } else if (strcasecmp(key, "Connection") == 0) {
        self->connection = val;
    } else if (strcasecmp(key, "Content-Range") == 0) {
        http_parse_range(self, val);
    } else if (strcasecmp(key, "If-Modified-Since") == 0) {
        self->if_mod_since = val;
    } else {
        A_LOG("header: %s %s", key, val);
    }
}

static
char *http_parse_querystring(char *url) {
    char *p;

    p = strchr(url, '?');
    if (p == NULL) {
        return NULL;
    }
    *p = '\0';
    return p + 1;
}

/** Parse the initial request line
 * Also modify data of client (padding NULL)
 * @return position of the last char parsed
 *         NULL on error
 */
static
char *http_parse_request(struct request_t *self, char *data, int len) {
    char *end;

    /* method */
    end = memchr(data, ' ', len);
    if (end == NULL) {
        A_ERR("no method %d: %.*s", len, len, data);
        return NULL;
    }
    *end = '\0';
    self->method = data;
    /* url */
    len -= end - data + 1;
    if (len <= 0) {
        A_ERR("no url %d", len);
        return NULL;
    }
    data = end + 1;
    if (*data != '/') {
        A_ERR("url does not start with / %.*s", len, data);
        return NULL;
    }
    end = memchr(data + 1, ' ', len);       /* already know the first char */
    if (end == NULL) {
        A_ERR("no url %d: %.*s", len, len, data);
        return NULL;
    }
    *end = '\0';
    self->url = data;
    /* query string in url */
    self->query_string = http_parse_querystring(self->url);
    /* version */
    len -= end - data + 1;
    if (len <= 0) {
        A_ERR("no version %d", len);
        return NULL;
    }
    data = end + 1;
    end = memchr(data, '\n', len);
{'fraction_non_alphanumeric': 0.17234880931985608, 'fraction_numerical': 0.010793215692992976, 'mean_word_length': 2.0437956204379564, 'pattern_counts': {'":': 0, '<': 23, '<?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': '3410108', 'n_tokens_mistral': 2176, 'n_tokens_neox': 2100, 'n_words': 624}