typedef struct h2_request h2_request;
struct h2_request {
- int id; /* stream id */
- int initiated_on; /* initiating stream id (PUSH) or 0 */
+ apr_uint32_t id; /* stream id */
+ apr_uint32_t initiated_on; /* initiating stream id (PUSH) or 0 */
const char *method; /* pseudo header values, see ch. 8.1.2.3 */
const char *scheme;
}
}
-static apr_off_t calc_buffered(h2_bucket_beam *beam)
+static apr_size_t calc_buffered(h2_bucket_beam *beam)
{
- apr_off_t len = 0;
+ apr_size_t len = 0;
apr_bucket *b;
for (b = H2_BLIST_FIRST(&beam->red);
b != H2_BLIST_SENTINEL(&beam->red);
}
static apr_status_t r_wait_space(h2_bucket_beam *beam, apr_read_type_e block,
- h2_beam_lock *pbl, apr_off_t *premain)
+ h2_beam_lock *pbl, apr_size_t *premain)
{
*premain = calc_space_left(beam);
while (!beam->aborted && *premain <= 0
}
apr_status_t h2_beam_create(h2_bucket_beam **pbeam, apr_pool_t *red_pool,
- int id, const char *tag,
+ apr_uint32_t id, const char *tag,
apr_size_t max_buf_size)
{
h2_bucket_beam *beam;
{
const char *data;
apr_size_t len;
- apr_off_t space_left = 0;
+ apr_size_t space_left = 0;
apr_status_t status;
if (APR_BUCKET_IS_METADATA(bred)) {
int h2_beam_no_files(void *ctx, h2_bucket_beam *beam, apr_file_t *file);
struct h2_bucket_beam {
- int id;
+ apr_uint32_t id;
const char *tag;
h2_blist red;
h2_blist hold;
*/
apr_status_t h2_beam_create(h2_bucket_beam **pbeam,
apr_pool_t *red_pool,
- int id, const char *tag,
+ apr_uint32_t id, const char *tag,
apr_size_t buffer_size);
/**
io->output = apr_brigade_create(c->pool, c->bucket_alloc);
io->is_tls = h2_h2_is_tls(c);
io->buffer_output = io->is_tls;
- io->pass_threshold = h2_config_geti64(cfg, H2_CONF_STREAM_MAX_MEM) / 2;
+ io->pass_threshold = (apr_size_t)h2_config_geti64(cfg, H2_CONF_STREAM_MAX_MEM) / 2;
if (io->is_tls) {
/* This is what we start with,
#include "h2_util.h"
-static void h2_beam_log(h2_bucket_beam *beam, int id, const char *msg,
+static void h2_beam_log(h2_bucket_beam *beam, apr_uint32_t id, const char *msg,
conn_rec *c, int level)
{
if (beam && APLOG_C_IS_LEVEL(c,level)) {
}
if (task->output.beam && !task->output.opened) {
+ apr_uint32_t beamed_count;
h2_beam_buffer_size_set(task->output.beam, m->stream_max_mem);
h2_beam_timeout_set(task->output.beam, m->stream_timeout);
h2_beam_on_consumed(task->output.beam, stream_output_consumed, task);
h2_beam_on_produced(task->output.beam, output_produced, m);
- m->tx_handles_reserved -= h2_beam_get_files_beamed(task->output.beam);
+ beamed_count = h2_beam_get_files_beamed(task->output.beam);
+ if (m->tx_handles_reserved >= beamed_count) {
+ m->tx_handles_reserved -= beamed_count;
+ }
+ else {
+ m->tx_handles_reserved = 0;
+ }
if (!task->output.copy_files) {
h2_beam_on_file_beam(task->output.beam, can_beam_file, m);
}
apr_array_header_t *spare_slaves; /* spare slave connections */
struct h2_workers *workers;
- int tx_handles_reserved;
- apr_size_t tx_chunk_size;
+ apr_uint32_t tx_handles_reserved;
+ apr_uint32_t tx_chunk_size;
h2_mplx_consumed_cb *input_consumed;
void *input_consumed_ctx;
struct h2_push_diary {
apr_array_header_t *entries;
- apr_size_t NMax; /* Maximum for N, should size change be necessary */
- apr_size_t N; /* Current maximum number of entries, power of 2 */
+ apr_uint32_t NMax; /* Maximum for N, should size change be necessary */
+ apr_uint32_t N; /* Current maximum number of entries, power of 2 */
apr_uint64_t mask; /* mask for relevant bits */
unsigned int mask_bits; /* number of relevant bits */
const char *authority;
s_parent = nghttp2_stream_get_parent(s);
if (s_parent) {
nghttp2_priority_spec ps;
- int id_parent, id_grandpa, w_parent, w, rv = 0;
+ apr_uint32_t id_parent, id_grandpa, w_parent, w;
+ int rv = 0;
char *ptype = "AFTER";
h2_dependency dep = prio->dependency;
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c,
"h2_stream(%ld-%d): on_resume", session->id, stream_id);
if (stream) {
- int rv = nghttp2_session_resume_data(session->ngh2, stream_id);
+ int rv;
+ if (stream->rst_error) {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, APLOGNO()
+ "h2_stream(%ld-%d): RST_STREAM, err=%d",
+ session->id, stream->id, stream->rst_error);
+ rv = nghttp2_submit_rst_stream(session->ngh2, NGHTTP2_FLAG_NONE,
+ stream->id, stream->rst_error);
+ }
+ else {
+ rv = nghttp2_session_resume_data(session->ngh2, stream_id);
+ }
session->have_written = 1;
ap_log_cerror(APLOG_MARK, nghttp2_is_fatal(rv)?
APLOG_ERR : APLOG_DEBUG, 0, session->c,
return APR_SUCCESS;
}
-h2_stream *h2_stream_open(int id, apr_pool_t *pool, h2_session *session,
+h2_stream *h2_stream_open(apr_uint32_t id, apr_pool_t *pool, h2_session *session,
int initiated_on)
{
h2_stream *stream = apr_pcalloc(pool, sizeof(h2_stream));
stream->rst_error = error_code;
close_input(stream);
close_output(stream);
+ if (stream->buffer) {
+ apr_brigade_cleanup(stream->buffer);
+ }
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, stream->session->c,
"h2_stream(%ld-%d): reset, error=%d",
stream->session->id, stream->id, error_code);
typedef struct h2_stream h2_stream;
struct h2_stream {
- int id; /* http2 stream id */
- int initiated_on; /* initiating stream id (PUSH) or 0 */
+ apr_uint32_t id; /* http2 stream id */
+ apr_uint32_t initiated_on; /* initiating stream id (PUSH) or 0 */
apr_time_t created; /* when stream was created */
h2_stream_state_t state; /* http/2 state of this stream */
struct h2_session *session; /* the session this stream belongs to */
* @param session the session this stream belongs to
* @return the newly opened stream
*/
-h2_stream *h2_stream_open(int id, apr_pool_t *pool, struct h2_session *session,
+h2_stream *h2_stream_open(apr_uint32_t id, apr_pool_t *pool, struct h2_session *session,
int initiated_on);
/**
apr_status_t status = APR_SUCCESS;
apr_bucket *b, *next, *first_data;
apr_off_t bblen = 0;
+ apr_size_t rmax = ((readbytes <= APR_SIZE_MAX)?
+ (apr_size_t)readbytes : APR_SIZE_MAX);
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c,
"h2_task(%s): read, mode=%d, block=%d, readbytes=%ld",
APR_BRIGADE_CONCAT(bb, task->input.bb);
}
else if (mode == AP_MODE_READBYTES) {
- status = h2_brigade_concat_length(bb, task->input.bb, readbytes);
+ status = h2_brigade_concat_length(bb, task->input.bb, rmax);
}
else if (mode == AP_MODE_SPECULATIVE) {
- status = h2_brigade_copy_length(bb, task->input.bb, readbytes);
+ status = h2_brigade_copy_length(bb, task->input.bb, rmax);
}
else if (mode == AP_MODE_GETLINE) {
/* we are reading a single LF line, e.g. the HTTP headers.
struct h2_task {
const char *id;
- int stream_id;
+ apr_uint32_t stream_id;
conn_rec *c;
apr_pool_t *pool;
* unless we do not move the file buckets */
--files_allowed;
}
- else if (maxlen < b->length) {
- apr_bucket_split(b, maxlen);
+ else if (maxlen < (apr_off_t)b->length) {
+ apr_bucket_split(b, (apr_size_t)maxlen);
maxlen = 0;
}
else {
if (data_len > avail) {
apr_bucket_split(b, avail);
- data_len = avail;
+ data_len = (apr_size_t)avail;
}
if (consume) {
if (remain <= 0) {
return APR_SUCCESS;
}
- apr_bucket_split(e, remain);
+ apr_bucket_split(e, (apr_size_t)remain);
}
}
const char *name, size_t nlen)
{
const literal *lit;
- int i;
+ size_t i;
for (i = 0; i < llen; ++i) {
lit = &lits[i];