diff options
author | sjg <sjg@FreeBSD.org> | 2014-04-27 08:13:43 +0000 |
---|---|---|
committer | sjg <sjg@FreeBSD.org> | 2014-04-27 08:13:43 +0000 |
commit | 0c7e03a54c8e7ddc9c3fe710f83d9ca53173692e (patch) | |
tree | b92e741b68057a24e381faa9809f32030d65574c /lib/libfetch/http.c | |
parent | c244fcbcaa61dc2a15995e7dbdf3ae8107bc2111 (diff) | |
parent | 69c3e6933b6946c49fe99b19986f018d71621980 (diff) | |
download | FreeBSD-src-0c7e03a54c8e7ddc9c3fe710f83d9ca53173692e.zip FreeBSD-src-0c7e03a54c8e7ddc9c3fe710f83d9ca53173692e.tar.gz |
Merge head
Diffstat (limited to 'lib/libfetch/http.c')
-rw-r--r-- | lib/libfetch/http.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c index 87535f0..cbbb8a8 100644 --- a/lib/libfetch/http.c +++ b/lib/libfetch/http.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2000-2013 Dag-Erling Smørgrav + * Copyright (c) 2000-2014 Dag-Erling Smørgrav * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -204,10 +204,11 @@ http_growbuf(struct httpio *io, size_t len) /* * Fill the input buffer, do chunk decoding on the fly */ -static int +static ssize_t http_fillbuf(struct httpio *io, size_t len) { ssize_t nbytes; + char ch; if (io->error) return (-1); @@ -229,7 +230,7 @@ http_fillbuf(struct httpio *io, size_t len) if (io->chunksize == 0) { switch (http_new_chunk(io)) { case -1: - io->error = 1; + io->error = EPROTO; return (-1); case 0: io->eof = 1; @@ -249,10 +250,8 @@ http_fillbuf(struct httpio *io, size_t len) io->chunksize -= io->buflen; if (io->chunksize == 0) { - char endl[2]; - - if (fetch_read(io->conn, endl, 2) != 2 || - endl[0] != '\r' || endl[1] != '\n') + if (fetch_read(io->conn, &ch, 1) != 1 || ch != '\r' || + fetch_read(io->conn, &ch, 1) != 1 || ch != '\n') return (-1); } @@ -268,31 +267,30 @@ static int http_readfn(void *v, char *buf, int len) { struct httpio *io = (struct httpio *)v; - int l, pos; + int rlen; if (io->error) return (-1); if (io->eof) return (0); - for (pos = 0; len > 0; pos += l, len -= l) { - /* empty buffer */ - if (!io->buf || io->bufpos == io->buflen) - if (http_fillbuf(io, len) < 1) - break; - l = io->buflen - io->bufpos; - if (len < l) - l = len; - memcpy(buf + pos, io->buf + io->bufpos, l); - io->bufpos += l; + /* empty buffer */ + if (!io->buf || io->bufpos == io->buflen) { + if ((rlen = http_fillbuf(io, len)) < 0) { + if ((errno = io->error) == EINTR) + io->error = 0; + return (-1); + } else if (rlen == 0) { + return (0); + } } - if (!pos && io->error) { - if (io->error == EINTR) - io->error = 0; - return (-1); - } - return (pos); + rlen = io->buflen - io->bufpos; + if (len < rlen) + rlen = len; + memcpy(buf, io->buf + io->bufpos, rlen); + io->bufpos += rlen; + return (rlen); } /* @@ -878,6 +876,12 @@ http_parse_mtime(const char *p, time_t *mtime) strncpy(locale, setlocale(LC_TIME, NULL), sizeof(locale)); setlocale(LC_TIME, "C"); r = strptime(p, "%a, %d %b %Y %H:%M:%S GMT", &tm); + /* + * Some proxies use UTC in response, but it should still be + * parsed. RFC2616 states GMT and UTC are exactly equal for HTTP. + */ + if (r == NULL) + r = strptime(p, "%a, %d %b %Y %H:%M:%S UTC", &tm); /* XXX should add support for date-2 and date-3 */ setlocale(LC_TIME, locale); if (r == NULL) |