Blob


1 {!
2 /*
3 * Copyright (c) 2022 Omar Polo <op@omarpolo.com>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
18 #include <sys/queue.h>
19 #include <sys/tree.h>
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
24 #include <event.h>
25 #include <libgen.h>
26 #include <limits.h>
27 #include <stdint.h>
28 #include <stdio.h>
29 #include <string.h>
31 #include "galileo.h"
32 #include "tmpl.h"
34 static int tp_navigation(struct template *);
36 !}
38 {{ define tp_head(struct template *tp, const char *lang,
39 const char *title) }}
40 {!
41 struct client *clt = tp->tp_arg;
42 struct proxy_config *pc = clt->clt_pc;
43 const char *stylesheet = pc ? pc->stylesheet : "";
44 const char *prfx = clt->clt_script_name;
45 const char *path = clt->clt_path_info;
46 int hidenav;
48 hidenav = pc ? pc->flags & PROXY_NO_NAVBAR : 0;
49 !}
50 <!doctype html>
51 <html{{ if *lang != '\0' }}{{ " " }}lang="{{ lang }}"{{ end }}>
52 <head>
53 <meta name="viewport" content="initial-scale=1" />
55 {{ if *stylesheet == 0 }}
56 <link rel="stylesheet" href="{{ prfx }}galileo.css" />
57 {{ else }}
58 <link rel="stylesheet" href="{{ stylesheet|urlescape }}" />
59 {{ end }}
61 <title>
62 {{ if title }}
63 {{ title }}
64 {{ else if pc }}
65 gemini://{{ pc->proxy_name }}{{ path }}
66 {{ end }}
67 </title>
68 </head>
69 <body>
70 {{ if path && !hidenav }}
71 {{ render tp_navigation(tp) }}
72 {{ end }}
73 {{ end }}
75 {{ define tp_foot(struct template *tp) }}
76 {!
77 struct client *clt = tp->tp_arg;
78 struct proxy_config *pc = clt->clt_pc;
79 const char *path = clt->clt_path_info;
80 int hidefoot;
82 hidefoot = pc ? pc->flags & PROXY_NO_FOOTER : 0;
83 !}
84 {{ if pc && !hidefoot }}
85 <footer>
86 <hr />
87 <dl>
88 <dt>Original URL:</dt>
89 <dd>
90 <a href="gemini://{{ pc->proxy_name | urlescape }}{{ path | urlescape }}">
91 gemini://{{ pc->proxy_name }}{{ path }}
92 </a>
93 </dd>
94 </dl>
95 </footer>
96 {{ end }}
97 </body>
98 </html>
99 {{ end }}
101 {{ define tp_navigation(struct template *tp) }}
102 {!
103 struct client *clt = tp->tp_arg;
104 const char *dname, *dsufx = "/", *prfx = clt->clt_script_name;
105 char *path = clt->clt_path_info;
106 char *tilde, *t, home[GEMINI_MAXLEN], up[GEMINI_MAXLEN];
107 char usr[64];
108 char c;
110 *home = '\0';
111 if ((tilde = strstr(path, "/~")) != NULL &&
112 (t = strchr(tilde + 1, '/')) != NULL) {
113 c = *++t;
114 *t = '\0';
115 (void) strlcpy(home, path + 1, sizeof(home));
116 *t = c;
118 c = *--t;
119 *t = '\0';
120 (void) strlcpy(usr, tilde + 2, sizeof(usr));
121 *t = c;
124 (void) strlcpy(up, path + 1, sizeof(up));
125 dname = dirname(up);
126 if (!strcmp(dname, ".")) {
127 dname = "";
128 dsufx = "";
130 !}
131 <header>
132 <nav>
133 <ul>
134 <li><a href="{{ prfx }}">/ Root</a></li>
136 <li><a href="{{ prfx }}{{ dname }}{{ dsufx }}">
137 ↑ Up
138 </a></li>
140 {{ if *home != '\0' }}
141 <li><a href="{{ prfx }}{{ home }}">
142 🏠 {{usr}}' home
143 </a></li>
144 {{ end }}
145 </ul>
146 </nav>
147 </header>
148 {{ end }}
150 {{ define tp_figure(struct template *tp, const char *url, const char *label) }}
151 <figure>
152 <a href="{{ url | urlescape }}">
153 <img src="{{ url | urlescape }}" />
154 </a>
155 <figcaption>
156 {{ label }}
157 </figcaption>
158 </figure>
159 {{ end }}
161 {{ define tp_pre_open(struct template *tp, const char *label) }}
162 <figure>
163 {{ if label && *label != '\0' }}
164 <figcaption>{{ label }}</figcaption>
165 {{ end }}
166 <pre>
167 {{ end }}
169 {{ define tp_pre_close(struct template *tp) }}
170 </pre>
171 </figure>
172 {{ end }}
174 {{ define tp_error(struct template *tp, int code, const char *reason) }}
175 {!
176 char scode[32];
177 int r;
179 r = snprintf(scode, sizeof(code), "%d", code);
180 if (r < 0 || (size_t)r >= sizeof(code))
181 return (0);
183 !}
184 {{ render tp_head(tp, "en", "Proxy error") }}
185 <main>
186 <h1>Proxy error</h1>
187 {{ if code != -1 }}
188 <p>Request failed with code: <code>{{ scode }}</code>.</p>
189 <p>The server says: {{ reason }}.</p>
190 {{ else }}
191 <p>Unable to serve the page due to: {{ reason }}.</p>
192 {{ end }}
193 </main>
194 {{ render tp_foot(tp) }}
195 {{ end }}
197 {{ define tp_inputpage(struct template *tp, const char *prompt) }}
198 {{ render tp_head(tp, "en", "input request") }}
199 <p>The server ask for input: <q>{{ prompt }}</q>.</p>
200 <form method="post" enctype="{{ FORM_URLENCODED }}">
201 <label for="reply">{{ "response " }}</label>
202 <input type="text" value="" id="reply" name="q" autofocus />
203 {{ " " }}
204 <button type="submit">Submit!</button>
205 </form>
206 {{ render tp_foot(tp) }}
207 {{ end }}