phroxy

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

commit c9369fcdaa399b0f9ae97611a023837e72f7e3c3
parent f1491a5ecb91945b0ef4dc69aff9d8f05ce00fea
Author: Willy Goiffon <dev@z3bra.org>
Date:   Thu, 22 Oct 2020 14:08:52 +0200

Add simple support for search queries

Diffstat:
Mphroxy.c | 72+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 65 insertions(+), 7 deletions(-)

diff --git a/phroxy.c b/phroxy.c @@ -103,15 +103,21 @@ err: } int -sendselector(int sock, const char *selector) +sendselector(int sock, const char *selector, const char *search) { char *msg, *p; + char *fmt = "%s\r\n"; size_t ln; ssize_t n; ln = strlen(selector) + 3; + if (search) { + fmt = "%s\t%s\r\n"; + ln += strlen(search); + } + msg = p = malloc(ln); - snprintf(msg, ln--, "%s\r\n", selector); + snprintf(msg, ln--, fmt, selector, search); while ((n = write(sock, p, ln)) > 0) { ln -= n; @@ -125,6 +131,51 @@ sendselector(int sock, const char *selector) return n; } +static char +hex2bin(const unsigned char *in) +{ + int out; + + if (*in == '%') + in++; + + if ('A' <= in[0] && in[0] <= 'F') out = 16 * (in[0] - 'A' + 10); + if ('0' <= in[0] && in[0] <= '9') out = 16 * (in[0] - '0'); + + if ('A' <= in[1] && in[1] <= 'F') out += (in[1] - 'A' + 10); + if ('0' <= in[1] && in[1] <= '9') out += (in[1] - '0'); + + return out; +} + +char * +urldec(char *search) +{ + char *msg, *p; + + if (!search) + return NULL; + + msg = p = search; + for (p = msg; *p != '\0'; msg++, p++) { + switch(*p) { + case '+': + *msg = ' '; + break; + case '%': + *msg = hex2bin((unsigned char *)p); + p += 2; + break; + default: + *msg = *p; + } + } + *msg = '\0'; + + return search; +} + + char * getrawitem(int sock, size_t *sz) { @@ -252,6 +303,7 @@ printmenu(int fd, char *data) char i, *p, a[LINE_MAX], *f[4]; char *ifmt = "<div class='item'><span> </span><code>%s</code></div>\n"; char *afmt = "<div class='item'><span>%s</span><a href='http://%s/%s:%s/%c%s'>%s</a></div>\n"; + char *sfmt = "<div class='item'><span>%s</span><details><summary>%s</summary><form method='get' action='http://%s/%s:%s/%c%s'><input type='text' name='q'></form></details></div>\n"; p = data; @@ -271,6 +323,9 @@ printmenu(int fd, char *data) case 'i': snprintf(a, sizeof(a), ifmt, f[0]); break; + case '7': + snprintf(a, sizeof(a), sfmt, itemname(i), f[0], http_host, f[2], f[3], i, f[1]); + break; default: snprintf(a, sizeof(a), afmt, itemname(i), http_host, f[2], f[3], i, f[1], f[0]); } @@ -330,12 +385,13 @@ serveitem(char item, char *path, char *data, size_t len) printheaders(contenttype(item, path)); switch(item) { + case '7': // search case '1': // menu case '0': // text printf("\r\n"); fflush(stdout); write(1, head, strlen(head)); - if (item == '1') printmenu(1, data); + if (item == '1' || item == '7') printmenu(1, data); if (item == '0') printhtml(1, data, len); write(1, foot, strlen(foot)); break; @@ -359,7 +415,6 @@ serveitem(char item, char *path, char *data, size_t len) } break; - case '7': // search case '2': // CSO phone-book server case '3': // Error case '8': // telnet session. @@ -405,15 +460,18 @@ phroxy(char *url) if (!path || *path == '\0') path = "/"; - if((srch = strchr(path, '?'))) - *srch = '\t'; + if((srch = strchr(path, '?'))) { + *srch = '\0'; + srch += 3; /* go past "?q=" in URL, to fetch actual query */ + fprintf(stderr, "Search: %s\n", urldec(srch)); + } if ((sock = connectto(host, port)) < 0) { printhttp(500); return 1; } - if (!sendselector(sock, path)) + if (!sendselector(sock, path, urldec(srch))) data = getrawitem(sock, &len); close(sock);