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 !}
47 <!doctype html>
48 <html{{ if *lang != '\0' }}{{ " " }}lang="{{ lang }}"{{ end }}>
49 <head>
50 <meta name="viewport" content="initial-scale=1" />
52 {{ if *stylesheet == 0 }}
53 <link rel="stylesheet" href="{{ prfx }}galileo.css" />
54 {{ else }}
55 <link rel="stylesheet" href="{{ stylesheet|urlescape }}" />
56 {{ end }}
58 <title>
59 {{ if title }}
60 {{ title }}
61 {{ else if pc }}
62 gemini://{{ pc->proxy_name }}{{ path }}
63 {{ end }}
64 </title>
65 </head>
66 <body>
67 {{ if path }}
68 {{ render tp_navigation(tp) }}
69 {{ end }}
70 {{ end }}
72 {{ define tp_foot(struct template *tp) }}
73 {!
74 struct client *clt = tp->tp_arg;
75 struct proxy_config *pc = clt->clt_pc;
76 const char *path = clt->clt_path_info;
77 !}
78 {{ if pc }}
79 <footer>
80 <hr />
81 <dl>
82 <dt>Original URL:</dt>
83 <dd>
84 <a href="gemini://{{ pc->proxy_name | urlescape }}{{ path | urlescape }}">
85 gemini://{{ pc->proxy_name }}{{ path }}
86 </a>
87 </dd>
88 </dl>
89 </footer>
90 {{ end }}
91 </body>
92 </html>
93 {{ end }}
95 {{ define tp_navigation(struct template *tp) }}
96 {!
97 struct client *clt = tp->tp_arg;
98 const char *prfx = clt->clt_script_name;
99 char *path = clt->clt_path_info;
100 char *tilde, *t, home[GEMINI_MAXLEN], up[GEMINI_MAXLEN];
101 char *dname;
102 char c;
104 *home = '\0';
105 if ((tilde = strstr(path, "/~")) != NULL &&
106 (t = strchr(tilde + 1, '/')) != NULL) {
107 c = *++t;
108 *t = '\0';
109 (void) strlcpy(home, path + 1, sizeof(home));
110 *t = c;
113 (void) strlcpy(up, path + 1, sizeof(up));
114 dname = dirname(up);
115 !}
116 <header>
117 <nav>
118 <ul>
119 <li><a href="{{ prfx }}">/ Root</a></li>
121 {{ if *home != '\0' }}
122 <li><a href="{{ prfx }}{{ home }}">🏠 Home</a></li>
123 {{ end }}
125 {{ if strcmp(dname, ".") != 0 }}
126 <li><a href="{{ prfx }}{{ dname }}/">↑ Up</a></li>
127 {{ end }}
128 </ul>
129 </nav>
130 </header>
131 {{ end }}
133 {{ define tp_figure(struct template *tp, const char *url, const char *label) }}
134 <figure>
135 <a href="{{ url | urlescape }}">
136 <img src="{{ url | urlescape }}" />
137 </a>
138 <figcaption>
139 {{ label }}
140 </figcaption>
141 </figure>
142 {{ end }}
144 {{ define tp_pre_open(struct template *tp, const char *label) }}
145 <figure>
146 {{ if label && *label != '\0' }}
147 <figcaption>{{ label }}</figcaption>
148 {{ end }}
149 <pre>
150 {{ end }}
152 {{ define tp_pre_close(struct template *tp) }}
153 </pre>
154 </figure>
155 {{ end }}
157 {{ define tp_error(struct template *tp, int code, const char *reason) }}
158 {!
159 char scode[32];
160 int r;
162 r = snprintf(scode, sizeof(code), "%d", code);
163 if (r < 0 || (size_t)r >= sizeof(code))
164 return (0);
166 !}
167 {{ render tp_head(tp, "en", "Proxy error") }}
168 <main>
169 <h1>Proxy error</h1>
170 {{ if code != -1 }}
171 <p>Request failed with code: <code>{{ scode }}</code>.</p>
172 <p>The server says: {{ reason }}.</p>
173 {{ else }}
174 <p>Unable to serve the page due to: {{ reason }}.</p>
175 {{ end }}
176 </main>
177 {{ render tp_foot(tp) }}
178 {{ end }}
180 {{ define tp_inputpage(struct template *tp, const char *prompt) }}
181 {{ render tp_head(tp, "en", "input request") }}
182 <p>The server ask for input: <q>{{ prompt }}</q>.</p>
183 <form method="post" enctype="{{ FORM_URLENCODED }}">
184 <label for="reply">{{ "response " }}</label>
185 <input type="text" value="" id="reply" name="q" autofocus />
186 {{ " " }}
187 <button type="submit">Submit!</button>
188 </form>
189 {{ render tp_foot(tp) }}
190 {{ end }}