commit a9d9f6e4088e82bc9a8388cda880fb5303840e28 from: Omar Polo date: Thu Apr 18 22:55:41 2024 UTC got-notify-http: fix I/O with TLS tls_write() may return TLS_WANT_READ. In that case, we're stuck trying to read while we have the request still in the buffer. So, we have to retry bufio_write() regardless of the POLLIN/POLLOUT state. We'd need this only in the TLS case, but in practice it doesn't harm for the plaintext case too. In fact, we're either waiting to flush the request or we're only reading the server reply. ok stsp commit - 02dab75a4ff7b71643c9c150a7254721785d8b0e commit + a9d9f6e4088e82bc9a8388cda880fb5303840e28 blob - 855a4b86c039fcefe9a9a40b0d2f4d826e81d66d blob + 60f89ca0e57362d2951dc69102b742825ac30059 --- gotd/libexec/got-notify-http/got-notify-http.c +++ gotd/libexec/got-notify-http/got-notify-http.c @@ -970,58 +970,56 @@ main(int argc, char **argv) if (ret == 0 || timeout.tv_sec <= 0) fatalx("timeout"); - if (bio.wbuf.len > 0 && (pfd.revents & POLLOUT)) { + if (bio.wbuf.len > 0) { if (bufio_write(&bio) == -1 && errno != EAGAIN) fatalx("bufio_write: %s", bufio_io_err(&bio)); } - if (pfd.revents & POLLIN) { - r = bufio_read(&bio); - if (r == -1 && errno != EAGAIN) - fatalx("bufio_read: %s", bufio_io_err(&bio)); - if (r == 0) - fatalx("unexpected EOF"); - for (;;) { - line = buf_getdelim(&bio.rbuf, "\r\n", &len); - if (line == NULL) - break; - if (response_code && *line == '\0') { - /* - * end of headers, don't bother - * reading the body, if there is. - */ - done = 1; - break; - } - if (response_code) { - buf_drain(&bio.rbuf, len); - continue; - } - spc = strchr(line, ' '); - if (spc == NULL) - fatalx("bad HTTP response from server"); - *spc++ = '\0'; - if (strcasecmp(line, "HTTP/1.1") != 0) - log_warnx("unexpected protocol: %s", - line); - line = spc; - - spc = strchr(line, ' '); - if (spc == NULL) - fatalx("bad HTTP response from server"); - *spc++ = '\0'; - - response_code = strtonum(line, 100, 599, - &errstr); - if (errstr != NULL) - log_warnx("response code is %s: %s", - errstr, line); + r = bufio_read(&bio); + if (r == -1 && errno != EAGAIN) + fatalx("bufio_read: %s", bufio_io_err(&bio)); + if (r == 0) + fatalx("unexpected EOF"); + for (;;) { + line = buf_getdelim(&bio.rbuf, "\r\n", &len); + if (line == NULL) + break; + if (response_code && *line == '\0') { + /* + * end of headers, don't bother + * reading the body, if there is. + */ + done = 1; + break; + } + if (response_code) { buf_drain(&bio.rbuf, len); + continue; } - if (done) - break; + spc = strchr(line, ' '); + if (spc == NULL) + fatalx("bad HTTP response from server"); + *spc++ = '\0'; + if (strcasecmp(line, "HTTP/1.1") != 0) + log_warnx("unexpected protocol: %s", line); + line = spc; + + spc = strchr(line, ' '); + if (spc == NULL) + fatalx("bad HTTP response from server"); + *spc++ = '\0'; + + response_code = strtonum(line, 100, 599, + &errstr); + if (errstr != NULL) + log_warnx("response code is %s: %s", + errstr, line); + + buf_drain(&bio.rbuf, len); } + if (done) + break; if (!feof(tmpfp) && bio.wbuf.len < sizeof(buf)) { len = fread(buf, 1, sizeof(buf), tmpfp);