This diff allows ftp(1) to change the User-Agent for HTTP(S) URL
requests via the FTPUSERAGENT environment variable (personally I prefer
HTTPUSERAGENT but FTPUSERAGENT is what's used by ftp(1) on other BSDs).

This is useful when fetching URLs that are sensitive to the User-Agent,
such as sites that send different content if you're using a mobile
browser/device.

I have tested this on amd64 and i386, including a make build/release and
a bsd.rd http install with the resulting sets.

Comments? OK?


Index: fetch.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.122
diff -u -p -u -p -r1.122 fetch.c
--- fetch.c     20 May 2014 01:25:23 -0000      1.122
+++ fetch.c     20 May 2014 02:47:40 -0000
@@ -893,10 +893,10 @@ again:
                if (cookie)
                        ftp_printf(fin, ssl, "GET %s HTTP/1.0\r\n"
                            "Proxy-Authorization: Basic %s%s\r\n%s\r\n\r\n",
-                           epath, cookie, buf ? buf : "", HTTP_USER_AGENT);
+                           epath, cookie, buf ? buf : "", httpuseragent);
                else
                        ftp_printf(fin, ssl, "GET %s HTTP/1.0\r\n%s%s\r\n\r\n",
-                           epath, buf ? buf : "", HTTP_USER_AGENT);
+                           epath, buf ? buf : "", httpuseragent);
 
        } else {
 #ifndef SMALL
@@ -954,7 +954,7 @@ again:
                        ftp_printf(fin, ssl, ":%s", port);
 #endif /* !SMALL */
                ftp_printf(fin, ssl, "\r\n%s%s\r\n\r\n",
-                   buf ? buf : "", HTTP_USER_AGENT);
+                   buf ? buf : "", httpuseragent);
                if (verbose)
                        fprintf(ttyout, "\n");
        }
@@ -1293,6 +1293,9 @@ auto_fetch(int argc, char *argv[], char 
        char *cp, *url, *host, *dir, *file, *portnum;
        char *username, *pass, *pathstart;
        char *ftpproxy, *httpproxy;
+#ifndef SMALL
+       char *uagent = NULL;
+#endif /* !SMALL */
        int rval, xargc;
        volatile int argpos;
        int dirhasglob, filehasglob, oautologin;
@@ -1313,6 +1316,18 @@ auto_fetch(int argc, char *argv[], char 
        if ((httpproxy = getenv(HTTP_PROXY)) != NULL && *httpproxy == '\0')
                httpproxy = NULL;
 
+       httpuseragent = HTTP_USER_AGENT;
+#ifndef SMALL
+       if ((cp = getenv("FTPUSERAGENT")) != NULL && *cp != '\0') {
+               /* Ensure that User-Agent value is in a single line. */
+               if (strcspn(cp, "\r\n") != strlen(cp))
+                       errx(1, "Invalid FTPUSERAGENT: %s.", cp);
+               if (asprintf(&uagent, "User-Agent: %s", cp) == -1)
+                       errx(1, "Can't allocate memory for HTTP(S) User-Agent");
+               httpuseragent = uagent;
+       }
+#endif /* !SMALL */
+
        /*
         * Loop through as long as there's files to fetch.
         */
@@ -1583,6 +1598,9 @@ bad_ftp_url:
        }
        if (connected && rval != -1)
                disconnect(0, NULL);
+#ifndef SMALL
+       free(uagent);
+#endif /* !SMALL */
        return (rval);
 }
 
@@ -1783,10 +1801,10 @@ proxy_connect(int socket, char *host, ch
        if (cookie) {
                l = asprintf(&connstr, "CONNECT %s:%s HTTP/1.1\r\n"
                        "Proxy-Authorization: Basic %s\r\n%s\r\n\r\n",
-                       host, port, cookie, HTTP_USER_AGENT);
+                       host, port, cookie, httpuseragent);
        } else {
                l = asprintf(&connstr, "CONNECT %s:%s HTTP/1.1\r\n%s\r\n\r\n",
-                       host, port, HTTP_USER_AGENT);
+                       host, port, httpuseragent);
        }
 
        if (l == -1)
Index: ftp.1
===================================================================
RCS file: /cvs/src/usr.bin/ftp/ftp.1,v
retrieving revision 1.91
diff -u -p -u -p -r1.91 ftp.1
--- ftp.1       23 Jan 2014 08:09:08 -0000      1.91
+++ ftp.1       24 Jan 2014 15:50:32 -0000
@@ -1705,6 +1705,10 @@ Default is port returned by a
 .Fn getservbyname
 lookup of
 .Dq ftpgate/tcp .
+.It Ev FTPUSERAGENT
+User-Agent header to use for HTTP(S) URL requests.
+The default value is
+.Dq Ox ftp .
 .It Ev HOME
 For default location of a
 .Pa .netrc
Index: ftp_var.h
===================================================================
RCS file: /cvs/src/usr.bin/ftp/ftp_var.h,v
retrieving revision 1.33
diff -u -p -u -p -r1.33 ftp_var.h
--- ftp_var.h   24 Dec 2013 13:00:59 -0000      1.33
+++ ftp_var.h   28 Dec 2013 04:24:15 -0000
@@ -181,6 +181,7 @@ char *httpport;                     /* port number to use 
 #ifndef SMALL
 char *httpsport;               /* port number to use for https connections */
 #endif /* !SMALL */
+char *httpuseragent;           /* user agent for http(s) connections */
 char *gateport;                        /* port number to use for gateftp 
connections */
 
 jmp_buf        toplevel;               /* non-local goto stuff for cmd scanner 
*/

Reply via email to