diff options
Diffstat (limited to 'net/libfetch/files/common.c')
-rw-r--r-- | net/libfetch/files/common.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/net/libfetch/files/common.c b/net/libfetch/files/common.c index 90fe09fb05e..c1e15871163 100644 --- a/net/libfetch/files/common.c +++ b/net/libfetch/files/common.c @@ -1,4 +1,4 @@ -/* $NetBSD: common.c,v 1.30 2016/10/20 21:22:18 joerg Exp $ */ +/* $NetBSD: common.c,v 1.31 2016/10/20 21:25:57 joerg Exp $ */ /*- * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav * Copyright (c) 2008, 2010 Joerg Sonnenberger <joerg@NetBSD.org> @@ -240,6 +240,7 @@ fetch_reopen(int sd) conn->next_buf = NULL; conn->next_len = 0; conn->sd = sd; + conn->buf_events = POLLIN; return (conn); } @@ -456,6 +457,7 @@ fetch_ssl(conn_t *conn, const struct url *URL, int verbose) fprintf(stderr, "SSL context creation failed\n"); return (-1); } + conn->buf_events = 0; SSL_set_fd(conn->ssl, conn->sd); #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT) if (!SSL_set_tlsext_host_name(conn->ssl, (char *)(uintptr_t)URL->host)) { @@ -537,9 +539,9 @@ fetch_read(conn_t *conn, char *buf, size_t len) } pfd.fd = conn->sd; - pfd.events = POLLIN; for (;;) { - if (fetchTimeout) { + pfd.events = conn->buf_events; + if (fetchTimeout && pfd.events) { do { timeout_cur = compute_timeout(&timeout_end); if (timeout_cur < 0) { @@ -558,9 +560,26 @@ fetch_read(conn_t *conn, char *buf, size_t len) } while (pfd.revents == 0); } #ifdef WITH_SSL - if (conn->ssl != NULL) + if (conn->ssl != NULL) { rlen = SSL_read(conn->ssl, buf, len); - else + if (rlen == -1) { + switch (SSL_get_error(conn->ssl, rlen)) { + case SSL_ERROR_WANT_READ: + conn->buf_events = POLLIN; + break; + case SSL_ERROR_WANT_WRITE: + conn->buf_events = POLLOUT; + break; + default: + errno = EIO; + fetch_syserr(); + return -1; + } + } else { + /* Assume buffering on the SSL layer. */ + conn->buf_events = 0; + } + } else #endif rlen = read(conn->sd, buf, len); if (rlen >= 0) |