Mercurial
annotate hg-web/main.c @ 164:ce05514681c6
[MrJuneJune] Resume links aren't broken due to previous resume.pdf links.
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Mon, 19 Jan 2026 05:40:22 -0800 |
| parents | ffb764d2fcc5 |
| children | 6de849867459 |
| 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 | 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 | 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 } |