mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-24 05:32:21 +00:00
MEDIUM: channel/htx: Add functions for forward HTX data
To ease the fast forwarding and the infinte forwarding on HTX proxies, 2 functions have been added to let the channel be almost aware of the way data are stored in its buffer. By calling these functions instead of legacy ones, we are sure to forward the right amount of data.
This commit is contained in:
parent
27ba2dc6d6
commit
b2aedea142
@ -36,6 +36,7 @@
|
|||||||
#include <types/global.h>
|
#include <types/global.h>
|
||||||
#include <types/stream.h>
|
#include <types/stream.h>
|
||||||
#include <types/stream_interface.h>
|
#include <types/stream_interface.h>
|
||||||
|
#include <types/htx.h>
|
||||||
|
|
||||||
#include <proto/task.h>
|
#include <proto/task.h>
|
||||||
|
|
||||||
@ -360,6 +361,24 @@ static inline void channel_forward_forever(struct channel *chn)
|
|||||||
chn->to_forward = CHN_INFINITE_FORWARD;
|
chn->to_forward = CHN_INFINITE_FORWARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline unsigned long long channel_htx_forward(struct channel *chn, struct htx *htx, unsigned long long bytes)
|
||||||
|
{
|
||||||
|
unsigned long long ret;
|
||||||
|
|
||||||
|
b_set_data(&chn->buf, htx->data);
|
||||||
|
ret = channel_forward(chn, bytes);
|
||||||
|
b_set_data(&chn->buf, b_size(&chn->buf));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void channel_htx_forward_forever(struct channel *chn, struct htx *htx)
|
||||||
|
{
|
||||||
|
b_set_data(&chn->buf, htx->data);
|
||||||
|
channel_forward_forever(chn);
|
||||||
|
b_set_data(&chn->buf, b_size(&chn->buf));
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* These functions are used to compute various channel content sizes */
|
/* These functions are used to compute various channel content sizes */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
@ -1245,10 +1245,8 @@ int htx_request_forward_body(struct stream *s, struct channel *req, int an_bit)
|
|||||||
* right length is then restored. We must do that, because when an HTX
|
* right length is then restored. We must do that, because when an HTX
|
||||||
* message is stored into a buffer, it appears as full.
|
* message is stored into a buffer, it appears as full.
|
||||||
*/
|
*/
|
||||||
b_set_data(&req->buf, co_data(req));
|
if ((msg->flags & HTTP_MSGF_XFER_LEN) && htx->extra)
|
||||||
if (msg->flags & HTTP_MSGF_XFER_LEN)
|
htx->extra -= channel_htx_forward(req, htx, htx->extra);
|
||||||
htx->extra -= channel_forward(req, htx->extra);
|
|
||||||
b_set_data(&req->buf, b_size(&req->buf));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the end-of-message is reached and if so, switch the message
|
/* Check if the end-of-message is reached and if so, switch the message
|
||||||
@ -2185,10 +2183,8 @@ int htx_response_forward_body(struct stream *s, struct channel *res, int an_bit)
|
|||||||
* right length is then restored. We must do that, because when an HTX
|
* right length is then restored. We must do that, because when an HTX
|
||||||
* message is stored into a buffer, it appears as full.
|
* message is stored into a buffer, it appears as full.
|
||||||
*/
|
*/
|
||||||
b_set_data(&res->buf, co_data(res));
|
if ((msg->flags & HTTP_MSGF_XFER_LEN) && htx->extra)
|
||||||
if (msg->flags & HTTP_MSGF_XFER_LEN)
|
htx->extra -= channel_htx_forward(res, htx, htx->extra);
|
||||||
htx->extra -= channel_forward(res, htx->extra);
|
|
||||||
b_set_data(&res->buf, b_size(&res->buf));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(msg->flags & HTTP_MSGF_XFER_LEN)) {
|
if (!(msg->flags & HTTP_MSGF_XFER_LEN)) {
|
||||||
|
62
src/stream.c
62
src/stream.c
@ -46,6 +46,7 @@
|
|||||||
#include <proto/hdr_idx.h>
|
#include <proto/hdr_idx.h>
|
||||||
#include <proto/hlua.h>
|
#include <proto/hlua.h>
|
||||||
#include <proto/http_rules.h>
|
#include <proto/http_rules.h>
|
||||||
|
#include <proto/htx.h>
|
||||||
#include <proto/listener.h>
|
#include <proto/listener.h>
|
||||||
#include <proto/log.h>
|
#include <proto/log.h>
|
||||||
#include <proto/raw_sock.h>
|
#include <proto/raw_sock.h>
|
||||||
@ -2184,19 +2185,27 @@ redo:
|
|||||||
channel_auto_close(req);
|
channel_auto_close(req);
|
||||||
c_adv(req, ci_data(req));
|
c_adv(req, ci_data(req));
|
||||||
|
|
||||||
/* We'll let data flow between the producer (if still connected)
|
if (IS_HTX_STRM(s) && s->txn) {
|
||||||
* to the consumer (which might possibly not be connected yet).
|
/* We'll let data flow between the producer (if still connected)
|
||||||
*/
|
* to the consumer (which might possibly not be connected yet).
|
||||||
if (!(req->flags & (CF_SHUTR|CF_SHUTW_NOW)))
|
*/
|
||||||
channel_forward_forever(req);
|
if (!(req->flags & (CF_SHUTR|CF_SHUTW_NOW)))
|
||||||
|
channel_htx_forward_forever(req, htxbuf(&req->buf));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* We'll let data flow between the producer (if still connected)
|
||||||
|
* to the consumer (which might possibly not be connected yet).
|
||||||
|
*/
|
||||||
|
if (!(req->flags & (CF_SHUTR|CF_SHUTW_NOW)))
|
||||||
|
channel_forward_forever(req);
|
||||||
|
|
||||||
/* Just in order to support fetching HTTP contents after start
|
/* Just in order to support fetching HTTP contents after start
|
||||||
* of forwarding when the HTTP forwarding analyser is not used,
|
* of forwarding when the HTTP forwarding analyser is not used,
|
||||||
* we simply reset msg->sov so that HTTP rewinding points to the
|
* we simply reset msg->sov so that HTTP rewinding points to the
|
||||||
* headers.
|
* headers.
|
||||||
*/
|
*/
|
||||||
if (IS_HTX_STRM(s) && s->txn)
|
|
||||||
s->txn->req.sov = s->txn->req.eoh + s->txn->req.eol - co_data(req);
|
s->txn->req.sov = s->txn->req.eoh + s->txn->req.eol - co_data(req);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if it is wise to enable kernel splicing to forward request data */
|
/* check if it is wise to enable kernel splicing to forward request data */
|
||||||
@ -2345,19 +2354,28 @@ redo:
|
|||||||
channel_auto_close(res);
|
channel_auto_close(res);
|
||||||
c_adv(res, ci_data(res));
|
c_adv(res, ci_data(res));
|
||||||
|
|
||||||
/* We'll let data flow between the producer (if still connected)
|
|
||||||
* to the consumer.
|
|
||||||
*/
|
|
||||||
if (!(res->flags & (CF_SHUTR|CF_SHUTW_NOW)))
|
|
||||||
channel_forward_forever(res);
|
|
||||||
|
|
||||||
/* Just in order to support fetching HTTP contents after start
|
if (IS_HTX_STRM(s) && s->txn) {
|
||||||
* of forwarding when the HTTP forwarding analyser is not used,
|
/* We'll let data flow between the producer (if still connected)
|
||||||
* we simply reset msg->sov so that HTTP rewinding points to the
|
* to the consumer.
|
||||||
* headers.
|
*/
|
||||||
*/
|
if (!(res->flags & (CF_SHUTR|CF_SHUTW_NOW)))
|
||||||
if (IS_HTX_STRM(s) && s->txn)
|
channel_htx_forward_forever(res, htxbuf(&res->buf));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* We'll let data flow between the producer (if still connected)
|
||||||
|
* to the consumer.
|
||||||
|
*/
|
||||||
|
if (!(res->flags & (CF_SHUTR|CF_SHUTW_NOW)))
|
||||||
|
channel_forward_forever(res);
|
||||||
|
|
||||||
|
/* Just in order to support fetching HTTP contents after start
|
||||||
|
* of forwarding when the HTTP forwarding analyser is not used,
|
||||||
|
* we simply reset msg->sov so that HTTP rewinding points to the
|
||||||
|
* headers.
|
||||||
|
*/
|
||||||
s->txn->rsp.sov = s->txn->rsp.eoh + s->txn->rsp.eol - co_data(res);
|
s->txn->rsp.sov = s->txn->rsp.eoh + s->txn->rsp.eol - co_data(res);
|
||||||
|
}
|
||||||
|
|
||||||
/* if we have no analyser anymore in any direction and have a
|
/* if we have no analyser anymore in any direction and have a
|
||||||
* tunnel timeout set, use it now. Note that we must respect
|
* tunnel timeout set, use it now. Note that we must respect
|
||||||
|
Loading…
Reference in New Issue
Block a user