__fallthrough;
case PROMEX_ST_DONE:
- /* no more data are expected. If the response buffer is
- * empty, be sure to add something (EOT block in this
- * case) to have something to send. It is important to
- * be sure the EOM flags will be handled by the
- * endpoint.
- */
- if (htx_is_empty(res_htx)) {
- if (!htx_add_endof(res_htx, HTX_BLK_EOT)) {
- applet_have_more_data(appctx);
- break;
- }
+ /* no more data are expected */
+ if (!htx_set_eom(res_htx)) {
+ applet_have_more_data(appctx);
+ break;
}
- res_htx->flags |= HTX_FL_EOM;
applet_set_eoi(appctx);
appctx->st0 = PROMEX_ST_END;
__fallthrough;
return !(htx->flags & HTX_FL_EOM);
}
-/* Set EOM flag in <htx>. This function is useful if the HTX message is empty.
- * In this case, an EOT block is appended first to ensure the EOM will be
- * forwarded as expected. This is a workaround as it is not possibly currently
- * to push an empty HTX DATA block.
+/* Set EOM flag in <htx>. This function must always be called to report the end
+ * of the message. Corresponding flags must never be added by hand, except from
+ * the HTX API itself. It must also be called after the last block of the
+ * message was added. Finally, this function takes care to add an EOT block if
+ * the HTX message is empty.
*
* Returns 1 on success else 0.
*/
if (appctx->st0 == HTX_CACHE_EOM) {
/* no more data are expected. */
- res_htx->flags |= HTX_FL_EOM;
+ htx_set_eom(res_htx);
applet_set_eoi(appctx);
se_fl_clr(appctx->sedesc, SE_FL_MAY_FASTFWD_PROD);
applet_fl_clr(appctx, APPCTX_FL_FASTFWD);
h1m->flags &= ~(H1_MF_CLEN|H1_MF_CHNK);
h1m->curr_len = h1m->body_len = 0;
h1m->state = H1_MSG_DONE;
- htx->flags |= HTX_FL_EOM;
}
else {
if (h1sl->rq.meth == HTTP_METH_HEAD)
if (((h1m->flags & H1_MF_CLEN) && h1m->body_len == 0) ||
(h1m->flags & (H1_MF_XFER_LEN|H1_MF_CLEN|H1_MF_CHNK)) == H1_MF_XFER_LEN) {
h1m->state = H1_MSG_DONE;
- htx->flags |= HTX_FL_EOM;
}
}
http_scheme_based_normalize(htx);
}
- end:
+ if (h1m->state == H1_MSG_DONE)
+ htx_set_eom(htx);
return 1;
+
output_full:
h1m_init_req(h1m);
h1m->flags |= (H1_MF_NO_PHDR|H1_MF_CLEAN_CONN_HDR);
h1m->flags |= H1_MF_XFER_LEN;
h1m->curr_len = h1m->body_len = 0;
h1m->state = H1_MSG_DONE;
- htx->flags |= HTX_FL_EOM;
}
else if ((h1m->flags & H1_MF_METH_HEAD) || (code >= 100 && code < 200) ||
(code == 204) || (code == 304)) {
h1m->flags |= H1_MF_XFER_LEN;
h1m->curr_len = h1m->body_len = 0;
- if (code >= 200) {
+ if (code >= 200)
flags |= HTX_SL_F_BODYLESS_RESP;
- htx->flags |= HTX_FL_EOM;
- }
h1m->state = H1_MSG_DONE;
}
else {
}
if (((h1m->flags & H1_MF_CLEN) && h1m->body_len == 0) ||
- (h1m->flags & (H1_MF_XFER_LEN|H1_MF_CLEN|H1_MF_CHNK)) == H1_MF_XFER_LEN) {
+ (h1m->flags & (H1_MF_XFER_LEN|H1_MF_CLEN|H1_MF_CHNK)) == H1_MF_XFER_LEN)
h1m->state = H1_MSG_DONE;
- htx->flags |= HTX_FL_EOM;
- }
}
flags |= h1m_htx_sl_flags(h1m);
goto error;
sl->info.res.status = code;
- end:
+ if (h1m->state == H1_MSG_DONE)
+ htx_set_eom(htx);
return 1;
+
output_full:
h1m_init_res(h1m);
h1m->flags |= (H1_MF_NO_PHDR|H1_MF_CLEAN_CONN_HDR);
total += sz;
if (!h1m->curr_len) {
h1m->state = H1_MSG_DONE;
- (*dsthtx)->flags |= HTX_FL_EOM;
+ htx_set_eom(*dsthtx);
}
}
else if (h1m->flags & H1_MF_CHNK) {
* body. Switch the message in DONE state
*/
h1m->state = H1_MSG_DONE;
- (*dsthtx)->flags |= HTX_FL_EOM;
+ htx_set_eom(*dsthtx);
}
else {
/* no content length, read till SHUTW */
goto error;
h1m->state = H1_MSG_DONE;
- dsthtx->flags |= HTX_FL_EOM;
+ htx_set_eom(dsthtx);
end:
return ret;
(*msgf & H2_MSGF_BODY_TUNNEL)) {
/* Request without body or tunnel requested */
sl_flags |= HTX_SL_F_BODYLESS;
- if (*msgf & H2_MSGF_BODY_TUNNEL)
- htx->flags |= HTX_FL_EOM;
}
if (*msgf & H2_MSGF_EXT_CONNECT) {
if (!htx_add_endof(htx, HTX_BLK_EOH))
goto fail;
+ if (*msgf & H2_MSGF_BODY_TUNNEL)
+ htx_set_eom(htx);
+
/* proceed to scheme-based normalization on target-URI */
if (fields & H2_PHDR_FND_SCHM)
http_scheme_based_normalize(htx);
(*msgf & H2_MSGF_BODY_TUNNEL)) {
/* Response without body or tunnel successfully established */
sl_flags |= HTX_SL_F_BODYLESS;
- if (*msgf & H2_MSGF_BODY_TUNNEL)
- htx->flags |= HTX_FL_EOM;
}
/* update the start line with last detected header info */
if (!htx_add_endof(htx, HTX_BLK_EOH))
goto fail;
+ if (*msgf & H2_MSGF_BODY_TUNNEL)
+ htx_set_eom(htx);
+
ret = 1;
return ret;
}
if (fin)
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
htx_to_buf(htx, &htx_buf);
htx = NULL;
}
if (fin)
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
/* Detect if an interim or final response was handled. */
if (sl->info.res.status >= 100 && sl->info.res.status < 200) {
}
if (fin)
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
out:
/* HTX may be non NULL if error before previous htx_to_buf(). */
}
if (fin && len == htx_sent)
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
out:
if (appbuf)
goto err;
if (eom)
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
htx_to_buf(htx, &hs->bo);
leave:
ret = 1;
goto err;
}
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
hs->flags |= HS_ST_HTTP_EOM_SENT;
htx_to_buf(htx, buf);
sl->info.res.status = 200;
if (hs->to_write > 0)
hs->to_write -= hstream_add_htx_data(hs, htx, hs->to_write);
if (hs->to_write <= 0) {
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
hs->flags |= HS_ST_HTTP_EOM_SENT;
}
htx_to_buf(htx, buf);
if (hs->to_write > 0)
hs->to_write -= hstream_add_htx_data(hs, htx, hs->to_write);
if (hs->to_write <= 0) {
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
hs->flags |= HS_ST_HTTP_EOM_SENT;
}
htx_to_buf(htx, &hs->res);
MAY_LJMP(check_args(L, 1, "set_eom"));
msg = MAY_LJMP(hlua_checkhttpmsg(L, 1));
htx = htxbuf(&msg->chn->buf);
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
return 0;
}
(body_len && !htx_add_data_atonce(htx, ist2(body, body_len))))
goto fail;
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
/* Now, forward the response and terminate the transaction */
s->txn.http->status = code;
* sure the EOM flags will be handled by the endpoint.
*/
res_htx = htx_from_buf(outbuf);
- if (htx_is_empty(res_htx)) {
- if (!htx_add_endof(res_htx, HTX_BLK_EOT)) {
- applet_have_more_data(ctx);
- yield = 1;
- goto out;
- }
+ if (!htx_set_eom(res_htx)) {
+ applet_have_more_data(ctx);
+ yield = 1;
+ goto out;
}
- res_htx->flags |= HTX_FL_EOM;
htx_to_buf(res_htx, outbuf);
applet_set_eoi(ctx);
applet_set_eos(ctx);
sl->info.req.meth = find_http_meth(istptr(meth), 3);
htx_add_endof(htx, HTX_BLK_EOH);
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
htx_to_buf(htx, &htx_buf);
hq_trace_req(meth, path, QMUX_EV_QCC_RECV, ist(TRC_LOC), __FUNCTION__, qcs, qcs->qcc);
}
if (fin && to_copy == htx_sent)
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
}
out:
if (!htx_add_endof(htx, HTX_BLK_EOH))
goto fail;
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
htx_to_buf(htx, &res->buf);
if (!(s->flags & SF_ERR_MASK))
if (!htx_add_endof(htx, HTX_BLK_EOH))
goto fail;
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
htx_to_buf(htx, &res->buf);
if (!(s->flags & SF_ERR_MASK))
channel_auto_close(res);
sc_schedule_abort(s->scb);
s->scb->flags |= SC_FL_EOI; /* The response is terminated, add EOI */
- htxbuf(&res->buf)->flags |= HTX_FL_EOM; /* no more data are expected */
+ if (!htx_is_empty(htx))
+ htx_set_eom(htx); /* no more data are expected */
}
else {
/* Send ASAP informational messages. Rely on SC_FL_EOI for final
(body && b_data(body) && !htx_add_data_atonce(htx, ist2(b_head(body), b_data(body)))))
goto fail;
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
}
leave:
/* If req.payload was set, does not set the end of stream which *MUST*
* be set in the callback */
if (!hc->ops.req_payload)
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
htx_to_buf(htx, &hc->req.buf);
/* if we copied all the data and the end flag is set */
if ((istlen(src) == ret) && end) {
- /* no more data are expected. If the HTX buffer is empty, be
- * sure to add something (EOT block in this case) to have
- * something to send. It is important to be sure the EOM flags
- * will be handled by the endpoint. Because the message is
- * empty, this should not fail. Otherwise it is an error
- */
- if (htx_is_empty(htx)) {
- if (!htx_add_endof(htx, HTX_BLK_EOT))
- goto end;
- }
- htx->flags |= HTX_FL_EOM;
+ /* no more data are expected */
+ if (!htx_set_eom(htx))
+ goto end;
}
htx_to_buf(htx, &hc->req.buf);
}
ret += sent;
}
-
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
return 1;
if (!(h1m->flags & H1_MF_XFER_LEN) && fstrm->state != FCGI_SS_ERROR &&
(fstrm->flags & FCGI_SF_ES_RCVD) && b_data(&fstrm->rxbuf) == total) {
TRACE_DEVEL("end of data", FCGI_EV_RSP_DATA, fconn->conn, fstrm);
- if (htx_is_empty(htx) && !htx_add_endof(htx, HTX_BLK_EOT))
+ if (!htx_set_eom(htx))
break;
- htx->flags |= HTX_FL_EOM;
h1m->state = H1_MSG_DONE;
TRACE_USER("H1 response fully rcvd", FCGI_EV_RSP_DATA|FCGI_EV_RSP_EOM, fconn->conn, fstrm, htx);
}
goto fail;
}
/* no more data are expected for this message */
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
*flags |= H2_SF_ES_RCVD;
}
}
if (appctx->st0 == STAT_HTTP_DONE) {
- /* no more data are expected. If the response buffer is empty,
- * be sure to add something (EOT block in this case) to have
- * something to send. It is important to be sure the EOM flags
- * will be handled by the endpoint.
- */
- if (htx_is_empty(res_htx)) {
- if (!htx_add_endof(res_htx, HTX_BLK_EOT)) {
- applet_fl_set(appctx, APPCTX_FL_OUTBLK_FULL);
- goto out;
- }
+ /* no more data are expected */
+ if (!htx_set_eom(res_htx)) {
+ applet_fl_set(appctx, APPCTX_FL_OUTBLK_FULL);
+ goto out;
}
- res_htx->flags |= HTX_FL_EOM;
applet_set_eoi(appctx);
se_fl_clr(appctx->sedesc, SE_FL_MAY_FASTFWD_PROD);
applet_fl_clr(appctx, APPCTX_FL_FASTFWD);
goto error_htx;
/* no more data are expected */
- htx->flags |= HTX_FL_EOM;
+ htx_set_eom(htx);
htx_to_buf(htx, &check->bo);
break;
}