tFormat text as HTML on the fly - phroxy - Gopher to HTTP proxy
(HTM) git clone git://git.z3bra.org/phroxy.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) LICENSE
---
(DIR) commit 5f381215e10e7696ffcb418cbc0f2f1a5f4aedb5
(DIR) parent 6399fbf8c0ea8bb09ad819e86c4393845b5e1472
(HTM) Author: Willy Goiffon <dev@z3bra.org>
Date: Thu, 24 Sep 2020 09:36:43 +0200
Format text as HTML on the fly
Diffstat:
M config.def.h | 8 +++-----
M phroxy.c | 102 +++++++++++++++----------------
2 files changed, 51 insertions(+), 59 deletions(-)
---
(DIR) diff --git a/config.def.h b/config.def.h
t@@ -1,14 +1,12 @@
char *default_hole = "z3bra.org";
const char *http_host = "z3bra.org";
-const char *htmlfmt =
+const char *head =
"<!DOCTYPE HTML>\n"
"<html><head>\n"
"<meta charset=\"utf-8\">"
"<meta name=\"viewport\" content=\"width=device-width\">"
- "<style>body { white-space: pre; }</style>"
"<title>gopher proxy</title>\n"
"</head>\n"
- "<body>\n"
- "%s\n"
- "</body></html>\n";
+ "<body>\n";
+const char *foot = "</body></html>\n";
(DIR) diff --git a/phroxy.c b/phroxy.c
t@@ -221,17 +221,13 @@ printheaders(char *ctype)
printf("Connection: close\r\n");
}
-char *
-htmlize(char *data, size_t *bodysize)
+int
+printmenu(int fd, char *data)
{
- size_t alen, blen;
- char *body = NULL;
char i, *p, a[LINE_MAX], *f[4];
char *ifmt = "%s\n";
char *afmt = "<a href='http://%s/%s:%s/%c%s'>%s (%s)</a>\n";
- blen = 0;
- body = NULL;
p = data;
while((p = strsep(&data, "\n"))) {
t@@ -252,57 +248,60 @@ htmlize(char *data, size_t *bodysize)
snprintf(a, sizeof(a), afmt, http_host, f[2], f[3], i, f[1], f[0], itemname(i));
}
- alen = strnlen(a, sizeof(a));
- body = realloc(body, blen + alen + 1);
- memcpy(body + blen, a, alen);
- blen += alen;
- body[blen] = '\0';
+ write(fd, a, strlen(a));
}
- if (bodysize)
- *bodysize = strnlen(body, blen);
-
- return body;
+ return 0;
}
-char *
-htmlwrap(char *data, size_t len, size_t *htmlsize)
+int
+printhtml(int fd, const char *data, size_t len)
{
- size_t hlen;
- char *html = NULL;
-
- hlen = strlen(htmlfmt) + len;
- html = malloc(hlen);
- if (!html)
- return NULL;
+ size_t r, n;
+ const char *s, *e;
- snprintf(html, hlen, htmlfmt, data);
+ n = 0;
+ while(n < len) {
+ s = data + n;
+ e = strstr(s, "\n\n");
+ r = e ? (size_t)(e - s) : strlen(s);
- if (htmlsize)
- *htmlsize = strnlen(html, hlen);
+ if (!r)
+ break;
- return html;
+ n += r + 2; /* go past "\n\n" */
+ write(fd, "<pre>", 5);
+ write(fd, s, r);
+ write(fd, "</pre>\n", 7);
+ }
+ return 0;
}
int
serveitem(char item, char *data, size_t len)
{
- char *send, *html;
+ char *send;
int sent;
+
+ if (!contenttype(item)) {
+ printhttp(415);
+ return 1;
+ }
+
+ printf("HTTP/1.1 200 OK\r\n");
+ printheaders(contenttype(item));
+
switch(item) {
- case '7': // search
case '1': // menu
- html = htmlize(data, &len);
- free(data);
- data = html;
- /* FALLTHROUGH */
-
case '0': // text
- html = htmlwrap(data, len, &len);
- free(data);
- data = html;
+ printf("\r\n");
+ write(1, head, strlen(head));
+ if (item == '1') printmenu(1, data);
+ if (item == '0') printhtml(1, data, len);
+ write(1, foot, strlen(foot));
break;
+
case '4': // BinHexed Macintosh file
case '5': // DOS binary archive of some sort
case '6': // uuencoded
t@@ -310,8 +309,18 @@ serveitem(char item, char *data, size_t len)
case 'g': // gif
case 'I': // image
case 'h': // http redirect
+ printf("Content-Length: %ld\r\n", len);
+ printf("\r\n");
+ send = data;
+ while (len > 0) {
+ if ((sent = write(1, send, len)) < 0)
+ return 1;
+ len -= sent;
+ send += sent;
+ }
break;
+ case '7': // search
case '2': // CSO phone-book server
case '3': // Error
case '8': // telnet session.
t@@ -319,26 +328,11 @@ serveitem(char item, char *data, size_t len)
case '+': // mirror link
default:
/* IGNORE */
- printhttp(415);
break;
}
- printf("HTTP/1.1 200 OK\r\n");
- printheaders(contenttype(item));
-
- printf("Content-Length: %ld\r\n", len);
- printf("\r\n");
- fflush(stdout);
-
- send = data;
- while (len > 0) {
- if ((sent = write(1, send, len)) < 0)
- return 1;
- len -= sent;
- send += sent;
- }
-
free(data);
+ fflush(stdout);
return 0;
}