On Thu, Jun 12, 2014 at 06:32:00PM +0200, Alexander Hall wrote: > On June 11, 2014 6:18:19 AM CEST, Lawrence Teo <l...@openbsd.org> wrote: > >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 generally dislike passing options as environment variables. The use > case you describe does not really strike me as something I'd have in > my $ENV. > > Does any of the other ftp's have a corresponding switch for it?
Thanks for your feedback. As Adam Thompson also mentioned in his reply, the other ftp's don't have a corresponding switch for the User-Agent. The closest switch is FreeBSD's fetch(1) which uses --user-agent, but I don't think we want that. :) I only chose the environment variable approach because it's what's used by the other BSDs. But if a command-line option is preferred, I don't mind it at all. So here's an alternate implementation that uses -U to specify the User-Agent. After testing it, I find that I prefer it over using the environment variable... for starters, there's way less typing! :) Index: fetch.c =================================================================== RCS file: /cvs/src/usr.bin/ftp/fetch.c,v retrieving revision 1.122 diff -u -p -r1.122 fetch.c --- fetch.c 20 May 2014 01:25:23 -0000 1.122 +++ fetch.c 14 Jun 2014 02:45:41 -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,13 @@ auto_fetch(int argc, char *argv[], char if ((httpproxy = getenv(HTTP_PROXY)) != NULL && *httpproxy == '\0') httpproxy = NULL; + if (httpuseragent == NULL) + httpuseragent = HTTP_USER_AGENT; +#ifndef SMALL + else + uagent = httpuseragent; +#endif /* !SMALL */ + /* * Loop through as long as there's files to fetch. */ @@ -1583,6 +1593,9 @@ bad_ftp_url: } if (connected && rval != -1) disconnect(0, NULL); +#ifndef SMALL + free(uagent); +#endif /* !SMALL */ return (rval); } Index: ftp.1 =================================================================== RCS file: /cvs/src/usr.bin/ftp/ftp.1,v retrieving revision 1.91 diff -u -p -r1.91 ftp.1 --- ftp.1 23 Jan 2014 08:09:08 -0000 1.91 +++ ftp.1 14 Jun 2014 02:45:41 -0000 @@ -62,6 +62,7 @@ .Op Fl o Ar output .Op Fl S Ar ssl_options .Op Fl s Ar srcaddr +.Op Fl U Ar useragent .Sm off .No http[s]:// Oo Ar user : password No @ .Oc Ar host Oo : Ar port @@ -267,6 +268,11 @@ of the connection. Only useful on systems with more than one address. .It Fl t Enables packet tracing. +.It Fl U Ar useragent +Set +.Ar useragent +as the User-Agent for HTTP(S) URL requests. +If not specified, the default User-Agent is ``OpenBSD ftp''. .It Fl V Disable verbose mode, overriding the default of enabled when input is from a terminal. Index: ftp_var.h =================================================================== RCS file: /cvs/src/usr.bin/ftp/ftp_var.h,v retrieving revision 1.33 diff -u -p -r1.33 ftp_var.h --- ftp_var.h 24 Dec 2013 13:00:59 -0000 1.33 +++ ftp_var.h 14 Jun 2014 02:45:41 -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 */ Index: main.c =================================================================== RCS file: /cvs/src/usr.bin/ftp/main.c,v retrieving revision 1.87 diff -u -p -r1.87 main.c --- main.c 23 Jan 2014 00:39:15 -0000 1.87 +++ main.c 14 Jun 2014 02:45:41 -0000 @@ -198,9 +198,10 @@ main(volatile int argc, char *argv[]) #ifndef SMALL cookiefile = getenv("http_cookies"); #endif /* !SMALL */ + httpuseragent = NULL; while ((ch = getopt(argc, argv, - "46AaCc:dD:Eegik:mno:pP:r:S:s:tvV")) != -1) { + "46AaCc:dD:Eegik:mno:pP:r:S:s:tU:vV")) != -1) { switch (ch) { case '4': family = PF_INET; @@ -361,6 +362,21 @@ main(volatile int argc, char *argv[]) trace = 1; break; + case 'U': +#ifndef SMALL + /* Prevent multiple User-Agents. */ + if (httpuseragent) + errx(1, "User-Agent was already defined"); + /* Ensure that User-Agent value is in a single line. */ + if (strcspn(optarg, "\r\n") != strlen(optarg)) + errx(1, "Invalid User-Agent: %s.", optarg); + if (asprintf(&httpuseragent, "User-Agent: %s", + optarg) == -1) + errx(1, "Can't allocate memory for HTTP(S) " + "User-Agent"); +#endif /* !SMALL */ + break; + case 'v': verbose = 1; break; @@ -852,7 +868,7 @@ usage(void) #ifndef SMALL "[-S ssl_options] " "[-s srcaddr]\n" - " " + " [-U useragent] " #endif /* !SMALL */ "http" #ifndef SMALL