annotate hg-web/main.c @ 222:a8d6435dc021 hg-web

[hg-web] Run local stack through Bazel
author MrJuneJune <me@mrjunejune.com>
date Sun, 02 Aug 2026 09:07:36 -0700
parents ce7f4400c2de
children 0e7b9464248d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
1 #include "seobeo/seobeo.h"
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
2 #include "dowa/dowa.h"
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
3
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
4 #include <ctype.h>
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
5 #include <errno.h>
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
6 #include <stdio.h>
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
7 #include <stdlib.h>
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
8 #include <string.h>
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
9 #include <strings.h>
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
10 #include <time.h>
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
11 #include <unistd.h>
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
12
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
13 #define HG_SERVE_HOST "127.0.0.1"
147
6de849867459 [HgWeb] Updated logic to use Seobeo Client.
June Park <parkjune1995@gmail.com>
parents: 135
diff changeset
14 #define HG_SERVE_PORT "4444"
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
15 #define HG_API_TIMEOUT_MS 15000
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
16 #define HG_STREAM_IDLE_TIMEOUT_MS 60000
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
17 #define MAX_PATH_LENGTH 4096
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
18 #define MAX_WIRE_QUERY_LENGTH 8192
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
19 #define MAX_WIRE_HEADER_LENGTH 8192
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
20
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
21 static const char *map_value_case_insensitive(Seobeo_Request_Entry *map, const char *key)
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
22 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
23 if (!map || !key)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
24 return NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
25
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
26 for (size_t i = 0; i < Dowa_Array_Length(map); i++)
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
27 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
28 if (map[i].key && strcasecmp(map[i].key, key) == 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
29 return map[i].value;
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
30 }
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
31 return NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
32 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
33
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
34 static char *arena_string(Dowa_Arena *arena, const char *value)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
35 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
36 size_t length = strlen(value);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
37 char *copy = Dowa_Arena_Allocate(arena, length + 1);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
38 memcpy(copy, value, length + 1);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
39 return copy;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
40 }
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
41
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
42 static Seobeo_Request_Entry *text_response(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
43 Dowa_Arena *arena,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
44 const char *status,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
45 const char *content_type,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
46 const char *body)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
47 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
48 Seobeo_Request_Entry *response = NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
49 Dowa_HashMap_Push_Arena(response, "status", arena_string(arena, status), arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
50 Dowa_HashMap_Push_Arena(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
51 response, "content-type", arena_string(arena, content_type), arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
52 Dowa_HashMap_Push_Arena(response, "body", arena_string(arena, body), arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
53 return response;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
54 }
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
55
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
56 static boolean decode_url_component(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
57 const char *encoded,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
58 Dowa_Arena *arena,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
59 char **decoded_out,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
60 size_t *decoded_length_out)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
61 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
62 if (!encoded || !decoded_out)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
63 return FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
64
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
65 size_t encoded_length = strlen(encoded);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
66 if (encoded_length >= MAX_PATH_LENGTH)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
67 return FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
68
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
69 char *decoded = Dowa_Arena_Allocate(arena, encoded_length + 1);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
70 size_t output_length = 0;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
71 for (size_t i = 0; i < encoded_length; i++)
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
72 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
73 unsigned char value = (unsigned char)encoded[i];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
74 if (encoded[i] == '%')
188
32ce881452fa Fixing few stuff.
MrJuneJune <me@mrjunejune.com>
parents: 175
diff changeset
75 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
76 if (i + 2 >= encoded_length ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
77 !isxdigit((unsigned char)encoded[i + 1]) ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
78 !isxdigit((unsigned char)encoded[i + 2]))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
79 return FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
80
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
81 char hex[3] = {encoded[i + 1], encoded[i + 2], '\0'};
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
82 value = (unsigned char)strtoul(hex, NULL, 16);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
83 i += 2;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
84 if (value == '\0')
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
85 return FALSE;
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
86 }
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
87 decoded[output_length++] = (char)value;
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
88 }
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
89 decoded[output_length] = '\0';
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
90
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
91 *decoded_out = decoded;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
92 if (decoded_length_out)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
93 *decoded_length_out = output_length;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
94 return TRUE;
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
95 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
96
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
97 static boolean normalize_repository_path(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
98 const char *encoded_path,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
99 Dowa_Arena *arena,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
100 char **normalized_out)
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
101 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
102 char *decoded = NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
103 size_t decoded_length = 0;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
104 if (!decode_url_component(encoded_path ? encoded_path : "", arena, &decoded, &decoded_length))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
105 return FALSE;
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
106
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
107 size_t start = 0;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
108 size_t end = decoded_length;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
109 if (start < end && decoded[start] == '/')
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
110 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
111 start++;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
112 if (start < end && decoded[start] == '/')
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
113 return FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
114 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
115 if (end > start && decoded[end - 1] == '/')
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
116 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
117 if (end - 1 > start && decoded[end - 2] == '/')
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
118 return FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
119 end--;
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
120 }
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
121
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
122 size_t segment_start = start;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
123 for (size_t i = start; i <= end; i++)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
124 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
125 boolean at_end = i == end;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
126 unsigned char c = at_end ? '/' : (unsigned char)decoded[i];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
127 if (!at_end && (iscntrl(c) || c == '\\' || c == '?' || c == '#'))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
128 return FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
129
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
130 if (c == '/')
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
131 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
132 size_t segment_length = i - segment_start;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
133 if (segment_length == 0 && !at_end)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
134 return FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
135 if ((segment_length == 1 && decoded[segment_start] == '.') ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
136 (segment_length == 2 && decoded[segment_start] == '.' &&
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
137 decoded[segment_start + 1] == '.'))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
138 return FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
139 segment_start = i + 1;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
140 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
141 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
142
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
143 size_t normalized_length = end - start;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
144 char *normalized = Dowa_Arena_Allocate(arena, normalized_length + 1);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
145 memcpy(normalized, decoded + start, normalized_length);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
146 normalized[normalized_length] = '\0';
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
147 *normalized_out = normalized;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
148 return TRUE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
149 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
150
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
151 static boolean validate_revision(const char *revision)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
152 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
153 if (!revision || revision[0] == '\0')
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
154 return FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
155 if (strcmp(revision, "tip") == 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
156 return TRUE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
157
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
158 size_t length = strlen(revision);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
159 if (length > 40)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
160 return FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
161 for (size_t i = 0; i < length; i++)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
162 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
163 if (!isxdigit((unsigned char)revision[i]))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
164 return FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
165 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
166 return TRUE;
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
167 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
168
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
169 static char *encode_repository_path(const char *path, Dowa_Arena *arena)
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
170 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
171 static const char hex[] = "0123456789ABCDEF";
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
172 size_t length = strlen(path);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
173 char *encoded = Dowa_Arena_Allocate(arena, length * 3 + 1);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
174 size_t output = 0;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
175 for (size_t i = 0; i < length; i++)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
176 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
177 unsigned char c = (unsigned char)path[i];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
178 if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~' || c == '/')
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
179 encoded[output++] = (char)c;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
180 else
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
181 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
182 encoded[output++] = '%';
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
183 encoded[output++] = hex[c >> 4];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
184 encoded[output++] = hex[c & 0x0F];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
185 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
186 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
187 encoded[output] = '\0';
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
188 return encoded;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
189 }
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
190
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
191 static boolean safe_header_value(const char *value, size_t maximum_length)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
192 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
193 if (!value)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
194 return TRUE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
195 size_t length = strlen(value);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
196 return length <= maximum_length &&
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
197 strchr(value, '\r') == NULL &&
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
198 strchr(value, '\n') == NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
199 }
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
200
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
201 static Seobeo_Client_Response *hg_proxy_request(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
202 const char *method,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
203 const char *path,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
204 const char *request_body,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
205 size_t request_body_length,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
206 const char *hg_argument,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
207 const char *accept)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
208 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
209 char url[MAX_PATH_LENGTH];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
210 int url_length = snprintf(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
211 url, sizeof(url), "http://%s:%s%s", HG_SERVE_HOST, HG_SERVE_PORT, path);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
212 if (url_length < 0 || (size_t)url_length >= sizeof(url))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
213 return NULL;
106
daf2d393741a Debugging in server.
June Park <parkjune1995@gmail.com>
parents: 104
diff changeset
214
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
215 Seobeo_Client_Request *request = Seobeo_Client_Request_Create(url);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
216 if (!request)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
217 return NULL;
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
218
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
219 Seobeo_Client_Request_Set_Method(request, method);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
220 Seobeo_Client_Request_Add_Header_Map(request, "User-Agent", "Seobeo/1.0");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
221 Seobeo_Client_Request_Add_Header_Map(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
222 request, "Accept", accept ? accept : "application/json");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
223 Seobeo_Client_Request_Set_Timeout_Milliseconds(request, HG_API_TIMEOUT_MS);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
224
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
225 if (hg_argument && hg_argument[0] != '\0')
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
226 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
227 if (!safe_header_value(hg_argument, MAX_WIRE_HEADER_LENGTH))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
228 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
229 Seobeo_Client_Request_Destroy(request);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
230 return NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
231 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
232 Seobeo_Client_Request_Add_Header_Map(request, "x-hgarg-1", hg_argument);
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
233 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
234
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
235 if (request_body && request_body_length > 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
236 Seobeo_Client_Request_Set_Body(request, request_body, request_body_length);
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
237
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
238 Seobeo_Client_Response *response = Seobeo_Client_Request_Execute(request);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
239 Seobeo_Client_Request_Destroy(request);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
240 return response;
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
241 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
242
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
243 static Seobeo_Request_Entry *forward_hg_response(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
244 Seobeo_Client_Response *hg_response,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
245 const char *default_content_type,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
246 Dowa_Arena *arena)
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
247 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
248 if (!hg_response)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
249 return text_response(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
250 arena, "502", "application/json", "{\"error\":\"Mercurial backend unavailable\"}");
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
251
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
252 const char *upstream_content_type =
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
253 map_value_case_insensitive(hg_response->headers, "Content-Type");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
254 const char *upstream_or_default_content_type =
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
255 upstream_content_type ? upstream_content_type : default_content_type;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
256 if (!upstream_or_default_content_type)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
257 upstream_or_default_content_type = "application/octet-stream";
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
258 char *content_type = arena_string(arena, upstream_or_default_content_type);
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
259
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
260 char *status = Dowa_Arena_Allocate(arena, 8);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
261 snprintf(status, 8, "%d", hg_response->status_code);
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
262
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
263 size_t body_length = hg_response->body ? hg_response->body_length : 0;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
264 char *body = Dowa_Arena_Allocate(arena, body_length + 1);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
265 if (body_length > 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
266 memcpy(body, hg_response->body, body_length);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
267 body[body_length] = '\0';
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
268 char *content_length = Dowa_Arena_Allocate(arena, 32);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
269 snprintf(content_length, 32, "%zu", body_length);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
270
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
271 Seobeo_Request_Entry *response = NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
272 Dowa_HashMap_Push_Arena(response, "status", status, arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
273 Dowa_HashMap_Push_Arena(response, "content-type", content_type, arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
274 Dowa_HashMap_Push_Arena(response, "body", body, arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
275 Dowa_HashMap_Push_Arena(response, "content-length", content_length, arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
276 Seobeo_Client_Response_Destroy(hg_response);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
277 return response;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
278 }
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
279
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
280 Seobeo_Request_Entry *ApiListDirectory(Seobeo_Request_Entry *request, Dowa_Arena *arena)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
281 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
282 const char *encoded_path = map_value_case_insensitive(request, "query_path");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
283 char *path = NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
284 if (!normalize_repository_path(encoded_path ? encoded_path : "", arena, &path))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
285 return text_response(arena, "400", "application/json", "{\"error\":\"Invalid repository path\"}");
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
286
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
287 char *encoded = encode_repository_path(path, arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
288 char hg_path[MAX_PATH_LENGTH];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
289 int length = snprintf(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
290 hg_path,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
291 sizeof(hg_path),
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
292 encoded[0] ? "/file/tip/%s?style=json" : "/file/tip/?style=json",
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
293 encoded);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
294 if (length < 0 || (size_t)length >= sizeof(hg_path))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
295 return text_response(arena, "400", "application/json", "{\"error\":\"Repository path is too long\"}");
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
296
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
297 return forward_hg_response(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
298 hg_proxy_request("GET", hg_path, NULL, 0, NULL, "application/json"),
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
299 "application/json",
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
300 arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
301 }
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
302
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
303 Seobeo_Request_Entry *ApiGetFile(Seobeo_Request_Entry *request, Dowa_Arena *arena)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
304 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
305 const char *encoded_path = map_value_case_insensitive(request, "query_path");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
306 char *path = NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
307 if (!normalize_repository_path(encoded_path ? encoded_path : "", arena, &path) ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
308 path[0] == '\0')
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
309 return text_response(arena, "400", "text/plain", "A valid file path is required");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
310
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
311 char *encoded = encode_repository_path(path, arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
312 char hg_path[MAX_PATH_LENGTH];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
313 int length = snprintf(hg_path, sizeof(hg_path), "/raw-file/tip/%s", encoded);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
314 if (length < 0 || (size_t)length >= sizeof(hg_path))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
315 return text_response(arena, "400", "text/plain", "File path is too long");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
316
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
317 return forward_hg_response(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
318 hg_proxy_request("GET", hg_path, NULL, 0, NULL, "application/octet-stream"),
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
319 "application/octet-stream",
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
320 arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
321 }
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
322
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
323 Seobeo_Request_Entry *ApiGetReadme(Seobeo_Request_Entry *request, Dowa_Arena *arena)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
324 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
325 const char *encoded_path = map_value_case_insensitive(request, "query_path");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
326 char *directory = NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
327 if (!normalize_repository_path(encoded_path ? encoded_path : "", arena, &directory))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
328 return text_response(arena, "400", "text/plain", "Invalid repository path");
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
329
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
330 size_t readme_length = strlen(directory) + strlen("/README.md") + 1;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
331 if (readme_length >= MAX_PATH_LENGTH)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
332 return text_response(arena, "400", "text/plain", "README path is too long");
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
333
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
334 char *readme_path = Dowa_Arena_Allocate(arena, readme_length);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
335 snprintf(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
336 readme_path,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
337 readme_length,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
338 directory[0] ? "%s/README.md" : "README.md",
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
339 directory);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
340 char *encoded = encode_repository_path(readme_path, arena);
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
341
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
342 char hg_path[MAX_PATH_LENGTH];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
343 int length = snprintf(hg_path, sizeof(hg_path), "/raw-file/tip/%s", encoded);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
344 if (length < 0 || (size_t)length >= sizeof(hg_path))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
345 return text_response(arena, "400", "text/plain", "README path is too long");
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
346
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
347 return forward_hg_response(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
348 hg_proxy_request("GET", hg_path, NULL, 0, NULL, "text/markdown"),
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
349 "text/markdown",
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
350 arena);
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
351 }
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
352
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
353 Seobeo_Request_Entry *ApiGetGraph(Seobeo_Request_Entry *request, Dowa_Arena *arena)
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
354 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
355 const char *graph_id = map_value_case_insensitive(request, ":graph_id");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
356 if (!validate_revision(graph_id))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
357 return text_response(arena, "400", "application/json", "{\"error\":\"Invalid graph revision\"}");
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
358
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
359 const char *encoded_graph_top =
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
360 map_value_case_insensitive(request, "query_graphtop");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
361 char *graph_top = NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
362 if (encoded_graph_top)
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
363 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
364 if (!decode_url_component(encoded_graph_top, arena, &graph_top, NULL) ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
365 !validate_revision(graph_top))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
366 return text_response(arena, "400", "application/json", "{\"error\":\"Invalid graph top revision\"}");
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
367 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
368
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
369 char hg_path[MAX_PATH_LENGTH];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
370 int length = graph_top
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
371 ? snprintf(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
372 hg_path,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
373 sizeof(hg_path),
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
374 "/graph/%s?graphtop=%s&style=json",
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
375 graph_id,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
376 graph_top)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
377 : snprintf(hg_path, sizeof(hg_path), "/graph/%s?style=json", graph_id);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
378 if (length < 0 || (size_t)length >= sizeof(hg_path))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
379 return text_response(arena, "400", "application/json", "{\"error\":\"Graph request is too long\"}");
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
380
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
381 return forward_hg_response(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
382 hg_proxy_request("GET", hg_path, NULL, 0, NULL, "application/json"),
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
383 "application/json",
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
384 arena);
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
385 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
386
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
387 Seobeo_Request_Entry *ApiGetChangeset(Seobeo_Request_Entry *request, Dowa_Arena *arena)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
388 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
389 const char *changeset_id = map_value_case_insensitive(request, ":changeset_id");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
390 if (!validate_revision(changeset_id))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
391 return text_response(arena, "400", "application/json", "{\"error\":\"Invalid changeset revision\"}");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
392
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
393 char hg_path[128];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
394 int length = snprintf(hg_path, sizeof(hg_path), "/json-rev/%s", changeset_id);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
395 if (length < 0 || (size_t)length >= sizeof(hg_path))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
396 return text_response(arena, "400", "application/json", "{\"error\":\"Changeset request is too long\"}");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
397
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
398 return forward_hg_response(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
399 hg_proxy_request("GET", hg_path, NULL, 0, NULL, "application/json"),
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
400 "application/json",
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
401 arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
402 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
403
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
404 static int64_t monotonic_milliseconds(void)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
405 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
406 struct timespec now;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
407 clock_gettime(CLOCK_MONOTONIC, &now);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
408 return (int64_t)now.tv_sec * 1000 + now.tv_nsec / 1000000;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
409 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
410
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
411 static size_t find_http_header_length(const uint8 *buffer, size_t length)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
412 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
413 if (!buffer || length < 4)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
414 return 0;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
415 for (size_t i = 0; i + 3 < length; i++)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
416 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
417 if (buffer[i] == '\r' && buffer[i + 1] == '\n' &&
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
418 buffer[i + 2] == '\r' && buffer[i + 3] == '\n')
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
419 return i + 4;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
420 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
421 return 0;
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
422 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
423
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
424 static void send_proxy_error(Seobeo_Handle *client, int status, const char *message)
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
425 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
426 const char *reason = status == 504 ? "Gateway Timeout" : "Bad Gateway";
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
427 char response[512];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
428 int length = snprintf(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
429 response,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
430 sizeof(response),
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
431 "HTTP/1.1 %d %s\r\n"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
432 "Content-Type: text/plain\r\n"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
433 "Content-Length: %zu\r\n"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
434 "Connection: close\r\n"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
435 "\r\n"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
436 "%s",
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
437 status,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
438 reason,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
439 strlen(message),
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
440 message);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
441 if (length > 0 && (size_t)length < sizeof(response))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
442 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
443 Seobeo_Handle_Queue(client, (const uint8 *)response, (uint32)length);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
444 Seobeo_Handle_Flush(client);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
445 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
446 }
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
447
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
448 static boolean parse_content_length(const char *value, size_t *length_out)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
449 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
450 if (!value || !length_out || value[0] == '\0')
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
451 return FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
452 errno = 0;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
453 char *end = NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
454 unsigned long long parsed = strtoull(value, &end, 10);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
455 if (errno != 0 || !end || *end != '\0' || parsed > SIZE_MAX)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
456 return FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
457 *length_out = (size_t)parsed;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
458 return TRUE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
459 }
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
460
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
461 void StreamHgWireProtocol(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
462 Seobeo_Handle *client,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
463 Seobeo_Request_Entry *request,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
464 Dowa_Arena *arena)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
465 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
466 (void)arena;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
467 const char *method = map_value_case_insensitive(request, "HTTP_Method");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
468 const char *query = map_value_case_insensitive(request, "QueryString");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
469 const char *body = map_value_case_insensitive(request, "Body");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
470 const char *content_length_value =
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
471 map_value_case_insensitive(request, "Content-Length");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
472 const char *content_type = map_value_case_insensitive(request, "Content-Type");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
473 const char *hg_argument = map_value_case_insensitive(request, "x-hgarg-1");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
474
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
475 if (!method || !query ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
476 (strcmp(method, "GET") != 0 && strcmp(method, "POST") != 0) ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
477 !safe_header_value(query, MAX_WIRE_QUERY_LENGTH) ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
478 !safe_header_value(hg_argument, MAX_WIRE_HEADER_LENGTH) ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
479 !safe_header_value(content_type, 256))
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
480 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
481 send_proxy_error(client, 502, "Invalid Mercurial proxy request");
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
482 return;
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
483 }
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
484
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
485 size_t body_length = 0;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
486 if (content_length_value &&
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
487 !parse_content_length(content_length_value, &body_length))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
488 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
489 send_proxy_error(client, 502, "Invalid Mercurial request length");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
490 return;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
491 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
492 if (body_length > 0 && !body)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
493 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
494 send_proxy_error(client, 502, "Missing Mercurial request body");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
495 return;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
496 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
497 if (body_length > UINT32_MAX)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
498 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
499 send_proxy_error(client, 502, "Mercurial request body is too large");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
500 return;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
501 }
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
502
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
503 Seobeo_Handle *upstream =
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
504 Seobeo_Stream_Handle_Client_Create(HG_SERVE_HOST, HG_SERVE_PORT, FALSE);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
505 if (!upstream || upstream->socket < 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
506 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
507 if (upstream)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
508 Seobeo_Handle_Destroy(upstream);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
509 send_proxy_error(client, 502, "Mercurial backend unavailable");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
510 return;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
511 }
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
512
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
513 char request_header[16384];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
514 int header_length = snprintf(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
515 request_header,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
516 sizeof(request_header),
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
517 "%s /?%s HTTP/1.1\r\n"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
518 "Host: %s:%s\r\n"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
519 "User-Agent: Seobeo/1.0\r\n"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
520 "Connection: close\r\n",
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
521 method,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
522 query,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
523 HG_SERVE_HOST,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
524 HG_SERVE_PORT);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
525 if (header_length < 0 || (size_t)header_length >= sizeof(request_header))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
526 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
527 Seobeo_Handle_Destroy(upstream);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
528 send_proxy_error(client, 502, "Mercurial request headers are too large");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
529 return;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
530 }
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
531
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
532 #define APPEND_WIRE_HEADER(...) \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
533 do { \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
534 int appended = snprintf( \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
535 request_header + header_length, \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
536 sizeof(request_header) - (size_t)header_length, \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
537 __VA_ARGS__); \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
538 if (appended < 0 || (size_t)appended >= sizeof(request_header) - (size_t)header_length) { \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
539 Seobeo_Handle_Destroy(upstream); \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
540 send_proxy_error(client, 502, "Mercurial request headers are too large"); \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
541 return; \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
542 } \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
543 header_length += appended; \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
544 } while (0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
545
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
546 if (hg_argument && hg_argument[0] != '\0')
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
547 APPEND_WIRE_HEADER("x-hgarg-1: %s\r\n", hg_argument);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
548 if (content_type && content_type[0] != '\0')
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
549 APPEND_WIRE_HEADER("Content-Type: %s\r\n", content_type);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
550 if (body_length > 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
551 APPEND_WIRE_HEADER("Content-Length: %zu\r\n", body_length);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
552 APPEND_WIRE_HEADER("\r\n");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
553 #undef APPEND_WIRE_HEADER
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
554
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
555 if (Seobeo_Handle_Queue(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
556 upstream, (const uint8 *)request_header, (uint32)header_length) != 0 ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
557 (body_length > 0 &&
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
558 Seobeo_Handle_Queue(upstream, (const uint8 *)body, (uint32)body_length) != 0) ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
559 Seobeo_Handle_Flush(upstream) != 0)
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
560 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
561 Seobeo_Handle_Destroy(upstream);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
562 send_proxy_error(client, 502, "Mercurial backend write failed");
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
563 return;
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
564 }
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
565
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
566 boolean response_started = FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
567 int64_t last_progress = monotonic_milliseconds();
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
568 while (!response_started)
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
569 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
570 int read_result = Seobeo_Handle_Read(upstream);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
571 if (read_result == -2 || read_result < 0)
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
572 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
573 Seobeo_Handle_Destroy(upstream);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
574 send_proxy_error(client, 502, "Mercurial backend closed before responding");
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
575 return;
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
576 }
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
577 if (read_result > 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
578 last_progress = monotonic_milliseconds();
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
579
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
580 size_t header_size =
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
581 find_http_header_length(upstream->read_buffer, upstream->read_buffer_len);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
582 if (header_size > 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
583 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
584 (void)header_size;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
585 if (Seobeo_Handle_Queue(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
586 client, upstream->read_buffer, upstream->read_buffer_len) != 0 ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
587 Seobeo_Handle_Flush(client) != 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
588 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
589 Seobeo_Handle_Destroy(upstream);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
590 return;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
591 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
592 Seobeo_Handle_Consume(upstream, upstream->read_buffer_len);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
593 response_started = TRUE;
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
594 break;
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
595 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
596
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
597 if (read_result == 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
598 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
599 if (monotonic_milliseconds() - last_progress >= HG_STREAM_IDLE_TIMEOUT_MS)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
600 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
601 Seobeo_Handle_Destroy(upstream);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
602 send_proxy_error(client, 504, "Mercurial backend response timed out");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
603 return;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
604 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
605 usleep(1000);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
606 }
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
607 }
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
608
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
609 while (TRUE)
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
610 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
611 int read_result = Seobeo_Handle_Read(upstream);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
612 if (read_result == -2)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
613 break;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
614 if (read_result < 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
615 break;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
616 if (read_result == 0)
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
617 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
618 if (monotonic_milliseconds() - last_progress >= HG_STREAM_IDLE_TIMEOUT_MS)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
619 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
620 Seobeo_Log(SEOBEO_ERROR, "Mercurial response stream timed out\n");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
621 break;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
622 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
623 usleep(1000);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
624 continue;
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
625 }
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
626
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
627 last_progress = monotonic_milliseconds();
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
628 if (Seobeo_Handle_Queue(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
629 client, upstream->read_buffer, upstream->read_buffer_len) != 0 ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
630 Seobeo_Handle_Flush(client) != 0)
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
631 break;
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
632 Seobeo_Handle_Consume(upstream, upstream->read_buffer_len);
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
633 }
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
634
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
635 Seobeo_Handle_Destroy(upstream);
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
636 }
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
637
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
638 Seobeo_Request_Entry *GetReactHome(Seobeo_Request_Entry *request, Dowa_Arena *arena)
108
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
639 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
640 (void)request;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
641 size_t file_size = 0;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
642 char *html = Seobeo_Web_LoadFile("/index.html", &file_size);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
643 if (!html)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
644 return text_response(arena, "500", "text/plain", "Application shell unavailable");
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
645
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
646 Seobeo_Request_Entry *response = NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
647 char *content_length = Dowa_Arena_Allocate(arena, 32);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
648 snprintf(content_length, 32, "%zu", file_size);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
649 Dowa_HashMap_Push_Arena(response, "status", "200", arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
650 Dowa_HashMap_Push_Arena(response, "content-type", "text/html", arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
651 Dowa_HashMap_Push_Arena(response, "body", html, arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
652 Dowa_HashMap_Push_Arena(response, "content-length", content_length, arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
653 return response;
108
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
654 }
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
655
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
656 int main(void)
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
657 {
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
658 Seobeo_Router_Init();
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
659
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
660 Seobeo_Router_Register("GET", "/", GetReactHome);
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
661 Seobeo_Router_Register("GET", "/directories", GetReactHome);
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
662 Seobeo_Router_Register("GET", "/directory", GetReactHome);
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
663 Seobeo_Router_Register("GET", "/graph", GetReactHome);
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
664 Seobeo_Router_Register("GET", "/changeset/:changeset_id", GetReactHome);
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
665
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
666 Seobeo_Router_Register("GET", "/api/repo/list", ApiListDirectory);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
667 Seobeo_Router_Register("GET", "/api/repo/file", ApiGetFile);
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
668 Seobeo_Router_Register("GET", "/api/repo/readme", ApiGetReadme);
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
669 Seobeo_Router_Register("GET", "/api/graph/:graph_id", ApiGetGraph);
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
670 Seobeo_Router_Register("GET", "/api/changeset/:changeset_id", ApiGetChangeset);
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
671
175
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
672 Seobeo_Router_Register_Stream("GET", "/repo", StreamHgWireProtocol);
71ad34a8bc9a [HgWeb] Can stream hg response now. Added react page for hg web since we use json anyway.
MrJuneJune <me@mrjunejune.com>
parents: 147
diff changeset
673 Seobeo_Router_Register_Stream("POST", "/repo", StreamHgWireProtocol);
108
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
674
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
675 printf("Starting on Port 6970...\n");
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
676 int result =
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
677 Seobeo_Web_Server_Start("hg-web/src", "6970", SEOBEO_MODE_EDGE, 1);
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
678 Seobeo_Router_Destroy();
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
679 return result;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
680 }