} h2_session_state;
typedef struct h2_session_props {
- apr_uint32_t accepted_max; /* the highest remote stream id was/will be handled */
- apr_uint32_t completed_max; /* the highest remote stream completed */
- apr_uint32_t emitted_count; /* the number of local streams sent */
- apr_uint32_t emitted_max; /* the highest local stream id sent */
- apr_uint32_t error; /* the last session error encountered */
+ int accepted_max; /* the highest remote stream id was/will be handled */
+ int completed_max; /* the highest remote stream completed */
+ int emitted_count; /* the number of local streams sent */
+ int emitted_max; /* the highest local stream id sent */
+ int error; /* the last session error encountered */
unsigned int accepting : 1; /* if the session is accepting new streams */
unsigned int shutdown : 1; /* if the final GOAWAY has been sent */
} h2_session_props;
}
apr_status_t h2_beam_create(h2_bucket_beam **pbeam, apr_pool_t *red_pool,
- apr_uint32_t id, const char *tag,
+ int id, const char *tag,
apr_size_t max_buf_size)
{
h2_bucket_beam *beam;
int h2_beam_no_files(void *ctx, h2_bucket_beam *beam, apr_file_t *file);
struct h2_bucket_beam {
- apr_uint32_t id;
+ int 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,
- apr_uint32_t id, const char *tag,
+ int id, const char *tag,
apr_size_t buffer_size);
/**
return status;
}
-conn_rec *h2_slave_create(conn_rec *master, apr_uint32_t slave_id,
+conn_rec *h2_slave_create(conn_rec *master, int slave_id,
apr_pool_t *parent, apr_allocator_t *allocator)
{
apr_pool_t *pool;
h2_mpm_type_t h2_conn_mpm_type(void);
-conn_rec *h2_slave_create(conn_rec *master, apr_uint32_t slave_id,
+conn_rec *h2_slave_create(conn_rec *master, int slave_id,
apr_pool_t *parent, apr_allocator_t *allocator);
void h2_slave_destroy(conn_rec *slave, apr_allocator_t **pallocator);
#include "h2_util.h"
-static void h2_beam_log(h2_bucket_beam *beam, apr_uint32_t id, const char *msg,
+static void h2_beam_log(h2_bucket_beam *beam, int id, const char *msg,
conn_rec *c, int level)
{
if (beam && APLOG_C_IS_LEVEL(c,level)) {
return m;
}
-apr_uint32_t h2_mplx_shutdown(h2_mplx *m)
+int h2_mplx_shutdown(h2_mplx *m)
{
int acquired, max_stream_started = 0;
return status;
}
-h2_stream *h2_mplx_stream_get(h2_mplx *m, apr_uint32_t id)
+h2_stream *h2_mplx_stream_get(h2_mplx *m, int id)
{
h2_stream *s = NULL;
int acquired;
apr_status_t h2_mplx_req_engine_pull(h2_req_engine *ngn,
apr_read_type_e block,
- apr_uint32_t capacity,
+ int capacity,
request_rec **pr)
{
h2_ngn_shed *shed = h2_ngn_shed_get_shed(ngn);
ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, m->c,
"h2_mplx(%ld-%d): on_resume",
m->id, stream->id);
- on_resume(on_ctx, stream->id);
+ on_resume(on_ctx, stream);
}
}
return status;
}
-apr_status_t h2_mplx_keep_active(h2_mplx *m, apr_uint32_t stream_id)
+apr_status_t h2_mplx_keep_active(h2_mplx *m, int stream_id)
{
apr_status_t status;
int acquired;
struct h2_ihash_t *tasks; /* all tasks started and not destroyed */
struct h2_ihash_t *redo_tasks; /* all tasks that need to be redone */
- apr_uint32_t max_streams; /* max # of concurrent streams */
- apr_uint32_t max_stream_started; /* highest stream id that started processing */
- apr_uint32_t workers_busy; /* # of workers processing on this mplx */
- apr_uint32_t workers_limit; /* current # of workers limit, dynamic */
- apr_uint32_t workers_def_limit; /* default # of workers limit */
- apr_uint32_t workers_max; /* max, hard limit # of workers in a process */
+ int max_streams; /* max # of concurrent streams */
+ int max_stream_started; /* highest stream id that started processing */
+ int workers_busy; /* # of workers processing on this mplx */
+ int workers_limit; /* current # of workers limit, dynamic */
+ int workers_def_limit; /* default # of workers limit */
+ int workers_max; /* max, hard limit # of workers in a process */
apr_time_t last_idle_block; /* last time, this mplx entered IDLE while
* streams were ready */
apr_time_t last_limit_change; /* last time, worker limit changed */
apr_array_header_t *spare_slaves; /* spare slave connections */
struct h2_workers *workers;
- apr_uint32_t tx_handles_reserved;
- apr_uint32_t tx_chunk_size;
+ int tx_handles_reserved;
+ int tx_chunk_size;
h2_mplx_consumed_cb *input_consumed;
void *input_consumed_ctx;
* but let the ongoing ones finish normally.
* @return the highest stream id being/been processed
*/
-apr_uint32_t h2_mplx_shutdown(h2_mplx *m);
+int h2_mplx_shutdown(h2_mplx *m);
int h2_mplx_is_busy(h2_mplx *m);
* IO lifetime of streams.
******************************************************************************/
-struct h2_stream *h2_mplx_stream_get(h2_mplx *m, apr_uint32_t id);
+struct h2_stream *h2_mplx_stream_get(h2_mplx *m, int id);
/**
* Notifies mplx that a stream has finished processing.
apr_status_t h2_mplx_out_trywait(h2_mplx *m, apr_interval_time_t timeout,
struct apr_thread_cond_t *iowait);
-apr_status_t h2_mplx_keep_active(h2_mplx *m, apr_uint32_t stream_id);
+apr_status_t h2_mplx_keep_active(h2_mplx *m, int stream_id);
/*******************************************************************************
* Stream processing.
void h2_mplx_set_consumed_cb(h2_mplx *m, h2_mplx_consumed_cb *cb, void *ctx);
-typedef apr_status_t stream_ev_callback(void *ctx, int stream_id);
+typedef apr_status_t stream_ev_callback(void *ctx, struct h2_stream *stream);
/**
* Dispatch events for the master connection, such as
const char *id,
const char *type,
apr_pool_t *pool,
- apr_uint32_t req_buffer_size,
+ apr_size_t req_buffer_size,
request_rec *r,
h2_output_consumed **pconsumed,
void **pbaton);
h2_mplx_req_engine_init *einit);
apr_status_t h2_mplx_req_engine_pull(struct h2_req_engine *ngn,
apr_read_type_e block,
- apr_uint32_t capacity,
+ int capacity,
request_rec **pr);
void h2_mplx_req_engine_done(struct h2_req_engine *ngn, conn_rec *r_conn);
unsigned int done : 1; /* engine has finished */
APR_RING_HEAD(h2_req_entries, h2_ngn_entry) entries;
- apr_uint32_t capacity; /* maximum concurrent requests */
- apr_uint32_t no_assigned; /* # of assigned requests */
- apr_uint32_t no_live; /* # of live */
- apr_uint32_t no_finished; /* # of finished */
+ int capacity; /* maximum concurrent requests */
+ int no_assigned; /* # of assigned requests */
+ int no_live; /* # of live */
+ int no_finished; /* # of finished */
h2_output_consumed *out_consumed;
void *out_consumed_ctx;
}
h2_ngn_shed *h2_ngn_shed_create(apr_pool_t *pool, conn_rec *c,
- apr_uint32_t default_capacity,
- apr_uint32_t req_buffer_size)
+ int default_capacity,
+ apr_size_t req_buffer_size)
{
h2_ngn_shed *shed;
apr_status_t h2_ngn_shed_pull_request(h2_ngn_shed *shed,
h2_req_engine *ngn,
- apr_uint32_t capacity,
+ int capacity,
int want_shutdown,
request_rec **pr)
{
unsigned int aborted : 1;
- apr_uint32_t default_capacity;
- apr_uint32_t req_buffer_size; /* preferred buffer size for responses */
+ int default_capacity;
+ apr_size_t req_buffer_size; /* preferred buffer size for responses */
};
const char *h2_req_engine_get_id(h2_req_engine *engine);
const char *id,
const char *type,
apr_pool_t *pool,
- apr_uint32_t req_buffer_size,
+ apr_size_t req_buffer_size,
request_rec *r,
h2_output_consumed **pconsumed,
void **pbaton);
h2_ngn_shed *h2_ngn_shed_create(apr_pool_t *pool, conn_rec *c,
- apr_uint32_t default_capactiy,
- apr_uint32_t req_buffer_size);
+ int default_capactiy,
+ apr_size_t req_buffer_size);
void h2_ngn_shed_set_ctx(h2_ngn_shed *shed, void *user_ctx);
void *h2_ngn_shed_get_ctx(h2_ngn_shed *shed);
h2_shed_ngn_init *init_cb);
apr_status_t h2_ngn_shed_pull_request(h2_ngn_shed *shed, h2_req_engine *pub_ngn,
- apr_uint32_t capacity,
+ int capacity,
int want_shutdown, request_rec **pr);
apr_status_t h2_ngn_shed_done_task(h2_ngn_shed *shed,
#include "h2_proxy_util.h"
/* h2_log2(n) iff n is a power of 2 */
-unsigned char h2_log2(apr_uint32_t n)
+unsigned char h2_log2(int n)
{
int lz = 0;
if (!n) {
* common helpers
******************************************************************************/
/* h2_log2(n) iff n is a power of 2 */
-unsigned char h2_log2(apr_uint32_t n);
+unsigned char h2_log2(int n);
/*******************************************************************************
* HTTP/2 header helpers
typedef struct {
h2_push_diary *diary;
unsigned char log2p;
- apr_uint32_t mask_bits;
- apr_uint32_t delta_bits;
- apr_uint32_t fixed_bits;
+ int mask_bits;
+ int delta_bits;
+ int fixed_bits;
apr_uint64_t fixed_mask;
apr_pool_t *pool;
unsigned char *data;
* @param plen on successful return, the length of the binary data
*/
apr_status_t h2_push_diary_digest_get(h2_push_diary *diary, apr_pool_t *pool,
- apr_uint32_t maxP, const char *authority,
+ int maxP, const char *authority,
const char **pdata, apr_size_t *plen)
{
apr_size_t nelts, N, i;
struct h2_push_diary {
apr_array_header_t *entries;
- apr_uint32_t NMax; /* Maximum for N, should size change be necessary */
- apr_uint32_t N; /* Current maximum number of entries, power of 2 */
+ int NMax; /* Maximum for N, should size change be necessary */
+ int 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;
* @param plen on successful return, the length of the binary data
*/
apr_status_t h2_push_diary_digest_get(h2_push_diary *diary, apr_pool_t *p,
- apr_uint32_t maxP, const char *authority,
+ int maxP, const char *authority,
const char **pdata, apr_size_t *plen);
/**
s_parent = nghttp2_stream_get_parent(s);
if (s_parent) {
nghttp2_priority_spec ps;
- apr_uint32_t id_parent, id_grandpa, w_parent, w;
+ int id_parent, id_grandpa, w_parent, w;
int rv = 0;
char *ptype = "AFTER";
h2_dependency dep = prio->dependency;
}
/**
- * A stream was resumed as new output data arrived.
+ * A stream was resumed as new response/output data arrived.
*/
-static apr_status_t on_stream_resume(void *ctx, int stream_id)
+static apr_status_t on_stream_resume(void *ctx, h2_stream *stream)
{
h2_session *session = ctx;
- h2_stream *stream = get_stream(session, stream_id);
apr_status_t status = APR_EAGAIN;
int rv;
+ apr_off_t len = 0;
+ int eos = 0;
+ h2_headers *headers = NULL;
+ ap_assert(stream);
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c,
- "h2_stream(%ld-%d): on_resume", session->id, stream_id);
- if (stream) {
- apr_off_t len = 0;
- int eos = 0;
- h2_headers *headers = NULL;
+ "h2_stream(%ld-%d): on_resume", session->id, stream->id);
- send_headers:
- status = h2_stream_out_prepare(stream, &len, &eos, &headers);
- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, session->c,
- "h2_stream(%ld-%d): prepared len=%ld, eos=%d",
- session->id, stream_id, (long)len, eos);
- if (headers) {
- status = on_stream_headers(session, stream, headers, len, eos);
- if (status != APR_SUCCESS) {
- return status;
- }
- goto send_headers;
- }
- else if (status != APR_EAGAIN) {
- 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,
- APLOGNO(02936)
- "h2_stream(%ld-%d): resuming %s",
- session->id, stream->id, rv? nghttp2_strerror(rv) : "");
+send_headers:
+ status = h2_stream_out_prepare(stream, &len, &eos, &headers);
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, session->c,
+ "h2_stream(%ld-%d): prepared len=%ld, eos=%d",
+ session->id, stream->id, (long)len, eos);
+ if (headers) {
+ status = on_stream_headers(session, stream, headers, len, eos);
+ if (status != APR_SUCCESS) {
+ return status;
}
+ goto send_headers;
+ }
+ else if (status != APR_EAGAIN) {
+ 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,
+ APLOGNO(02936)
+ "h2_stream(%ld-%d): resuming %s",
+ session->id, stream->id, rv? nghttp2_strerror(rv) : "");
}
return status;
}
return APR_SUCCESS;
}
-h2_stream *h2_stream_open(apr_uint32_t id, apr_pool_t *pool, h2_session *session,
+h2_stream *h2_stream_open(int id, apr_pool_t *pool, h2_session *session,
int initiated_on)
{
h2_stream *stream = apr_pcalloc(pool, sizeof(h2_stream));
typedef struct h2_stream h2_stream;
struct h2_stream {
- apr_uint32_t id; /* http2 stream id */
- apr_uint32_t initiated_on; /* initiating stream id (PUSH) or 0 */
+ int id; /* http2 stream id */
+ int 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(apr_uint32_t id, apr_pool_t *pool, struct h2_session *session,
+h2_stream *h2_stream_open(int id, apr_pool_t *pool, struct h2_session *session,
int initiated_on);
/**
return OK;
}
-h2_task *h2_task_create(conn_rec *c, apr_uint32_t stream_id,
+h2_task *h2_task_create(conn_rec *c, int stream_id,
const h2_request *req, h2_bucket_beam *input,
h2_mplx *mplx)
{
struct h2_task {
const char *id;
- apr_uint32_t stream_id;
+ int stream_id;
conn_rec *c;
apr_pool_t *pool;
struct h2_req_engine *assigned; /* engine that task has been assigned to */
};
-h2_task *h2_task_create(conn_rec *c, apr_uint32_t stream_id,
+h2_task *h2_task_create(conn_rec *c, int stream_id,
const struct h2_request *req,
struct h2_bucket_beam *input, struct h2_mplx *mplx);
#include "h2_util.h"
/* h2_log2(n) iff n is a power of 2 */
-unsigned char h2_log2(apr_uint32_t n)
+unsigned char h2_log2(int n)
{
int lz = 0;
if (!n) {
* common helpers
******************************************************************************/
/* h2_log2(n) iff n is a power of 2 */
-unsigned char h2_log2(apr_uint32_t n);
+unsigned char h2_log2(int n);
/**
* Count the bytes that all key/value pairs in a table have
* @macro
* Version number of the http2 module as c string
*/
-#define MOD_HTTP2_VERSION "1.7.2"
+#define MOD_HTTP2_VERSION "1.7.3"
/**
* @macro
* release. This is a 24 bit number with 8 bits for major number, 8 bits
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
*/
-#define MOD_HTTP2_VERSION_NUM 0x010702
+#define MOD_HTTP2_VERSION_NUM 0x010703
#endif /* mod_h2_h2_version_h */
static apr_status_t http2_req_engine_pull(h2_req_engine *ngn,
apr_read_type_e block,
- apr_uint32_t capacity,
+ int capacity,
request_rec **pr)
{
return h2_mplx_req_engine_pull(ngn, block, capacity, pr);
const char *id,
const char *type,
apr_pool_t *pool,
- apr_uint32_t req_buffer_size,
+ apr_size_t req_buffer_size,
request_rec *r,
http2_output_consumed **pconsumed,
void **pbaton);
/**
* Get a new request for processing in this engine.
* @param engine the engine which is done processing the slave
- * @param timeout wait a maximum amount of time for a new slave, 0 will not wait
- * @param pslave the slave connection that needs processing or NULL
+ * @param block if call should block waiting for request to come
+ * @param capacity how many parallel requests are acceptable
+ * @param pr the request that needs processing or NULL
* @return APR_SUCCESS if new request was assigned
* APR_EAGAIN if no new request is available
* APR_EOF if engine may shut down, as no more request will be scheduled
APR_DECLARE_OPTIONAL_FN(apr_status_t,
http2_req_engine_pull, (h2_req_engine *engine,
apr_read_type_e block,
- apr_uint32_t capacity,
+ int capacity,
request_rec **pr));
APR_DECLARE_OPTIONAL_FN(void,
http2_req_engine_done, (h2_req_engine *engine,
http2_req_engine_init *einit);
static apr_status_t (*req_engine_pull)(h2_req_engine *engine,
apr_read_type_e block,
- apr_uint32_t capacity,
+ int capacity,
request_rec **pr);
static void (*req_engine_done)(h2_req_engine *engine, conn_rec *r_conn);
const char *engine_id;
const char *engine_type;
apr_pool_t *engine_pool;
- apr_uint32_t req_buffer_size;
+ apr_size_t req_buffer_size;
request_rec *next;
apr_size_t capacity;
const char *id,
const char *type,
apr_pool_t *pool,
- apr_uint32_t req_buffer_size,
+ apr_size_t req_buffer_size,
request_rec *r,
http2_output_consumed **pconsumed,
void **pctx)