<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>
#include <time.h>
#include <string.h>
#include <netdb.h>
#include <err.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/queue.h>

#include <dynamic.h>

#include "reactor_user.h"
#include "reactor_pool.h"
#include "reactor_core.h"
#include "reactor_timer.h"
#include "reactor_resolver.h"
#include "reactor_stream.h"
#include "reactor_tcp.h"
#include "reactor_http_parser.h"
#include "reactor_http.h"
#include "reactor_http_server.h"

static void reactor_http_server_map_release(void *data)
{
  reactor_http_server_map *map;

  map = data;
  free(map->method);
  free(map->path);
}

static void reactor_http_server_hold(reactor_http_server *server)
{
  server->ref ++;
}

static void reactor_http_server_release(reactor_http_server *server)
{
  server->ref --;
  if (!server->ref)
    {
      vector_destruct(&server->map);
      if (server->user.callback)
        reactor_user_dispatch(&server->user, REACTOR_HTTP_SERVER_EVENT_CLOSE, server);
    }
}

static void reactor_http_server_error(reactor_http_server *server)
{
  if (server->user.callback)
    reactor_user_dispatch(&server->user, REACTOR_HTTP_SERVER_EVENT_ERROR, server);
}

static void reactor_http_server_date(reactor_http_server *server)
{
  static const char *days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
  static const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  time_t t;
  struct tm tm;

  (void) time(&t);
  (void) gmtime_r(&t, &tm);
  (void) strftime(server->date, sizeof server->date, "---, %d --- %Y %H:%M:%S GMT", &tm);
  memcpy(server->date, days[tm.tm_wday], 3);
  memcpy(server->date + 8, months[tm.tm_mon], 3);
}

static void reactor_http_server_request(reactor_http_server_session *session, reactor_http_request *request)
{
  reactor_http_server_map *map;
  size_t i;

  map = vector_data(&session->server->map);
  for (i = 0; i < vector_size(&session->server->map); i ++)
    if ((!map[i].method || strcmp(map[i].method, request->method) == 0) &&
        (!map[i].path || strcmp(map[i].path, request->path) == 0))
      {
       reactor_user_dispatch(&map->user, REACTOR_HTTP_SERVER_EVENT_REQUEST,
                              (reactor_http_server_context[]){{.session = session, .request = request}});
        return;
      }
}

static void reactor_http_server_event_http(void *state, int type, void *data)
{
  reactor_http_server_session *session = state;
  reactor_http_request *request;<commit_msg>Allow multiple routes<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>
#include <time.h>
#include <string.h>
#include <netdb.h>
#include <err.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/queue.h>

#include <dynamic.h>

#include "reactor_user.h"
#include "reactor_pool.h"
#include "reactor_core.h"
#include "reactor_timer.h"
#include "reactor_resolver.h"
#include "reactor_stream.h"
#include "reactor_tcp.h"
#include "reactor_http_parser.h"
#include "reactor_http.h"
#include "reactor_http_server.h"

static void reactor_http_server_map_release(void *data)
{
  reactor_http_server_map *map;

  map = data;
  free(map->method);
  free(map->path);
}

static void reactor_http_server_hold(reactor_http_server *server)
{
  server->ref ++;
}

static void reactor_http_server_release(reactor_http_server *server)
{
  server->ref --;
  if (!server->ref)
    {
      vector_destruct(&server->map);
      if (server->user.callback)
        reactor_user_dispatch(&server->user, REACTOR_HTTP_SERVER_EVENT_CLOSE, server);
    }
}

static void reactor_http_server_error(reactor_http_server *server)
{
  if (server->user.callback)
    reactor_user_dispatch(&server->user, REACTOR_HTTP_SERVER_EVENT_ERROR, server);
}

static void reactor_http_server_date(reactor_http_server *server)
{
  static const char *days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
  static const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  time_t t;
  struct tm tm;

  (void) time(&t);
  (void) gmtime_r(&t, &tm);
  (void) strftime(server->date, sizeof server->date, "---, %d --- %Y %H:%M:%S GMT", &tm);
  memcpy(server->date, days[tm.tm_wday], 3);
  memcpy(server->date + 8, months[tm.tm_mon], 3);
}

static void reactor_http_server_request(reactor_http_server_session *session, reactor_http_request *request)
{
  reactor_http_server_map *map;
  size_t i;

  map = vector_data(&session->server->map);
  for (i = 0; i < vector_size(&session->server->map); i ++)
    if ((!map[i].method || strcmp(map[i].method, request->method) == 0) &&
        (!map[i].path || strcmp(map[i].path, request->path) == 0))
      {
        reactor_user_dispatch(&map[i].user, REACTOR_HTTP_SERVER_EVENT_REQUEST,
                              (reactor_http_server_context[]){{.session = session, .request = request}});
        return;
      }
}

static void reactor_http_server_event_http(void *state, int type, void *data)
{
  reactor_http_server_session *session = state;
  reactor_http_request *request;
{'fraction_non_alphanumeric': 0.16689020885227054, 'fraction_numerical': 0.0022992910519256562, 'mean_word_length': 4.774336283185841, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 72, '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': '6794928', 'n_tokens_mistral': 2003, 'n_tokens_neox': 1935, 'n_words': 379}