tAdd simple support for search queries - phroxy - Gopher to HTTP proxy
 (HTM) git clone git://git.z3bra.org/phroxy.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit c9369fcdaa399b0f9ae97611a023837e72f7e3c3
 (DIR) parent f1491a5ecb91945b0ef4dc69aff9d8f05ce00fea
 (HTM) Author: Willy Goiffon <dev@z3bra.org>
       Date:   Thu, 22 Oct 2020 14:08:52 +0200
       
       Add simple support for search queries
       
       Diffstat:
         M phroxy.c                            |      72 ++++++++++++++++++++++++++++---
       
       1 file changed, 65 insertions(+), 7 deletions(-)
       ---
 (DIR) diff --git a/phroxy.c b/phroxy.c
       t@@ -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;
       t@@ -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)
        {
       t@@ -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;
        
       t@@ -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]);
                        }
       t@@ -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;
       t@@ -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.
       t@@ -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);