apr_table_t *headers;
apr_time_t request_time;
- int chunked; /* iff request body needs to be forwarded as chunked */
+ unsigned int chunked : 1; /* iff request body needs to be forwarded as chunked */
apr_off_t raw_bytes; /* RAW network bytes that generated this request - if known. */
int http_status; /* Store a possible HTTP status code that gets
* defined before creating the dummy HTTP/1.1
APR_BUCKET_REMOVE(b);
apr_bucket_setaside(b, beam->pool);
H2_BLIST_INSERT_TAIL(&beam->buckets_to_send, b);
- *pwritten += (apr_off_t)b->length;
goto cleanup;
}
/* non meta bucket */
static apr_status_t beam_out(conn_rec *c2, h2_conn_ctx_t *conn_ctx, apr_bucket_brigade* bb)
{
- apr_off_t written;
+ apr_off_t written, header_len = 0;
apr_status_t rv;
+ if (h2_c2_logio_add_bytes_out) {
+ /* mod_logio wants to report the number of bytes written in a
+ * response, including header and footer fields. Since h2 converts
+ * those during c1 processing into the HPACKed h2 HEADER frames,
+ * we need to give mod_logio something here and count just the
+ * raw lengths of all headers in the buckets. */
+ apr_bucket *b;
+ for (b = APR_BRIGADE_FIRST(bb);
+ b != APR_BRIGADE_SENTINEL(bb);
+ b = APR_BUCKET_NEXT(b)) {
+ if (H2_BUCKET_IS_HEADERS(b)) {
+ header_len += (apr_off_t)h2_bucket_headers_headers_length(b);
+ }
+ }
+ }
+
rv = h2_beam_send(conn_ctx->beam_out, c2, bb, APR_BLOCK_READ, &written);
if (APR_STATUS_IS_EAGAIN(rv)) {
rv = APR_SUCCESS;
}
if (written && h2_c2_logio_add_bytes_out) {
- h2_c2_logio_add_bytes_out(c2, written);
+ h2_c2_logio_add_bytes_out(c2, written + header_len);
}
return rv;
}
b = apr_bucket_shared_make(b, br, 0, 0);
b->type = &h2_bucket_type_headers;
- b->length = h2_headers_length(r);
+ b->length = 0;
return b;
}
return len;
}
+apr_size_t h2_bucket_headers_headers_length(apr_bucket *b)
+{
+ h2_headers *h = h2_bucket_headers_get(b);
+ return h? h2_headers_length(h) : 0;
+}
+
h2_headers *h2_headers_rcreate(request_rec *r, int status,
const apr_table_t *header, apr_pool_t *pool)
{
* @param pool the memory pool to use
*/
h2_headers *h2_headers_die(apr_status_t type,
- const struct h2_request *req, apr_pool_t *pool);
+ const struct h2_request *req, apr_pool_t *pool);
int h2_headers_are_response(h2_headers *headers);
*/
apr_size_t h2_headers_length(h2_headers *headers);
+/**
+ * For H2HEADER buckets, return the length of all contained header strings.
+ * For all other buckets, return 0.
+ */
+apr_size_t h2_bucket_headers_headers_length(apr_bucket *b);
+
#endif /* defined(__mod_h2__h2_headers__) */
assert 0 == len(promises)
# 2 H2PushResource config trigger on GET, but not on POST
- def test_h2_400_20(self, env):
+ def test_h2_400_20(self, env, repeat):
url = env.mkurl("https", "push", "/006-push20.html")
r = env.nghttp().get(url)
assert 200 == r.response["status"]