Hi, quick comments inline.
On 6/1/15, Sunil Nimmagadda <su...@nimmagadda.net> wrote: > On Thu, May 21, 2015 at 11:16:09PM -0400, Ted Unangst wrote: >> Sunil Nimmagadda wrote: >> > Hi, >> > >> > The idea is to start with the subset of ftp(1) functionality needed >> > by pkg_add(1): >> > >> > ftp [-o output] url ... >> > >> > i.e., should be able to download files over HTTP(S) and FTP. >> > >> > This implementation works as FETCH_CMD for pkg_add(1) over HTTP(S). >> > >> > FTP is not yet done, but thinking of implementing just PASV and >> > RETR commands and drop command interpreter compeletely. >> > >> > The SMALL variant drops HTTPS and FTP support. >> > >> > Comments? >> >> screw ftp. just make a new util http, that just does http. > > Hi, > > Here is a work in progress version 2. Changes from previous diff... > 1. Drop ftp provision and rename the utility as http(1). > 2. HTTP redirect handling. > 3. Proxy support. > 4. Resume interrupted file transfer. > 5. Basic and Proxy Authorization. > > Todo: progressmeter, cookies, RFC1738 URL encoding/decoding and > maybe some more. > > Comments? > [...] > Index: http.c > =================================================================== > RCS file: http.c > diff -N http.c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ http.c 1 Jun 2015 09:02:59 -0000 [...] > +int > +proxy_connect(int s, struct url *url, struct url *proxy) > +{ > + FILE *fp; > + char hostname[HOST_NAME_MAX+1], *buf; > + const char *proxy_auth = NULL; > + size_t len; > + int code; > + > + if ((fp = fdopen(s, "r+")) == NULL) > + err(1, "http_connect: fdopen"); > + > + if (gethostname(hostname, sizeof(hostname)) != 0) > + hostname[0] = '\0'; Pretty sure the "Host:" header should indicate the remote host, not local. > + if (proxy->user[0] || proxy->pass[0]) > + proxy_auth = base64_encode(proxy->user, proxy->pass); > + > + fprintf(fp, > + "CONNECT %s:%s HTTP/1.0\r\n" > + "Host: %s\r\n" > + "User-Agent: %s\r\n" > + "%s%s" > + "\r\n", > + url->host, > + (url->port[0]) ? url->port : "80", > + hostname, > + ua, > + (proxy_auth) ? "Proxy-Authorization: Basic " : "", > + (proxy_auth) ? proxy_auth : ""); > + > + fflush(fp); > + if ((buf = http_getline(fp, &len)) == NULL) > + return (-1); > + > + if ((code = http_response_code(buf)) == -1) { > + free(buf); > + return (-1); > + } > + > + free(buf); > + if (code != 200) > + errx(1, "Error retrieving file: %s", errstr(code)); > + > + return (0); > +} > + > +const char * > +base64_encode(const char *user, const char *pass) > +{ > + static char basic_auth[BUFSIZ]; > + char *creds, b64_creds[BUFSIZ]; > + int ret; > + > + if ((ret = asprintf(&creds, "%s:%s", user, pass)) == -1) > + errx(1, "base64_encode: asprintf failed"); > + > + if (b64_ntop(creds, ret, b64_creds, sizeof(b64_creds)) == -1) > + errx(1, "error in base64 encoding"); > + > + free(creds); > + ret = snprintf(basic_auth, sizeof(basic_auth), "%s\r\n", b64_creds); > + if (ret == -1 || ret > sizeof(basic_auth)) > + errx(1, "base64_encode: basic_auth overflow"); > + > + return (basic_auth); > +} > + > +int > +http_get(int s, struct url *url, const char *fn, int resume, > + struct headers *hdrs) > +{ > + struct stat sb; > + char hostname[HOST_NAME_MAX+1], range[BUFSIZ]; > + const char *basic_auth = NULL; > + FILE *fin; > + char *buf; > + size_t len; > + int fd, flags, res = -1; > + > + if ((fin = fdopen(s, "r+")) == NULL) > + err(1, "http_get: fdopen"); > + > + if (gethostname(hostname, sizeof(hostname)) != 0) > + hostname[0] = '\0'; Same here. But afaik HTTP/1.0 doesn't require that header. --patrick > + if (stat(fn, &sb) == -1) > + resume = 0; > + else { > + snprintf(range, sizeof(range), > + "Range: bytes=%lld-\r\n", sb.st_size); > + } > + > + if (url->user[0] || url->pass[0]) > + basic_auth = base64_encode(url->user, url->pass); > + > + fprintf(fin, > + "GET %s HTTP/1.0\r\n" > + "Host: %s\r\n" > + "User-Agent: %s\r\n" > + "%s" > + "%s%s" > + "\r\n", > + (url->path[0]) ? url->path : "/", > + hostname, > + ua, > + (resume) ? range : "", > + (basic_auth) ? "Authorization: Basic " : "", > + (basic_auth) ? basic_auth : ""); [...]