return 0;
}
- res = h2_get_buf(h2c, br_tail(h2c->mbuf));
- if (!res) {
+ res = br_tail(h2c->mbuf);
+ if (!h2_get_buf(h2c, res)) {
h2c->flags |= H2_CF_MUX_MALLOC;
h2c->flags |= H2_CF_DEM_MROOM;
return 0;
return 0;
}
- res = h2_get_buf(h2c, br_tail(h2c->mbuf));
- if (!res) {
+ res = br_tail(h2c->mbuf);
+ if (!h2_get_buf(h2c, res)) {
h2c->flags |= H2_CF_MUX_MALLOC;
h2c->flags |= H2_CF_DEM_MROOM;
return 0;
return 0;
}
- res = h2_get_buf(h2c, br_tail(h2c->mbuf));
- if (!res) {
+ res = br_tail(h2c->mbuf);
+ if (!h2_get_buf(h2c, res)) {
h2c->flags |= H2_CF_MUX_MALLOC;
if (h2s)
h2s->flags |= H2_SF_BLK_MROOM;
return 0;
}
- res = h2_get_buf(h2c, br_tail(h2c->mbuf));
- if (!res) {
+ res = br_tail(h2c->mbuf);
+ if (!h2_get_buf(h2c, res)) {
h2c->flags |= H2_CF_MUX_MALLOC;
h2s->flags |= H2_SF_BLK_MROOM;
return 0;
return 0;
}
- res = h2_get_buf(h2c, br_tail(h2c->mbuf));
- if (!res) {
+ res = br_tail(h2c->mbuf);
+ if (!h2_get_buf(h2c, res)) {
h2c->flags |= H2_CF_MUX_MALLOC;
h2c->flags |= H2_CF_DEM_MROOM;
return 0;
return 0;
}
- res = h2_get_buf(h2c, br_tail(h2c->mbuf));
- if (!res) {
+ res = br_tail(h2c->mbuf);
+ if (!h2_get_buf(h2c, res)) {
h2c->flags |= H2_CF_MUX_MALLOC;
h2s->flags |= H2_SF_BLK_MROOM;
return 0;
return 0;
}
- res = h2_get_buf(h2c, br_tail(h2c->mbuf));
- if (!res) {
+ res = br_tail(h2c->mbuf);
+ if (!h2_get_buf(h2c, res)) {
h2c->flags |= H2_CF_MUX_MALLOC;
h2c->flags |= H2_CF_DEM_MROOM;
return 0;
return 0;
}
- res = h2_get_buf(h2c, br_tail(h2c->mbuf));
- if (!res) {
+ res = br_tail(h2c->mbuf);
+ if (!h2_get_buf(h2c, res)) {
h2c->flags |= H2_CF_MUX_MALLOC;
h2c->flags |= H2_CF_DEM_MROOM;
return 0;
return 0;
}
- res = h2_get_buf(h2c, br_tail(h2c->mbuf));
- if (!res) {
+ res = br_tail(h2c->mbuf);
+ if (!h2_get_buf(h2c, res)) {
h2c->flags |= H2_CF_MUX_MALLOC;
h2c->flags |= H2_CF_DEM_MROOM;
return 0;
struct h2c *h2c = h2s->h2c;
struct h1m *h1m = &h2s->h1m;
struct buffer outbuf;
+ struct buffer *mbuf;
union h1_sl sl;
int es_now = 0;
int ret = 0;
return 0;
}
- if (!h2_get_buf(h2c, br_tail(h2c->mbuf))) {
- h2c->flags |= H2_CF_MUX_MALLOC;
- h2s->flags |= H2_SF_BLK_MROOM;
- return 0;
- }
-
/* First, try to parse the H1 response and index it into <list>.
* NOTE! Since it comes from haproxy, we *know* that a response header
* block does not wrap and we can safely read it this way without
h1m->curr_len = h1m->body_len = 0;
}
+ mbuf = br_tail(h2c->mbuf);
+ if (!h2_get_buf(h2c, mbuf)) {
+ h2c->flags |= H2_CF_MUX_MALLOC;
+ h2s->flags |= H2_SF_BLK_MROOM;
+ return 0;
+ }
+
chunk_reset(&outbuf);
while (1) {
- outbuf.area = b_tail(br_tail(h2c->mbuf));
- outbuf.size = b_contig_space(br_tail(h2c->mbuf));
- outbuf.data = 0;
-
- if (outbuf.size >= 9 || !b_space_wraps(br_tail(h2c->mbuf)))
+ outbuf = b_make(b_tail(mbuf), b_contig_space(mbuf), 0, 0);
+ if (outbuf.size >= 9 || !b_space_wraps(mbuf))
break;
realign_again:
- b_slow_realign(br_tail(h2c->mbuf), trash.area, b_data(br_tail(h2c->mbuf)));
+ b_slow_realign(mbuf, trash.area, b_data(mbuf));
}
if (outbuf.size < 9)
}
if (!hpack_encode_str_status(&outbuf, h2s->status, list[0].v)) {
- if (b_space_wraps(br_tail(h2c->mbuf)))
+ if (b_space_wraps(mbuf))
goto realign_again;
goto full;
}
if (!hpack_encode_header(&outbuf, list[hdr].n, list[hdr].v)) {
/* output full */
- if (b_space_wraps(br_tail(h2c->mbuf)))
+ if (b_space_wraps(mbuf))
goto realign_again;
goto full;
}
max -= ret;
/* commit the H2 response */
- b_add(br_tail(h2c->mbuf), outbuf.data);
+ b_add(mbuf, outbuf.data);
h2s->flags |= H2_SF_HEADERS_SENT;
if (es_now) {
struct h2c *h2c = h2s->h2c;
struct h1m *h1m = &h2s->h1m;
struct buffer outbuf;
+ struct buffer *mbuf;
int ret = 0;
size_t total = 0;
int es_now = 0;
goto end;
}
- if (!h2_get_buf(h2c, br_tail(h2c->mbuf))) {
+ mbuf = br_tail(h2c->mbuf);
+ if (!h2_get_buf(h2c, mbuf)) {
h2c->flags |= H2_CF_MUX_MALLOC;
h2s->flags |= H2_SF_BLK_MROOM;
goto end;
chunk_reset(&outbuf);
while (1) {
- outbuf.area = b_tail(br_tail(h2c->mbuf));
- outbuf.size = b_contig_space(br_tail(h2c->mbuf));
- outbuf.data = 0;
-
- if (outbuf.size >= 9 || !b_space_wraps(br_tail(h2c->mbuf)))
+ outbuf = b_make(b_tail(mbuf), b_contig_space(mbuf), 0, 0);
+ if (outbuf.size >= 9 || !b_space_wraps(mbuf))
break;
realign_again:
/* If there are pending data in the output buffer, and we have
* still perform a copy anyway. Otherwise we'll pretend the mbuf
* is full and wait, to save some slow realign calls.
*/
- if ((max + 9 > b_room(br_tail(h2c->mbuf)) || max >= b_size(br_tail(h2c->mbuf)) / 4)) {
+ if ((max + 9 > b_room(mbuf) || max >= b_size(mbuf) / 4)) {
h2c->flags |= H2_CF_MUX_MFULL;
h2s->flags |= H2_SF_BLK_MROOM;
goto end;
}
- b_slow_realign(br_tail(h2c->mbuf), trash.area, b_data(br_tail(h2c->mbuf)));
+ b_slow_realign(mbuf, trash.area, b_data(mbuf));
}
if (outbuf.size < 9) {
* the amount of data to move is low, let's defragment the
* buffer now.
*/
- if (b_space_wraps(br_tail(h2c->mbuf)) &&
- (size + 9 <= b_room(br_tail(h2c->mbuf))) &&
- b_data(br_tail(h2c->mbuf)) <= MAX_DATA_REALIGN)
+ if (b_space_wraps(mbuf) &&
+ (size + 9 <= b_room(mbuf)) &&
+ b_data(mbuf) <= MAX_DATA_REALIGN)
goto realign_again;
size = outbuf.size - 9;
}
outbuf.area[4] |= H2_F_DATA_END_STREAM;
/* commit the H2 response */
- b_add(br_tail(h2c->mbuf), size + 9);
+ b_add(mbuf, size + 9);
/* consume incoming H1 response */
if (size > 0) {
struct htx_blk *blk;
struct htx_blk *blk_end;
struct buffer outbuf;
+ struct buffer *mbuf;
struct htx_sl *sl;
enum htx_blk_type type;
int es_now = 0;
return 0;
}
- if (!h2_get_buf(h2c, br_tail(h2c->mbuf))) {
+ mbuf = br_tail(h2c->mbuf);
+ if (!h2_get_buf(h2c, mbuf)) {
h2c->flags |= H2_CF_MUX_MALLOC;
h2s->flags |= H2_SF_BLK_MROOM;
return 0;
chunk_reset(&outbuf);
while (1) {
- outbuf.area = b_tail(br_tail(h2c->mbuf));
- outbuf.size = b_contig_space(br_tail(h2c->mbuf));
- outbuf.data = 0;
-
- if (outbuf.size >= 9 || !b_space_wraps(br_tail(h2c->mbuf)))
+ outbuf = b_make(b_tail(mbuf), b_contig_space(mbuf), 0, 0);
+ if (outbuf.size >= 9 || !b_space_wraps(mbuf))
break;
realign_again:
- b_slow_realign(br_tail(h2c->mbuf), trash.area, b_data(br_tail(h2c->mbuf)));
+ b_slow_realign(mbuf, trash.area, b_data(mbuf));
}
if (outbuf.size < 9)
/* encode status, which necessarily is the first one */
if (!hpack_encode_int_status(&outbuf, h2s->status)) {
- if (b_space_wraps(br_tail(h2c->mbuf)))
+ if (b_space_wraps(mbuf))
goto realign_again;
goto full;
}
if (!hpack_encode_header(&outbuf, list[hdr].n, list[hdr].v)) {
/* output full */
- if (b_space_wraps(br_tail(h2c->mbuf)))
+ if (b_space_wraps(mbuf))
goto realign_again;
goto full;
}
outbuf.area[4] |= H2_F_HEADERS_END_STREAM;
/* commit the H2 response */
- b_add(br_tail(h2c->mbuf), outbuf.data);
+ b_add(mbuf, outbuf.data);
/* indicates the HEADERS frame was sent, except for 1xx responses. For
* 1xx responses, another HEADERS frame is expected.
struct htx_blk *blk;
struct htx_blk *blk_end;
struct buffer outbuf;
+ struct buffer *mbuf;
struct htx_sl *sl;
struct ist meth, path, auth;
enum htx_blk_type type;
return 0;
}
- if (!h2_get_buf(h2c, br_tail(h2c->mbuf))) {
+ mbuf = br_tail(h2c->mbuf);
+ if (!h2_get_buf(h2c, mbuf)) {
h2c->flags |= H2_CF_MUX_MALLOC;
h2s->flags |= H2_SF_BLK_MROOM;
return 0;
chunk_reset(&outbuf);
while (1) {
- outbuf.area = b_tail(br_tail(h2c->mbuf));
- outbuf.size = b_contig_space(br_tail(h2c->mbuf));
- outbuf.data = 0;
-
- if (outbuf.size >= 9 || !b_space_wraps(br_tail(h2c->mbuf)))
+ outbuf = b_make(b_tail(mbuf), b_contig_space(mbuf), 0, 0);
+ if (outbuf.size >= 9 || !b_space_wraps(mbuf))
break;
realign_again:
- b_slow_realign(br_tail(h2c->mbuf), trash.area, b_data(br_tail(h2c->mbuf)));
+ b_slow_realign(mbuf, trash.area, b_data(mbuf));
}
if (outbuf.size < 9)
/* encode the method, which necessarily is the first one */
if (!hpack_encode_method(&outbuf, sl->info.req.meth, meth)) {
- if (b_space_wraps(br_tail(h2c->mbuf)))
+ if (b_space_wraps(mbuf))
goto realign_again;
goto full;
}
/* encode the scheme which is always "https" (or 0x86 for "http") */
if (!hpack_encode_scheme(&outbuf, ist("https"))) {
/* output full */
- if (b_space_wraps(br_tail(h2c->mbuf)))
+ if (b_space_wraps(mbuf))
goto realign_again;
goto full;
}
/* encode the path, which necessarily is the second one */
if (!hpack_encode_path(&outbuf, path)) {
/* output full */
- if (b_space_wraps(br_tail(h2c->mbuf)))
+ if (b_space_wraps(mbuf))
goto realign_again;
goto full;
}
if (auth.ptr && !hpack_encode_header(&outbuf, ist(":authority"), auth)) {
/* output full */
- if (b_space_wraps(br_tail(h2c->mbuf)))
+ if (b_space_wraps(mbuf))
goto realign_again;
goto full;
}
if (!hpack_encode_header(&outbuf, list[hdr].n, list[hdr].v)) {
/* output full */
- if (b_space_wraps(br_tail(h2c->mbuf)))
+ if (b_space_wraps(mbuf))
goto realign_again;
goto full;
}
outbuf.area[4] |= H2_F_HEADERS_END_STREAM;
/* commit the H2 response */
- b_add(br_tail(h2c->mbuf), outbuf.data);
+ b_add(mbuf, outbuf.data);
h2s->flags |= H2_SF_HEADERS_SENT;
h2s->st = H2_SS_OPEN;
struct h2c *h2c = h2s->h2c;
struct htx *htx;
struct buffer outbuf;
+ struct buffer *mbuf;
size_t total = 0;
int es_now = 0;
int bsize; /* htx block size */
goto end;
}
- if (!h2_get_buf(h2c, br_tail(h2c->mbuf))) {
+ mbuf = br_tail(h2c->mbuf);
+ if (!h2_get_buf(h2c, mbuf)) {
h2c->flags |= H2_CF_MUX_MALLOC;
h2s->flags |= H2_SF_BLK_MROOM;
goto end;
if (unlikely(fsize == count &&
htx->used == 1 && type == HTX_BLK_DATA &&
fsize <= h2s->mws && fsize <= h2c->mws && fsize <= h2c->mfs)) {
- void *old_area = br_tail(h2c->mbuf)->area;
+ void *old_area = mbuf->area;
- if (b_data(br_tail(h2c->mbuf))) {
+ if (b_data(mbuf)) {
/* Too bad there are data left there. We're willing to memcpy/memmove
* up to 1/4 of the buffer, which means that it's OK to copy a large
* frame into a buffer containing few data if it needs to be realigned,
* and that it's also OK to copy few data without realigning. Otherwise
* we'll pretend the mbuf is full and wait for it to become empty.
*/
- if (fsize + 9 <= b_room(br_tail(h2c->mbuf)) &&
- (b_data(br_tail(h2c->mbuf)) <= b_size(br_tail(h2c->mbuf)) / 4 ||
- (fsize <= b_size(br_tail(h2c->mbuf)) / 4 && fsize + 9 <= b_contig_space(br_tail(h2c->mbuf)))))
+ if (fsize + 9 <= b_room(mbuf) &&
+ (b_data(mbuf) <= b_size(mbuf) / 4 ||
+ (fsize <= b_size(mbuf) / 4 && fsize + 9 <= b_contig_space(mbuf))))
goto copy;
h2c->flags |= H2_CF_MUX_MFULL;
/* map an H2 frame to the HTX block so that we can put the
* frame header there.
*/
- br_tail(h2c->mbuf)->area = buf->area;
- br_tail(h2c->mbuf)->head = sizeof(struct htx) + blk->addr - 9;
- br_tail(h2c->mbuf)->data = fsize + 9;
- outbuf.area = b_head(br_tail(h2c->mbuf));
+ *mbuf = b_make(buf->area, buf->size, sizeof(struct htx) + blk->addr - 9, fsize + 9);
+ outbuf.area = b_head(mbuf);
/* prepend an H2 DATA frame header just before the DATA block */
memcpy(outbuf.area, "\x00\x00\x00\x00\x00", 5);
/* for DATA and EOM we'll have to emit a frame, even if empty */
while (1) {
- outbuf.area = b_tail(br_tail(h2c->mbuf));
- outbuf.size = b_contig_space(br_tail(h2c->mbuf));
- outbuf.data = 0;
-
- if (outbuf.size >= 9 || !b_space_wraps(br_tail(h2c->mbuf)))
+ outbuf = b_make(b_tail(mbuf), b_contig_space(mbuf), 0, 0);
+ if (outbuf.size >= 9 || !b_space_wraps(mbuf))
break;
realign_again:
- b_slow_realign(br_tail(h2c->mbuf), trash.area, b_data(br_tail(h2c->mbuf)));
+ b_slow_realign(mbuf, trash.area, b_data(mbuf));
}
if (outbuf.size < 9) {
* the amount of data to move is low, let's defragment the
* buffer now.
*/
- if (b_space_wraps(br_tail(h2c->mbuf)) &&
- (fsize + 9 <= b_room(br_tail(h2c->mbuf))) &&
- b_data(br_tail(h2c->mbuf)) <= MAX_DATA_REALIGN)
+ if (b_space_wraps(mbuf) &&
+ (fsize + 9 <= b_room(mbuf)) &&
+ b_data(mbuf) <= MAX_DATA_REALIGN)
goto realign_again;
fsize = outbuf.size - 9;
outbuf.area[4] |= H2_F_DATA_END_STREAM;
/* commit the H2 response */
- b_add(br_tail(h2c->mbuf), fsize + 9);
+ b_add(mbuf, fsize + 9);
/* consume incoming HTX block, including EOM */
total += fsize;
struct htx_blk *blk;
struct htx_blk *blk_end;
struct buffer outbuf;
+ struct buffer *mbuf;
struct h1m h1m;
enum htx_blk_type type;
uint32_t size;
goto end;
}
- if (!h2_get_buf(h2c, br_tail(h2c->mbuf))) {
+ mbuf = br_tail(h2c->mbuf);
+ if (!h2_get_buf(h2c, mbuf)) {
h2c->flags |= H2_CF_MUX_MALLOC;
h2s->flags |= H2_SF_BLK_MROOM;
goto end;
chunk_reset(&outbuf);
while (1) {
- outbuf.area = b_tail(br_tail(h2c->mbuf));
- outbuf.size = b_contig_space(br_tail(h2c->mbuf));
- outbuf.data = 0;
-
- if (outbuf.size >= 9 || !b_space_wraps(br_tail(h2c->mbuf)))
+ outbuf = b_make(b_tail(mbuf), b_contig_space(mbuf), 0, 0);
+ if (outbuf.size >= 9 || !b_space_wraps(mbuf))
break;
realign_again:
- b_slow_realign(br_tail(h2c->mbuf), trash.area, b_data(br_tail(h2c->mbuf)));
+ b_slow_realign(mbuf, trash.area, b_data(mbuf));
}
if (outbuf.size < 9)
if (!hpack_encode_header(&outbuf, list[idx].n, list[idx].v)) {
/* output full */
- if (b_space_wraps(br_tail(h2c->mbuf)))
+ if (b_space_wraps(mbuf))
goto realign_again;
goto full;
}
h2_set_frame_size(outbuf.area, outbuf.data - 9);
/* commit the H2 response */
- b_add(br_tail(h2c->mbuf), outbuf.data);
+ b_add(mbuf, outbuf.data);
h2s->flags |= H2_SF_ES_SENT;
if (h2s->st == H2_SS_OPEN)
int send_cnt = 0;
int tree_cnt = 0;
int orph_cnt = 0;
+ struct buffer *tmbuf;
if (!h2c)
return;
node = eb32_next(node);
}
+ tmbuf = br_tail(h2c->mbuf);
chunk_appendf(msg, " h2c.st0=%d .err=%d .maxid=%d .lastid=%d .flg=0x%04x"
" .nbst=%u .nbcs=%u .fctl_cnt=%d .send_cnt=%d .tree_cnt=%d"
" .orph_cnt=%d .sub=%d .dsi=%d .dbuf=%u@%p+%u/%u .msi=%d .mbuf=%u@%p+%u/%u",
(unsigned int)b_data(&h2c->dbuf), b_orig(&h2c->dbuf),
(unsigned int)b_head_ofs(&h2c->dbuf), (unsigned int)b_size(&h2c->dbuf),
h2c->msi,
- (unsigned int)b_data(br_tail(h2c->mbuf)), b_orig(br_tail(h2c->mbuf)),
- (unsigned int)b_head_ofs(br_tail(h2c->mbuf)), (unsigned int)b_size(br_tail(h2c->mbuf)));
+ (unsigned int)b_data(tmbuf), b_orig(tmbuf),
+ (unsigned int)b_head_ofs(tmbuf), (unsigned int)b_size(tmbuf));
if (h2s) {
chunk_appendf(msg, " last_h2s=%p .id=%d .flg=0x%04x .rxbuf=%u@%p+%u/%u .cs=%p",