Make fetch_read() return size_t like fread() does. It is bogus to

have one backing implementation that returns different values and
types than the other.  Handle error setting properly; i.e. bail
out if the internal read returned an error. Now we get a proper
error message when the the server resets our connection instead of
a warning that the right failed with an invalid argument.

The server used for testing was:
	http://capeweather.dyndns.org:8080/graphs/3474.png
Which seems to be unreliable :-)
This commit is contained in:
christos 2019-04-04 00:36:09 +00:00
parent 021d832a13
commit a5b9754eb4
3 changed files with 29 additions and 23 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: fetch.c,v 1.230 2018/02/11 02:51:58 christos Exp $ */
/* $NetBSD: fetch.c,v 1.231 2019/04/04 00:36:09 christos Exp $ */
/*-
* Copyright (c) 1997-2015 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: fetch.c,v 1.230 2018/02/11 02:51:58 christos Exp $");
__RCSID("$NetBSD: fetch.c,v 1.231 2019/04/04 00:36:09 christos Exp $");
#endif /* not lint */
/*
@ -1640,10 +1640,14 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
if (ischunked)
bufrem = MIN(chunksize, bufrem);
while (bufrem > 0) {
size_t nr = MIN((off_t)bufsize, bufrem);
flen = fetch_read(xferbuf, sizeof(char),
MIN((off_t)bufsize, bufrem), fin);
if (flen <= 0)
nr, fin);
if (flen == 0) {
if (fetch_error(fin))
goto chunkerror;
goto chunkdone;
}
bytes += flen;
bufrem -= flen;
if (fwrite(xferbuf, sizeof(char), flen, fout)
@ -1694,7 +1698,7 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
} while (ischunked);
/* XXX: deal with optional trailer & CRLF here? */
chunkerror:
if (hash && !progress && bytes > 0) {
if (bytes < mark)
(void)putc('#', ttyout);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ssl.c,v 1.6 2018/02/06 19:26:02 christos Exp $ */
/* $NetBSD: ssl.c,v 1.7 2019/04/04 00:36:09 christos Exp $ */
/*-
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
@ -34,7 +34,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: ssl.c,v 1.6 2018/02/06 19:26:02 christos Exp $");
__RCSID("$NetBSD: ssl.c,v 1.7 2019/04/04 00:36:09 christos Exp $");
#endif
#include <time.h>
@ -348,7 +348,7 @@ fetch_cache_data(struct fetch_connect *conn, char *src, size_t nbytes)
return 0;
}
ssize_t
size_t
fetch_read(void *ptr, size_t size, size_t nmemb, struct fetch_connect *conn)
{
struct timeval now, timeout, delta;
@ -408,6 +408,7 @@ fetch_read(void *ptr, size_t size, size_t nmemb, struct fetch_connect *conn)
else
rlen = fetch_nonssl_read(conn->sd, buf, len);
if (rlen == 0) {
conn->iseof = 1;
break;
} else if (rlen > 0) {
len -= rlen;
@ -415,9 +416,10 @@ fetch_read(void *ptr, size_t size, size_t nmemb, struct fetch_connect *conn)
total += rlen;
continue;
} else if (rlen == FETCH_READ_ERROR) {
conn->iserr = errno;
if (errno == EINTR)
fetch_cache_data(conn, start, total);
return -1;
return 0;
}
FD_ZERO(&readfds);
while (!FD_ISSET(conn->sd, &readfds)) {
@ -425,8 +427,8 @@ fetch_read(void *ptr, size_t size, size_t nmemb, struct fetch_connect *conn)
if (quit_time > 0) {
gettimeofday(&now, NULL);
if (!timercmp(&timeout, &now, >)) {
errno = ETIMEDOUT;
return -1;
conn->iserr = ETIMEDOUT;
return 0;
}
timersub(&timeout, &now, &delta);
}
@ -435,7 +437,8 @@ fetch_read(void *ptr, size_t size, size_t nmemb, struct fetch_connect *conn)
quit_time > 0 ? &delta : NULL) < 0) {
if (errno == EINTR)
continue;
return -1;
conn->iserr = errno;
return 0;
}
}
}
@ -451,7 +454,7 @@ char *
fetch_getln(char *str, int size, struct fetch_connect *conn)
{
size_t tmpsize;
ssize_t len;
size_t len;
char c;
if (conn->buf == NULL) {
@ -474,13 +477,12 @@ fetch_getln(char *str, int size, struct fetch_connect *conn)
conn->buflen = 0;
do {
len = fetch_read(&c, sizeof(c), 1, conn);
if (len == -1) {
conn->iserr = 1;
return NULL;
}
if (len == 0) {
conn->iseof = 1;
break;
if (conn->iserr)
return NULL;
if (conn->iseof)
break;
abort();
}
conn->buf[conn->buflen++] = c;
if (conn->buflen == conn->bufsize) {
@ -532,8 +534,8 @@ fetch_getline(struct fetch_connect *conn, char *buf, size_t buflen,
} else if (len == buflen - 1) { /* line too long */
while (1) {
char c;
ssize_t rlen = fetch_read(&c, sizeof(c), 1, conn);
if (rlen <= 0 || c == '\n')
size_t rlen = fetch_read(&c, sizeof(c), 1, conn);
if (rlen == 0 || c == '\n')
break;
}
if (errormsg)

View File

@ -1,4 +1,4 @@
/* $NetBSD: ssl.h,v 1.3 2015/09/12 19:38:42 wiz Exp $ */
/* $NetBSD: ssl.h,v 1.4 2019/04/04 00:36:09 christos Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@ int fetch_flush(struct fetch_connect *);
struct fetch_connect *fetch_open(const char *, const char *);
struct fetch_connect *fetch_fdopen(int, const char *);
int fetch_close(struct fetch_connect *);
ssize_t fetch_read(void *, size_t, size_t, struct fetch_connect *);
size_t fetch_read(void *, size_t, size_t, struct fetch_connect *);
char *fetch_getln(char *, int, struct fetch_connect *);
int fetch_getline(struct fetch_connect *, char *, size_t, const char **);
void fetch_set_ssl(struct fetch_connect *, void *);