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 : "");
[...]

Reply via email to