annotate hg-web/main.c @ 223:0e7b9464248d hg-web

[hg-web] Add browser route regression coverage
author MrJuneJune <me@mrjunejune.com>
date Sun, 02 Aug 2026 10:07:40 -0700
parents ce7f4400c2de
children 3007ef5fc0ed
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
223
0e7b9464248d [hg-web] Add browser route regression coverage
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
347 Seobeo_Client_Response *hg_response =
0e7b9464248d [hg-web] Add browser route regression coverage
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
348 hg_proxy_request("GET", hg_path, NULL, 0, NULL, "text/markdown");
0e7b9464248d [hg-web] Add browser route regression coverage
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
349 if (hg_response && hg_response->status_code == HTTP_NOT_FOUND)
0e7b9464248d [hg-web] Add browser route regression coverage
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
350 {
0e7b9464248d [hg-web] Add browser route regression coverage
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
351 Seobeo_Client_Response_Destroy(hg_response);
0e7b9464248d [hg-web] Add browser route regression coverage
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
352 return text_response(arena, "204", "text/markdown", "");
0e7b9464248d [hg-web] Add browser route regression coverage
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
353 }
0e7b9464248d [hg-web] Add browser route regression coverage
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
354 return forward_hg_response(hg_response, "text/markdown", arena);
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
355 }
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
356
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
357 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
358 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
359 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
360 if (!validate_revision(graph_id))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
361 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
362
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
363 const char *encoded_graph_top =
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
364 map_value_case_insensitive(request, "query_graphtop");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
365 char *graph_top = NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
366 if (encoded_graph_top)
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
367 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
368 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
369 !validate_revision(graph_top))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
370 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
371 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
372
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
373 char hg_path[MAX_PATH_LENGTH];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
374 int length = graph_top
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
375 ? snprintf(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
376 hg_path,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
377 sizeof(hg_path),
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
378 "/graph/%s?graphtop=%s&style=json",
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
379 graph_id,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
380 graph_top)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
381 : 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
382 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
383 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
384
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
385 return forward_hg_response(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
386 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
387 "application/json",
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
388 arena);
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
389 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
390
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
391 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
392 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
393 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
394 if (!validate_revision(changeset_id))
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
395 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
396
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
397 char hg_path[128];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
398 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
399 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
400 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
401
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
402 return forward_hg_response(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
403 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
404 "application/json",
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
405 arena);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
406 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
407
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
408 static int64_t monotonic_milliseconds(void)
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 struct timespec now;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
411 clock_gettime(CLOCK_MONOTONIC, &now);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
412 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
413 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
414
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
415 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
416 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
417 if (!buffer || length < 4)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
418 return 0;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
419 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
420 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
421 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
422 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
423 return i + 4;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
424 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
425 return 0;
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
426 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
427
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
428 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
429 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
430 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
431 char response[512];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
432 int length = snprintf(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
433 response,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
434 sizeof(response),
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
435 "HTTP/1.1 %d %s\r\n"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
436 "Content-Type: text/plain\r\n"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
437 "Content-Length: %zu\r\n"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
438 "Connection: close\r\n"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
439 "\r\n"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
440 "%s",
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
441 status,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
442 reason,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
443 strlen(message),
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
444 message);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
445 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
446 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
447 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
448 Seobeo_Handle_Flush(client);
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 }
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
451
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
452 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
453 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
454 if (!value || !length_out || value[0] == '\0')
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
455 return FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
456 errno = 0;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
457 char *end = NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
458 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
459 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
460 return FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
461 *length_out = (size_t)parsed;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
462 return TRUE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
463 }
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
464
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
465 void StreamHgWireProtocol(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
466 Seobeo_Handle *client,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
467 Seobeo_Request_Entry *request,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
468 Dowa_Arena *arena)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
469 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
470 (void)arena;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
471 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
472 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
473 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
474 const char *content_length_value =
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
475 map_value_case_insensitive(request, "Content-Length");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
476 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
477 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
478
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
479 if (!method || !query ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
480 (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
481 !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
482 !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
483 !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
484 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
485 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
486 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
487 }
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
488
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
489 size_t body_length = 0;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
490 if (content_length_value &&
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
491 !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
492 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
493 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
494 return;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
495 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
496 if (body_length > 0 && !body)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
497 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
498 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
499 return;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
500 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
501 if (body_length > UINT32_MAX)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
502 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
503 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
504 return;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
505 }
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
506
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
507 Seobeo_Handle *upstream =
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
508 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
509 if (!upstream || upstream->socket < 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
510 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
511 if (upstream)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
512 Seobeo_Handle_Destroy(upstream);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
513 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
514 return;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
515 }
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
516
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
517 char request_header[16384];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
518 int header_length = snprintf(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
519 request_header,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
520 sizeof(request_header),
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
521 "%s /?%s HTTP/1.1\r\n"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
522 "Host: %s:%s\r\n"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
523 "User-Agent: Seobeo/1.0\r\n"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
524 "Connection: close\r\n",
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
525 method,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
526 query,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
527 HG_SERVE_HOST,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
528 HG_SERVE_PORT);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
529 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
530 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
531 Seobeo_Handle_Destroy(upstream);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
532 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
533 return;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
534 }
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
535
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
536 #define APPEND_WIRE_HEADER(...) \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
537 do { \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
538 int appended = snprintf( \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
539 request_header + header_length, \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
540 sizeof(request_header) - (size_t)header_length, \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
541 __VA_ARGS__); \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
542 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
543 Seobeo_Handle_Destroy(upstream); \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
544 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
545 return; \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
546 } \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
547 header_length += appended; \
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
548 } while (0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
549
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
550 if (hg_argument && hg_argument[0] != '\0')
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
551 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
552 if (content_type && content_type[0] != '\0')
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
553 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
554 if (body_length > 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
555 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
556 APPEND_WIRE_HEADER("\r\n");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
557 #undef APPEND_WIRE_HEADER
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
558
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
559 if (Seobeo_Handle_Queue(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
560 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
561 (body_length > 0 &&
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
562 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
563 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
564 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
565 Seobeo_Handle_Destroy(upstream);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
566 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
567 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
568 }
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 boolean response_started = FALSE;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
571 int64_t last_progress = monotonic_milliseconds();
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
572 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
573 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
574 int read_result = Seobeo_Handle_Read(upstream);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
575 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
576 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
577 Seobeo_Handle_Destroy(upstream);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
578 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
579 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
580 }
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
581 if (read_result > 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
582 last_progress = monotonic_milliseconds();
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 size_t header_size =
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
585 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
586 if (header_size > 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
587 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
588 (void)header_size;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
589 if (Seobeo_Handle_Queue(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
590 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
591 Seobeo_Handle_Flush(client) != 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
592 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
593 Seobeo_Handle_Destroy(upstream);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
594 return;
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 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
597 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
598 break;
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
599 }
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 if (read_result == 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
602 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
603 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
604 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
605 Seobeo_Handle_Destroy(upstream);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
606 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
607 return;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
608 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
609 usleep(1000);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
610 }
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
611 }
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
612
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
613 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
614 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
615 int read_result = Seobeo_Handle_Read(upstream);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
616 if (read_result == -2)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
617 break;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
618 if (read_result < 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
619 break;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
620 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
621 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
622 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
623 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
624 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
625 break;
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 usleep(1000);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
628 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
629 }
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
630
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
631 last_progress = monotonic_milliseconds();
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
632 if (Seobeo_Handle_Queue(
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
633 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
634 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
635 break;
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
636 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
637 }
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
638
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
639 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
640 }
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
641
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
642 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
643 {
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
644 (void)request;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
645 size_t file_size = 0;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
646 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
647 if (!html)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
648 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
649
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
650 Seobeo_Request_Entry *response = NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
651 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
652 snprintf(content_length, 32, "%zu", file_size);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
653 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
654 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
655 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
656 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
657 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
658 }
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
659
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
660 int main(void)
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
661 {
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
662 Seobeo_Router_Init();
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
663
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
664 Seobeo_Router_Register("GET", "/", GetReactHome);
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
665 Seobeo_Router_Register("GET", "/directories", GetReactHome);
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
666 Seobeo_Router_Register("GET", "/directory", GetReactHome);
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
667 Seobeo_Router_Register("GET", "/graph", GetReactHome);
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
668 Seobeo_Router_Register("GET", "/changeset/:changeset_id", GetReactHome);
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
669
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
670 Seobeo_Router_Register("GET", "/api/repo/list", ApiListDirectory);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
671 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
672 Seobeo_Router_Register("GET", "/api/repo/readme", ApiGetReadme);
193
9f4429c49733 [HgWeb] Making progress....
MrJuneJune <me@mrjunejune.com>
parents: 190
diff changeset
673 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
674 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
675
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
676 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
677 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
678
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
679 printf("Starting on Port 6970...\n");
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
680 int result =
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents: 193
diff changeset
681 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
682 Seobeo_Router_Destroy();
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
683 return result;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
684 }