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 <limits.h>
26 #include <stdint.h>
27 #include <stdio.h>
28 #include <string.h>
30 #include "galileo.h"
32 !}
34 {{ define tp_head(struct template *tp, const char *lang,
35 const char *title) }}
36 {! struct client *clt = tp->tp_arg; !}
37 {! struct proxy_config *pc = clt->clt_pc; !}
38 {! const char *stylesheet = pc->stylesheet; !}
39 {! const char *path = clt->clt_path_info; !}
40 <!doctype html>
41 <html{{ if *lang != '\0' }}lang="{{ lang }}"{{ end }}>
42 <head>
43 <meta name="viewport" content="initial-scale=1" />
45 {{ if *stylesheet == '\0' }}
46 <link rel="stylesheet" href="{{ prfx|urlescape }}/galileo.css" />
47 {{ else }}
48 <link rel="stylesheet" href="{{ stylesheet|urlescape }}" />
49 {{ end }}
51 <title>
52 {{ if title }}
53 {{ title }}
54 {{ else }}
55 gemini://{{ pc->proxy_name }}{{ path }}
56 {{ end }}
57 </title>
58 </head>
59 <body>
60 {{ end }}
62 {{ define tp_foot(struct template *tp) }}
63 {! struct client *clt = tp->tp_arg; !}
64 {! struct proxy_config *pc = clt->clt_pc; !}
65 {! const char *host = pc->proxy_name; !}
66 {! const char *path = clt->clt_path_info; !}
68 <footer>
69 <hr />
70 <dl>
71 <dt>Original URL:</dt>
72 <dd>
73 <a href="gemini://{{ host | urlescape }}{{ path | urlescape }}">
74 gemini://{{ host }}{{ path }}
75 </a>
76 </dd>
77 </dl>
78 </footer>
79 </body>
80 </html>
81 {{ end }}
83 {{ define tp_figure(struct template *tp, const char *url,
84 const char *label) }}
85 {!
86 struct client *clt = tp->tp_arg;
87 const char *path = "";
88 int relativify;
90 relativify = *url == '/' || strstr(url, "//") == NULL;
91 if (relativify) {
92 path = clt->clt_script_name;
93 url++; /* skip leading / */
94 }
95 !}
96 <figure>
97 <a href="{{ path | urlescape }}{{ url | urlescape }}">
98 <img src="{{ path | urlescape }}{{ url | urlescape }}" />
99 </a>
100 <figcaption>
101 {{ label }}
102 </figcaption>
103 </figure>
104 {{ end }}
106 {{ define tp_error(struct template *tp, int code, const char *reason) }}
107 {!
108 char scode[32];
109 int r;
111 r = snprintf(scode, sizeof(code), "%d", code);
112 if (r < 0 || (size_t)r >= sizeof(code))
113 return 0;
115 !}
116 {{ render tp_head(tp, "en", "Proxy error") }}
117 <main>
118 <h1>Proxy error</h1>
119 {{ if code != -1 }}
120 <p>Request failed with code: <code>{{ scode }}</code>.</p>
121 <p>The server says: {{ reason }}.</p>
122 {{ else }}
123 <p>Unable to serve the page due to: {{ reason }}.</p>
124 {{ end }}
125 </main>
126 {{ render tp_foot(tp) }}
127 {{ end }}
129 {{ define tp_inputpage(struct template *tp, const char *prompt) }}
130 {{ render tp_head(tp, "en", "input request") }}
131 <p>The server ask for input: <q>{{ prompt }}</q>.</p>
132 <form method="post" enctype="{{ FORM_URLENCODED }}">
133 <label for="reply">{{ "response " }}</label>
134 <input type="text" value="" id="reply" name="q" />
135 {{ " " }}
136 <button type="submit">Submit!</button>
137 </form>
138 {{ render tp_foot(tp) }}
139 {{ end }}