annotate hg-web/main.c @ 150:c37490913530

[Config] Updated .vimrc files and made command for ctags movements.
author June Park <parkjune1995@gmail.com>
date Sat, 10 Jan 2026 13:30:28 -0800
parents ffb764d2fcc5
children 6de849867459
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"
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
3 #include <stdio.h>
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
4 #include <stdlib.h>
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
5 #include <string.h>
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
6 #include <ctype.h>
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
7 #include <unistd.h>
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
8 #include <sys/socket.h>
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
9 #include <netinet/in.h>
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
10 #include <arpa/inet.h>
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
11 #include <netdb.h>
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"
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
14 #define HG_SERVE_PORT 4444
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
15
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
16 #define MAX_PATH 4096
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
17
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
18 // TODO: Move this to seobeo....
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
19 // Asked AI to create this lol, probably should learn to decode it myself..
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
20 static void url_decode(char *dst, const char *src)
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
21 {
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
22 char a, b;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
23 while (*src) {
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
24 if ((*src == '%') &&
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
25 ((a = src[1]) && (b = src[2])) &&
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
26 (isxdigit(a) && isxdigit(b))) {
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
27 if (a >= 'a') a -= 'a'-'A';
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
28 if (a >= 'A') a -= ('A' - 10);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
29 else a -= '0';
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
30 if (b >= 'a') b -= 'a'-'A';
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
31 if (b >= 'A') b -= ('A' - 10);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
32 else b -= '0';
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
33 *dst++ = 16*a+b;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
34 src+=3;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
35 } else if (*src == '+') {
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
36 *dst++ = ' ';
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
37 src++;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
38 } else {
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
39 *dst++ = *src++;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
40 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
41 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
42 *dst = '\0';
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
43 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
44
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
45 static char* sanitize_path(const char *input_path, Dowa_Arena *arena)
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
46 {
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
47 if (!input_path || strlen(input_path) == 0)
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
48 {
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
49 char *empty = Dowa_Arena_Allocate(arena, 1);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
50 empty[0] = '\0';
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
51 return empty;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
52 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
53
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
54 size_t len = strlen(input_path);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
55 char *result = Dowa_Arena_Allocate(arena, len + 1);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
56 size_t j = 0;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
57
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
58 for (size_t i = 0; i < len; i++)
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
59 {
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
60 if (input_path[i] == '.' && (i == 0 || input_path[i-1] == '/')) {
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
61 if (i + 1 < len && input_path[i+1] == '.') {
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
62 // Skip ".."
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
63 i++;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
64 continue;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
65 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
66 // Skip "."
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
67 continue;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
68 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
69 result[j++] = input_path[i];
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
70 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
71 result[j] = '\0';
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
72
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
73 // Remove leading/trailing slashes
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
74 while (result[0] == '/')
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
75 memmove(result, result + 1, strlen(result));
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
76 while (j > 0 && result[j-1] == '/')
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
77 result[--j] = '\0';
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
78
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
79 return result;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
80 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
81
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
82 // Helper to connect to hg serve
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
83 static int hg_proxy_connect(void)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
84 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
85 int sock = socket(AF_INET, SOCK_STREAM, 0);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
86 if (sock < 0)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
87 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
88 Seobeo_Log(SEOBEO_DEBUG, "Failed to create socket\n");
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
89 return -1;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
90 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
91
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
92 struct sockaddr_in server_addr;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
93 memset(&server_addr, 0, sizeof(server_addr));
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
94 server_addr.sin_family = AF_INET;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
95 server_addr.sin_port = htons(HG_SERVE_PORT);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
96 inet_pton(AF_INET, HG_SERVE_HOST, &server_addr.sin_addr);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
97
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
98 if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
99 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
100 Seobeo_Log(SEOBEO_DEBUG, "Failed to connect to hg serve at %s:%d\n", HG_SERVE_HOST, HG_SERVE_PORT);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
101 close(sock);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
102 return -1;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
103 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
104
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
105 return sock;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
106 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
107
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
108 // Generic helper to proxy a request to hg serve and get the response body
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
109 // Returns allocated body on success, NULL on failure
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
110 // out_status and out_content_type are optional output parameters
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
111 // out_body_len returns the actual body length (for binary content)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
112 static char* hg_proxy_request(
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
113 const char *method,
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
114 const char *path,
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
115 const char *req_body,
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
116 size_t body_len,
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
117 char *out_status, // should be at least 4 bytes
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
118 char *out_content_type, // should be at least 256 bytes
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
119 size_t *out_body_len, // optional: returns actual body length
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
120 Dowa_Arena *arena)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
121 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
122 int sock = hg_proxy_connect();
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
123 if (sock < 0) return NULL;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
124
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
125 // Build HTTP request
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
126 char http_request[MAX_PATH * 2];
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
127 snprintf(http_request, sizeof(http_request),
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
128 "%s %s HTTP/1.1\r\n"
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
129 "Host: %s:%d\r\n"
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
130 "Connection: close\r\n"
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
131 "Accept: application/json, text/plain, */*\r\n"
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
132 "Content-Length: %zu\r\n"
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
133 "\r\n",
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
134 method, path, HG_SERVE_HOST, HG_SERVE_PORT, body_len);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
136 Seobeo_Log(SEOBEO_DEBUG, "HG Proxy request: %s %s\n", method, path);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
137
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
138 if (send(sock, http_request, strlen(http_request), 0) < 0)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
139 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
140 close(sock);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
141 return NULL;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
142 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
143
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
144 if (body_len > 0 && req_body)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
145 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
146 send(sock, req_body, body_len, 0);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
147 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
148
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
149 // Read response
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
150 int buffer_size = 1024 * 1024 * 5; // 5MB
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
151 char *response_buf = Dowa_Arena_Allocate(arena, buffer_size);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
152 size_t total_read = 0;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
153 ssize_t bytes_read;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
154
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
155 while ((bytes_read = recv(sock, response_buf + total_read, buffer_size - total_read - 1, 0)) > 0)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
156 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
157 total_read += bytes_read;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
158 if (total_read >= (size_t)(buffer_size - 1)) break;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
159 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
160 response_buf[total_read] = '\0';
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
161 close(sock);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
162
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
163 Seobeo_Log(SEOBEO_DEBUG, "HG Proxy: received %zu bytes\n", total_read);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
164
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
165 // Parse response headers - use memmem to handle binary content
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
166 char *headers_end = NULL;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
167 for (size_t i = 0; i + 3 < total_read; i++)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
168 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
169 if (response_buf[i] == '\r' && response_buf[i+1] == '\n' &&
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
170 response_buf[i+2] == '\r' && response_buf[i+3] == '\n')
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
171 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
172 headers_end = response_buf + i;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
173 break;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
174 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
175 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
176 if (!headers_end) return NULL;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
177
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
178 // Extract status
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
179 if (out_status && strncmp(response_buf, "HTTP/", 5) == 0)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
180 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
181 char *status_start = strchr(response_buf, ' ');
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
182 if (status_start)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
183 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
184 strncpy(out_status, status_start + 1, 3);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
185 out_status[3] = '\0';
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
186 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
187 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
188
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
189 // Extract content-type
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
190 if (out_content_type)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
191 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
192 out_content_type[0] = '\0';
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
193 char *ct_header = strcasestr(response_buf, "Content-Type:");
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
194 if (ct_header && ct_header < headers_end)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
195 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
196 ct_header += 13;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
197 while (*ct_header == ' ') ct_header++;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
198 char *ct_end = strpbrk(ct_header, "\r\n");
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
199 if (ct_end)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
200 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
201 size_t ct_len = ct_end - ct_header;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
202 if (ct_len < 256)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
203 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
204 strncpy(out_content_type, ct_header, ct_len);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
205 out_content_type[ct_len] = '\0';
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
206 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
207 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
208 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
209 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
210
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
211 // Return body (copy to fresh allocation for clean pointer)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
212 char *body = headers_end + 4;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
213 size_t body_size = total_read - (body - response_buf);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
214
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
215 if (out_body_len) *out_body_len = body_size;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
216
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
217 char *result = Dowa_Arena_Allocate(arena, body_size + 1);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
218 memcpy(result, body, body_size);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
219 result[body_size] = '\0';
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
220
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
221 return result;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
222 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
223
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
224 Seobeo_Request_Entry* ApiListDirectory(Seobeo_Request_Entry *req, Dowa_Arena *arena)
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
225 {
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
226 Seobeo_Request_Entry *resp = NULL;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
227
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
228 void *path_kv = Dowa_HashMap_Get_Ptr(req, "query_path");
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
229 const char *rel_path = path_kv ? ((Seobeo_Request_Entry*)path_kv)->value : "";
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
230
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
231 char *decoded_path = Dowa_Arena_Allocate(arena, strlen(rel_path) + 1);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
232 url_decode(decoded_path, rel_path);
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 char *safe_path = sanitize_path(decoded_path, arena);
106
daf2d393741a Debugging in server.
June Park <parkjune1995@gmail.com>
parents: 104
diff changeset
235
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
236 Seobeo_Log(SEOBEO_INFO, "ApiListDirectory: safe_path='%s'\n", safe_path);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
237
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
238 char hg_path[MAX_PATH];
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
239 if (strlen(safe_path) > 0)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
240 snprintf(hg_path, sizeof(hg_path), "/file/tip/%s?style=json", safe_path);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
241 else
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
242 snprintf(hg_path, sizeof(hg_path), "/file/tip/?style=json");
106
daf2d393741a Debugging in server.
June Park <parkjune1995@gmail.com>
parents: 104
diff changeset
243
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
244 char status[4] = "200";
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
245 char content_type[256] = "";
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
246 size_t body_len = 0;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
247 char *hg_response = hg_proxy_request("GET", hg_path, NULL, 0, status, content_type, &body_len, arena);
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
248
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
249 Seobeo_Log(SEOBEO_DEBUG, "ApiListDirectory: status=%s body_len=%zu\n", status, body_len);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
250
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
251 if (!hg_response || status[0] != '2')
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
252 {
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
253 Seobeo_Log(SEOBEO_DEBUG, "Failed to get directory from hg serve\n");
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
254 Dowa_HashMap_Push_Arena(resp, "status", "502", arena);
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
255 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
256 Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Failed to connect to hg serve\"}", arena);
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
257 return resp;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
258 }
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
259 char *json = hg_response;
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
260
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
261 Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
262 Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
263 Dowa_HashMap_Push_Arena(resp, "body", json, arena);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
264
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
265 return resp;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
266 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
267
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
268 Seobeo_Request_Entry* ApiGetFile(Seobeo_Request_Entry *req, Dowa_Arena *arena)
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
269 {
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
270 Seobeo_Request_Entry *resp = NULL;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
271
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
272 void *path_kv = Dowa_HashMap_Get_Ptr(req, "query_path");
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
273 const char *rel_path = path_kv ? ((Seobeo_Request_Entry*)path_kv)->value : "";
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
274 char *decoded_path = Dowa_Arena_Allocate(arena, strlen(rel_path) + 1);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
275 url_decode(decoded_path, rel_path);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
276 char *safe_path = sanitize_path(decoded_path, arena);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
277
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
278 Seobeo_Log(SEOBEO_INFO, "ApiGetFile: safe_path='%s'\n", safe_path);
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
279
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
280 if (strlen(safe_path) == 0)
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
281 {
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
282 Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
283 Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
284 Dowa_HashMap_Push_Arena(resp, "body", "File path required", arena);
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
285 return resp;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
286 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
287
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
288 // Build hg serve URL: /raw-file/tip/<path>
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
289 char hg_path[MAX_PATH];
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
290 snprintf(hg_path, sizeof(hg_path), "/raw-file/tip/%s", safe_path);
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
291
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
292 char status[4] = "200";
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
293 char content_type[256] = "";
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
294 size_t body_len = 0;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
295 char *body = hg_proxy_request("GET", hg_path, NULL, 0, status, content_type, &body_len, arena);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
296
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
297 Seobeo_Log(SEOBEO_DEBUG, "ApiGetFile: status=%s body_len=%zu\n", status, body_len);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
298
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
299 if (!body)
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
300 {
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
301 Dowa_HashMap_Push_Arena(resp, "status", "502", arena);
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
302 Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
303 Dowa_HashMap_Push_Arena(resp, "body", "Failed to connect to hg serve", arena);
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
304 return resp;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
305 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
306
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
307 if (status[0] != '2')
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
308 {
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
309 Seobeo_Log(SEOBEO_DEBUG, "ApiGetFile: error response: %s\n", body);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
310 Dowa_HashMap_Push_Arena(resp, "status", status, arena);
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
311 Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
312 // Return actual error from hg serve if available
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
313 Dowa_HashMap_Push_Arena(resp, "body", body_len > 0 ? body : "File not found", arena);
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
314 return resp;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
315 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
316
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
317 // Use content-type from hg serve, or determine from extension
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
318 const char *final_content_type = content_type;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
319 if (strlen(content_type) == 0 || strcmp(content_type, "application/octet-stream") == 0)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
320 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
321 final_content_type = "text/plain";
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
322 if (strstr(safe_path, ".md")) final_content_type = "text/markdown";
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
323 else if (strstr(safe_path, ".html")) final_content_type = "text/html";
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
324 else if (strstr(safe_path, ".css")) final_content_type = "text/css";
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
325 else if (strstr(safe_path, ".js")) final_content_type = "application/javascript";
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
326 else if (strstr(safe_path, ".json")) final_content_type = "application/json";
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
327 }
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
328
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
329 Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
330 Dowa_HashMap_Push_Arena(resp, "content-type", final_content_type, arena);
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
331 Dowa_HashMap_Push_Arena(resp, "body", body, arena);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
332
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
333 return resp;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
334 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
335
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
336 Seobeo_Request_Entry* ApiGetReadme(Seobeo_Request_Entry *req, Dowa_Arena *arena) {
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
337 return ApiGetFile(req, arena);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
338 }
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
339
108
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
340 Seobeo_Request_Entry* ApiHgWireProtocol(Seobeo_Request_Entry *req, Dowa_Arena *arena)
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
341 {
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
342 Seobeo_Request_Entry *resp = NULL;
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
343
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
344 // Get method
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
345 void *method_kv = Dowa_HashMap_Get_Ptr(req, "HTTP_Method");
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
346 const char *method = method_kv ? ((Seobeo_Request_Entry*)method_kv)->value : "GET";
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
347
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
348 // Get query string
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
349 void *query_kv = Dowa_HashMap_Get_Ptr(req, "QueryString");
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
350 const char *query_string = query_kv ? ((Seobeo_Request_Entry*)query_kv)->value : "";
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
351
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
352 // Get request body for POST
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
353 void *body_kv = Dowa_HashMap_Get_Ptr(req, "Body");
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
354 const char *req_body = body_kv ? ((Seobeo_Request_Entry*)body_kv)->value : "";
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
355 size_t body_len = strlen(req_body);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
356
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
357 Seobeo_Log(SEOBEO_DEBUG, "HG Proxy: method=%s query=%s body_len=%zu\n", method, query_string, body_len);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
358
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
359 // Connect to hg serve
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
360 int sock = hg_proxy_connect();
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
361 if (sock < 0)
108
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
362 {
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
363 Dowa_HashMap_Push_Arena(resp, "status", "502", arena);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
364 Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
365 Dowa_HashMap_Push_Arena(resp, "body", "Failed to connect to hg serve", 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
366 return resp;
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
367 }
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
368
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
369 // Build the HTTP request to forward to hg serve
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
370 char http_request[MAX_PATH * 2];
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
371 if (strlen(query_string) > 0)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
372 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
373 snprintf(http_request, sizeof(http_request),
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
374 "%s /?%s HTTP/1.1\r\n"
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
375 "Host: %s:%d\r\n"
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
376 "Connection: close\r\n"
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
377 "Content-Length: %zu\r\n"
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
378 "\r\n",
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
379 method, query_string, HG_SERVE_HOST, HG_SERVE_PORT, body_len);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
380 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
381 else
109
1c446ab6f945 [MrJuneJune] New Blog about writing Seobeo library.
June Park <parkjune1995@gmail.com>
parents: 108
diff changeset
382 {
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
383 snprintf(http_request, sizeof(http_request),
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
384 "%s / HTTP/1.1\r\n"
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
385 "Host: %s:%d\r\n"
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
386 "Connection: close\r\n"
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
387 "Content-Length: %zu\r\n"
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
388 "\r\n",
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
389 method, HG_SERVE_HOST, HG_SERVE_PORT, body_len);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
390 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
391
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
392 // Send HTTP request headers
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
393 if (send(sock, http_request, strlen(http_request), 0) < 0)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
394 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
395 Seobeo_Log(SEOBEO_DEBUG, "Failed to send request to hg serve\n");
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
396 close(sock);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
397 Dowa_HashMap_Push_Arena(resp, "status", "502", arena);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
398 Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
399 Dowa_HashMap_Push_Arena(resp, "body", "Failed to send to hg serve", 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
400 return resp;
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
401 }
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
402
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
403 // Send body if present
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
404 if (body_len > 0)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
405 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
406 send(sock, req_body, body_len, 0);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
407 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
408
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
409 // Read response from hg serve
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
410 int buffer_size = 1024 * 1024 * 5; // 5MB
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
411 char *response_buf = Dowa_Arena_Allocate(arena, buffer_size);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
412 size_t total_read = 0;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
413 ssize_t bytes_read;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
414
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
415 while ((bytes_read = recv(sock, response_buf + total_read, buffer_size - total_read - 1, 0)) > 0)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
416 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
417 total_read += bytes_read;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
418 if (total_read >= (size_t)(buffer_size - 1)) break;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
419 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
420 response_buf[total_read] = '\0';
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
421 close(sock);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
422
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
423 Seobeo_Log(SEOBEO_DEBUG, "HG Proxy: received %zu bytes\n", total_read);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
424
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
425 // Parse HTTP response - find headers end
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
426 char *headers_end = strstr(response_buf, "\r\n\r\n");
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
427 if (!headers_end)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
428 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
429 Dowa_HashMap_Push_Arena(resp, "status", "502", arena);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
430 Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
431 Dowa_HashMap_Push_Arena(resp, "body", "Invalid response from hg serve", arena);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
432 return resp;
108
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
433 }
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
434
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
435 // Extract status code from first line (e.g., "HTTP/1.1 200 OK")
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
436 char status_code[4] = "200";
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
437 if (strncmp(response_buf, "HTTP/", 5) == 0)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
438 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
439 char *status_start = strchr(response_buf, ' ');
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
440 if (status_start)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
441 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
442 strncpy(status_code, status_start + 1, 3);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
443 status_code[3] = '\0';
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
444 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
445 }
108
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
446
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
447 // Extract content-type from headers
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
448 const char *content_type = "application/mercurial-0.1";
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
449 char *ct_header = strcasestr(response_buf, "Content-Type:");
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
450 if (ct_header && ct_header < headers_end)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
451 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
452 ct_header += 13; // Skip "Content-Type:"
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
453 while (*ct_header == ' ') ct_header++;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
454 char *ct_end = strpbrk(ct_header, "\r\n");
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
455 if (ct_end)
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
456 {
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
457 size_t ct_len = ct_end - ct_header;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
458 char *ct_copy = Dowa_Arena_Allocate(arena, ct_len + 1);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
459 strncpy(ct_copy, ct_header, ct_len);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
460 ct_copy[ct_len] = '\0';
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
461 content_type = ct_copy;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
462 }
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
463 }
108
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
464
135
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
465 // Body starts after \r\n\r\n
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
466 char *body = headers_end + 4;
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
467
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
468 Dowa_HashMap_Push_Arena(resp, "status", status_code, arena);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
469 Dowa_HashMap_Push_Arena(resp, "content-type", content_type, arena);
ffb764d2fcc5 [HgWeb] Updated hg web so it works
June Park <parkjune1995@gmail.com>
parents: 109
diff changeset
470 Dowa_HashMap_Push_Arena(resp, "body", body, 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
471
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
472 return resp;
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
473 }
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
474
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
475 int main(void) {
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
476 Seobeo_Router_Init();
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
477
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
478 Seobeo_Router_Register("GET", "/api/repo/list", ApiListDirectory);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
479 Seobeo_Router_Register("GET", "/api/repo/file", ApiGetFile);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
480 Seobeo_Router_Register("GET", "/api/repo/readme", ApiGetReadme);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
481
108
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
482 Seobeo_Router_Register("GET", "/repo", ApiHgWireProtocol);
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
483 Seobeo_Router_Register("POST", "/repo", ApiHgWireProtocol);
f07abbcd2ec5 [HgWeb] Will probably hold off on using it since it is not urgent.
June Park <parkjune1995@gmail.com>
parents: 107
diff changeset
484
104
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
485 printf("Starting on Port 6970...\n");
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
486 printf("Repository: %s\n", REPO_ROOT);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
487
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
488 int result = Seobeo_Web_Server_Start("hg-web/src", "6970", SEOBEO_MODE_EDGE, 4);
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
489
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
490 Seobeo_Router_Destroy();
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
491
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
492 return result;
2301aeb7503b [Hg Web] Super simple mercurial server.
June Park <parkjune1995@gmail.com>
parents:
diff changeset
493 }