Since commit
b24260ec9 ("BUG/MEDIUM: http-client: Only consume input buffer
when hc one is empty"), the http-client applet stops to consume data as soon
as its response buffer is not empty. The applet is only unblocked when the
caller consumes these data by calling httpclient_res_xfer().
However, some callers are not consuming the response payload on the
fly. They are waiting for the end of the response to retrieve the whole
payload from the httpclient response buffer. For these callers,
httpclient_res_xfer() is never called. So the applet remains blocked and the
response is never fully received. The transfer is stuck till the server
timeout expiration.
To fix this, the HTTPCLIENT_O_RES_ACCUM option is added. It must be set by
the callers accumulating the whole response payload in the httpclient
response buffer. In that case, the applet must not stop the reception. Of
course, it means the whole payload must fit in the response buffer for these
callers. But it was already the case.
This patch depends on:
* "BUG/MEDIUM: http-client: Don't use the httpclient context if it was released".
It is required to fix a bug and must be backported as far as 3.3 with the
next commits.
/* options */
#define HTTPCLIENT_O_HTTPPROXY 0x00000001 /* the request must use an absolute URI */
#define HTTPCLIENT_O_RES_HTX 0x00000002 /* response is stored in HTX */
+#define HTTPCLIENT_O_RES_ACCUM 0x00000004 /* The whole response payload is accumulated in <res.buf>. The caller
+ * only retrieves it when the response is finished. */
/* States of the HTTP Client Appctx */
enum {
}
out:
- if (hc && appctx->st0 != HTTPCLIENT_S_RES_END && !b_is_null(&hc->res.buf)) {
- /* Don't accept more data while the httpclient response buffer is not empty */
+ if (hc && appctx->st0 != HTTPCLIENT_S_RES_END &&
+ !(hc->options & HTTPCLIENT_O_RES_ACCUM) && !b_is_null(&hc->res.buf)) {
+ /* Don't accept more data while the httpclient response buffer is
+ * not empty. It will be re-enabled by the caller, when it will
+ * consume these data.
+ *
+ * This is only performed for callers consuming the response on
+ * the fly. The others expect to retrieve the whole payload at
+ * the end of the response. For these ones, we must continue to
+ * fill the response buffer.
+ */
applet_wont_consume(appctx);
}
return;