mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-18 03:30:43 +00:00
MINOR: stream: Add a function to validate TCP to H1 upgrades
TCP to H1 upgrades are buggy for now. When such upgrade is performed, a
crash is experienced. The bug is the result of the recent H1 mux
refactoring, and more specifically because of the commit c4bfa59f1
("MAJOR:
mux-h1: Create the client stream as later as possible"). Indeed, now the H1
mux is responsible to create the frontend conn-stream once the request
headers are fully received. Thus the TCP to H1 upgrade is a problem because
the frontend conn-stream already exists.
To fix the bug, we must keep this conn-stream and the associate stream and
use it in the H1 mux. To do so, the upgrade will be performed in two
steps. First, the mux is upgraded from mux-pt to mux-h1. Then, the mux-h1
performs the stream upgrade, once the request headers are fully received and
parsed. To do so, stream_upgrade_from_cs() must be used. This function set
the SF_HTX flags to switch the stream to HTX mode, it removes the SF_IGNORE
flags and eventually it fills the request channel with some input data.
This patch is required to fix the TCP to H1 upgrades and is intimately
linked with the next commits.
This commit is contained in:
parent
39c7b6b09d
commit
4ef84c9c41
@ -60,6 +60,7 @@ extern struct data_cb sess_conn_cb;
|
||||
|
||||
struct stream *stream_new(struct session *sess, enum obj_type *origin, struct buffer *input);
|
||||
int stream_create_from_cs(struct conn_stream *cs, struct buffer *input);
|
||||
int stream_upgrade_from_cs(struct conn_stream *cs, struct buffer *input);
|
||||
|
||||
/* kill a stream and set the termination flags to <why> (one of SF_ERR_*) */
|
||||
void stream_shutdown(struct stream *stream, int why);
|
||||
|
32
src/stream.c
32
src/stream.c
@ -285,6 +285,38 @@ int stream_create_from_cs(struct conn_stream *cs, struct buffer *input)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Upgrade an existing TCP stream for connection <conn>. Return < 0 on error.
|
||||
* This is only valid right after a TCP to H1 upgrade. The stream should be
|
||||
* "reativated" by removing SF_IGNORE flag. And the right mode must be set.
|
||||
* On success, <input> buffer is transferred to the stream and thus points to
|
||||
* BUF_NULL. On error, it is unchanged and it is the caller responsibility to
|
||||
* release it (this never happens for now).
|
||||
*/
|
||||
int stream_upgrade_from_cs(struct conn_stream *cs, struct buffer *input)
|
||||
{
|
||||
struct stream_interface *si = cs->data;
|
||||
struct stream *s = si_strm(si);
|
||||
|
||||
if (cs->conn->mux->flags & MX_FL_HTX)
|
||||
s->flags |= SF_HTX;
|
||||
|
||||
if (!b_is_null(input)) {
|
||||
/* Xfer the input buffer to the request channel. <input> will
|
||||
* than point to BUF_NULL. From this point, it is the stream
|
||||
* responsibility to release it.
|
||||
*/
|
||||
s->req.buf = *input;
|
||||
*input = BUF_NULL;
|
||||
s->req.total = (IS_HTX_STRM(s) ? htxbuf(&s->req.buf)->data : b_data(&s->req.buf));
|
||||
s->req.flags |= (s->req.total ? CF_READ_PARTIAL : 0);
|
||||
}
|
||||
|
||||
s->flags &= ~SF_IGNORE;
|
||||
|
||||
task_wakeup(s->task, TASK_WOKEN_INIT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Callback used to wake up a stream when an input buffer is available. The
|
||||
* stream <s>'s stream interfaces are checked for a failed buffer allocation
|
||||
* as indicated by the presence of the SI_FL_RXBLK_ROOM flag and the lack of a
|
||||
|
Loading…
Reference in New Issue
Block a user