phroxy

Gopher to HTTP proxy
git clone git://git.z3bra.org/phroxy.git
Log | Files | Refs | LICENSE

commit 5f381215e10e7696ffcb418cbc0f2f1a5f4aedb5
parent 6399fbf8c0ea8bb09ad819e86c4393845b5e1472
Author: Willy Goiffon <dev@z3bra.org>
Date:   Thu, 24 Sep 2020 09:36:43 +0200

Format text as HTML on the fly

Diffstat:
Mconfig.def.h | 8+++-----
Mphroxy.c | 102+++++++++++++++++++++++++++++++++++++------------------------------------------
2 files changed, 51 insertions(+), 59 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -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"; diff --git a/phroxy.c b/phroxy.c @@ -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"))) { @@ -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 @@ -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. @@ -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; }