commit 770f8d29ee699d4a55495f9e6286e6bb1fba65a1 from: Omar Polo date: Fri Apr 26 14:15:04 2024 UTC got-notify-http: fix I/O with TLS (again) We try to handle early replies from the server, so we call tls_read() at each "tick" of the event loop. For the TLS case, however, bufio_read() will set bio->wantev, and if we rely only on it we can deadlock trying to read data from the server without having sent all the request. Found out the hard way while trying to send several notifications in one go. ok stsp commit - 9a8d74891980ef72c6e4bb2f7d377738b3308d0f commit + 770f8d29ee699d4a55495f9e6286e6bb1fba65a1 blob - 67a9f9676ed29a79b0958dbcc5feedfe5137eec0 blob + 4ee2c0b6e836e4cf92abff873a5b9c94c9da2a21 --- gotd/libexec/got-notify-http/got-notify-http.c +++ gotd/libexec/got-notify-http/got-notify-http.c @@ -811,6 +811,16 @@ static inline int bufio2poll(struct bufio *bio) { int f, ret = 0; + + /* + * If we have data queued up, retry for both POLLIN and POLLOUT + * since we want to push this data to the server while still + * processing an eventual reply. Otherwise, we could wait + * indefinitely for the server to reply without us having + * sent the HTTP request completely. + */ + if (bio->wbuf.len) + return POLLIN|POLLOUT; f = bufio_ev(bio); if (f & BUFIO_WANT_READ)