h2_task_input *h2_task_input_create(h2_task *task, apr_pool_t *pool, apr_bucket_alloc_t *bucket_alloc) { h2_task_input *input = apr_pcalloc(pool, sizeof(h2_task_input)); if (input) { input->task = task; input->bb = NULL; if (task->serialize_headers) { ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, task->c, "h2_task_input(%s): serialize request %s %s", task->id, task->request->method, task->request->path); input->bb = apr_brigade_create(pool, bucket_alloc); apr_brigade_printf(input->bb, NULL, NULL, "%s %s HTTP/1.1\r\n", task->request->method, task->request->path); apr_table_do(ser_header, input, task->request->headers, NULL); apr_brigade_puts(input->bb, NULL, NULL, "\r\n"); if (input->task->input_eos) { APR_BRIGADE_INSERT_TAIL(input->bb, apr_bucket_eos_create(bucket_alloc)); } } else if (!input->task->input_eos) { input->bb = apr_brigade_create(pool, bucket_alloc); } else { /* We do not serialize and have eos already, no need to * create a bucket brigade. */ } } return input; }
apr_status_t h2_session_goaway(h2_session *session, apr_status_t reason) { assert(session); apr_status_t status = APR_SUCCESS; if (session->aborted) { return APR_EINVAL; } int rv = 0; if (reason == APR_SUCCESS) { rv = nghttp2_submit_shutdown_notice(session->ngh2); } else { int err = 0; int last_id = nghttp2_session_get_last_proc_stream_id(session->ngh2); rv = nghttp2_submit_goaway(session->ngh2, last_id, NGHTTP2_FLAG_NONE, err, NULL, 0); } if (rv != 0) { status = APR_EGENERAL; ap_log_cerror(APLOG_MARK, APLOG_ERR, status, session->c, "session(%ld): submit goaway: %s", session->id, nghttp2_strerror(rv)); } return status; }
apr_status_t h2_stream_write_eoh(h2_stream *stream, int eos) { apr_status_t status; AP_DEBUG_ASSERT(stream); /* Seeing the end-of-headers, we have everything we need to * start processing it. */ status = h2_mplx_create_task(stream->m, stream); status = h2_mplx_create_task(stream->m, stream); if (status == APR_SUCCESS) { status = h2_request_end_headers(stream->request, stream->m, stream->task, eos); if (status == APR_SUCCESS) { status = h2_mplx_do_task(stream->m, stream->task); } if (eos) { status = h2_stream_write_eos(stream); } ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, stream->m->c, "h2_mplx(%ld-%d): start stream, task %s %s (%s)", stream->m->id, stream->id, stream->request->method, stream->request->path, stream->request->authority); } return status; }
apr_status_t h2_stream_prep_read(h2_stream *stream, apr_size_t *plen, int *peos) { apr_status_t status = APR_SUCCESS; const char *src; if (stream->bbout && !APR_BRIGADE_EMPTY(stream->bbout)) { src = "stream"; status = h2_util_bb_avail(stream->bbout, plen, peos); if (status == APR_SUCCESS && !*peos && !*plen) { apr_brigade_cleanup(stream->bbout); return h2_stream_prep_read(stream, plen, peos); } } else { src = "mplx"; status = h2_mplx_out_readx(stream->m, stream->id, NULL, NULL, plen, peos); } if (status == APR_SUCCESS && !*peos && !*plen) { status = APR_EAGAIN; } ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, stream->m->c, "h2_stream(%ld-%d): prep_read %s, len=%ld eos=%d", stream->m->id, stream->id, src, (long)*plen, *peos); return status; }
static apr_status_t out_open(h2_mplx *m, int stream_id, h2_response *response, ap_filter_t* f, apr_bucket_brigade *bb, struct apr_thread_cond_t *iowait) { apr_status_t status = APR_SUCCESS; h2_io *io = h2_io_set_get(m->stream_ios, stream_id); if (io && !io->orphaned) { if (f) { ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, f->c, "h2_mplx(%ld-%d): open response: %d, rst=%d", m->id, stream_id, response->http_status, response->rst_error); } h2_io_set_response(io, response); h2_io_set_add(m->ready_ios, io); if (bb) { status = out_write(m, io, f, bb, response->trailers, iowait); } have_out_data_for(m, stream_id); } else { status = APR_ECONNABORTED; } return status; }
static int h2_task_process_conn(conn_rec* c) { h2_ctx *ctx = h2_ctx_get(c); if (h2_ctx_is_task(ctx)) { if (!ctx->task->serialize_headers) { ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, "h2_h2, processing request directly"); h2_task_process_request(ctx->task->request, c); return DONE; } ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, "h2_task(%s), serialized handling", ctx->task->id); } return DECLINED; }
OCSP_RESPONSE *modssl_dispatch_ocsp_request(const apr_uri_t *uri, apr_interval_time_t timeout, OCSP_REQUEST *request, conn_rec *c, apr_pool_t *p) { OCSP_RESPONSE *response = NULL; apr_socket_t *sd; BIO *bio; bio = serialize_request(request, uri); if (bio == NULL) { ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01989) "could not serialize OCSP request"); ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, mySrvFromConn(c)); return NULL; } sd = send_request(bio, uri, timeout, c, p); if (sd == NULL) { /* Errors already logged. */ BIO_free(bio); return NULL; } /* Clear the BIO contents, ready for the response. */ (void)BIO_reset(bio); response = read_response(sd, bio, c, p); apr_socket_close(sd); BIO_free(bio); return response; }
static int filter_init(ap_filter_t *f) { ap_filter_provider_t *p; provider_ctx *pctx; int err; ap_filter_rec_t *filter = f->frec; harness_ctx *fctx = apr_pcalloc(f->r->pool, sizeof(harness_ctx)); for (p = filter->providers; p; p = p->next) { if (p->frec->filter_init_func) { f->ctx = NULL; if ((err = p->frec->filter_init_func(f)) != OK) { ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, "filter_init for %s failed", p->frec->name); return err; /* if anyone errors out here, so do we */ } if (f->ctx != NULL) { /* the filter init function set a ctx - we need to record it */ pctx = apr_pcalloc(f->r->pool, sizeof(provider_ctx)); pctx->provider = p; pctx->ctx = f->ctx; pctx->next = fctx->init_ctx; fctx->init_ctx = pctx; } } } f->ctx = fctx; return OK; }
apr_status_t h2_stream_read_to(h2_stream *stream, apr_bucket_brigade *bb, apr_size_t *plen, int *peos) { apr_status_t status = APR_SUCCESS; if (stream->rst_error) { return APR_ECONNRESET; } if (APR_BRIGADE_EMPTY(stream->bbout)) { apr_size_t tlen = *plen; int eos; status = h2_mplx_out_read_to(stream->session->mplx, stream->id, stream->bbout, &tlen, &eos); } if (status == APR_SUCCESS && !APR_BRIGADE_EMPTY(stream->bbout)) { status = h2_transfer_brigade(bb, stream->bbout, stream->pool, plen, peos); } else { *plen = 0; *peos = 0; } if (status == APR_SUCCESS && !*peos && !*plen) { status = APR_EAGAIN; } ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, stream->session->c, "h2_stream(%ld-%d): read_to, len=%ld eos=%d", stream->session->id, stream->id, (long)*plen, *peos); return status; }
void h2_stream_rst(h2_stream *stream, int error_code) { stream->rst_error = error_code; ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, stream->session->c, "h2_stream(%ld-%d): reset, error=%d", stream->session->id, stream->id, error_code); }
apr_status_t h2_stream_schedule(h2_stream *stream, int eos, h2_stream_pri_cmp *cmp, void *ctx) { apr_status_t status; AP_DEBUG_ASSERT(stream); if (stream->rst_error) { return APR_ECONNRESET; } /* Seeing the end-of-headers, we have everything we need to * start processing it. */ status = h2_mplx_process(stream->session->mplx, stream->id, stream->request, eos, cmp, ctx); if (eos) { set_closed(stream); } ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, stream->session->c, "h2_mplx(%ld-%d): start stream, task %s %s (%s)", stream->session->id, stream->id, stream->request->method, stream->request->path, stream->request->authority); return status; }
apr_status_t h2_stream_set_response(h2_stream *stream, h2_response *response, apr_bucket_brigade *bb) { apr_status_t status = APR_SUCCESS; stream->response = response; if (bb && !APR_BRIGADE_EMPTY(bb)) { int move_all = INT_MAX; /* we can move file handles from h2_mplx into this h2_stream as many * as we want, since the lifetimes are the same and we are not freeing * the ones in h2_mplx->io before this stream is done. */ status = h2_util_move(stream->bbout, bb, 16 * 1024, &move_all, "h2_stream_set_response"); } if (APLOGctrace1(stream->session->c)) { apr_size_t len = 0; int eos = 0; h2_util_bb_avail(stream->bbout, &len, &eos); ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, stream->session->c, "h2_stream(%ld-%d): set_response(%s), len=%ld, eos=%d", stream->session->id, stream->id, response->status, (long)len, (int)eos); } return status; }
static apr_status_t init_callbacks(conn_rec *c, nghttp2_session_callbacks **pcb) { int rv = nghttp2_session_callbacks_new(pcb); if (rv != 0) { ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02926) "nghttp2_session_callbacks_new: %s", nghttp2_strerror(rv)); return APR_EGENERAL; } NGH2_SET_CALLBACK(*pcb, send, send_cb); NGH2_SET_CALLBACK(*pcb, on_frame_recv, on_frame_recv_cb); NGH2_SET_CALLBACK(*pcb, on_invalid_frame_recv, on_invalid_frame_recv_cb); NGH2_SET_CALLBACK(*pcb, on_data_chunk_recv, on_data_chunk_recv_cb); NGH2_SET_CALLBACK(*pcb, before_frame_send, before_frame_send_cb); NGH2_SET_CALLBACK(*pcb, on_frame_send, on_frame_send_cb); NGH2_SET_CALLBACK(*pcb, on_frame_not_send, on_frame_not_send_cb); NGH2_SET_CALLBACK(*pcb, on_stream_close, on_stream_close_cb); NGH2_SET_CALLBACK(*pcb, on_begin_headers, on_begin_headers_cb); NGH2_SET_CALLBACK(*pcb, on_header, on_header_cb); NGH2_SET_CALLBACK(*pcb, send_data, on_send_data_cb); NGH2_SET_CALLBACK(*pcb, data_source_read_length, on_data_source_read_length_cb); return APR_SUCCESS; }
static int stream_open(h2_session *session, int stream_id) { h2_stream * stream; apr_pool_t *stream_pool; if (session->aborted) { return NGHTTP2_ERR_CALLBACK_FAILURE; } if (session->spare) { stream_pool = session->spare; session->spare = NULL; } else { apr_pool_create(&stream_pool, session->pool); } stream = h2_stream_create(stream_id, stream_pool, session); stream->state = H2_STREAM_ST_OPEN; h2_stream_set_add(session->streams, stream); if (stream->id > session->max_stream_received) { session->max_stream_received = stream->id; } ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, "h2_session: stream(%ld-%d): opened", session->id, stream_id); return 0; }
static apr_status_t pass_out(apr_bucket_brigade *bb, void *ctx) { h2_conn_io *io = (h2_conn_io*)ctx; apr_status_t status; apr_off_t bblen; if (APR_BRIGADE_EMPTY(bb)) { return APR_SUCCESS; } ap_update_child_status(io->connection->sbh, SERVER_BUSY_WRITE, NULL); status = apr_brigade_length(bb, 0, &bblen); if (status == APR_SUCCESS) { ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, io->connection, "h2_conn_io(%ld): pass_out brigade %ld bytes", io->connection->id, (long)bblen); status = ap_pass_brigade(io->connection->output_filters, bb); if (status == APR_SUCCESS) { io->bytes_written += (apr_size_t)bblen; io->last_write = apr_time_now(); } apr_brigade_cleanup(bb); } return status; }
apr_status_t h2_conn_run(struct h2_ctx *ctx, conn_rec *c) { apr_status_t status; int mpm_state = 0; do { if (c->cs) { c->cs->sense = CONN_SENSE_DEFAULT; } status = h2_session_process(h2_ctx_session_get(ctx), async_mpm); if (c->cs) { c->cs->state = CONN_STATE_WRITE_COMPLETION; } if (APR_STATUS_IS_EOF(status)) { ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c, "h2_session(%ld): process, closing conn", c->id); c->keepalive = AP_CONN_CLOSE; } else { c->keepalive = AP_CONN_KEEPALIVE; } if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state)) { break; } } while (!async_mpm && c->keepalive == AP_CONN_KEEPALIVE && mpm_state != AP_MPMQ_STOPPING); return DONE; }
h2_stream *h2_mplx_next_submit(h2_mplx *m, h2_stream_set *streams) { apr_status_t status; h2_stream *stream = NULL; AP_DEBUG_ASSERT(m); if (m->aborted) { return NULL; } status = apr_thread_mutex_lock(m->lock); if (APR_SUCCESS == status) { h2_io *io = h2_io_set_get_highest_prio(m->ready_ios); if (io) { h2_response *response = io->response; h2_io_set_remove(m->ready_ios, io); stream = h2_stream_set_get(streams, response->stream_id); if (stream) { h2_stream_set_response(stream, response, io->bbout); if (io->output_drained) { apr_thread_cond_signal(io->output_drained); } } else { ap_log_cerror(APLOG_MARK, APLOG_WARNING, APR_NOTFOUND, m->c, APLOGNO(02953) "h2_mplx(%ld): stream for response %d", m->id, response->stream_id); } } apr_thread_mutex_unlock(m->lock); } return stream; }
static ib_status_t ib_error_callback(ib_tx_t *tx, int status, void *cbdata) { #if 0 /* We're being called from a connection filter here. * So on input we have to anticipate the Request * while on output we're too late to do anything very interesting. */ ap_filter_t *f = vf; mod_ib_conn_ctx *ctx = ap_get_module_config(f->c->conn_config, &ironbee_module); if (ctx == NULL) { ctx = apr_pcalloc(f->c->pool, sizeof(mod_ib_conn_ctx)); ap_set_module_config(f->c->conn_config, &ironbee_module, ctx); } if (ap_is_HTTP_VALID_RESPONSE(status)) { /* Ironbee wants us to return an HTTP error */ ctx->status = status; } else if (status == DONE) { /* Ironbee wants us to return an HTTP error */ ctx->status = status; } else { ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c, IB_PRODUCT_NAME ": requested unsupported action %d", status); return IB_ENOTIMPL; } #endif return IB_ENOTIMPL; }
static apr_status_t out_open(h2_mplx *m, int stream_id, h2_response *response, ap_filter_t* f, apr_bucket_brigade *bb, struct apr_thread_cond_t *iowait) { apr_status_t status = APR_SUCCESS; h2_io *io = h2_io_set_get(m->stream_ios, stream_id); if (io) { if (f) { ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c, "h2_mplx(%ld-%d): open response: %s", m->id, stream_id, response->status); } io->response = h2_response_copy(io->pool, response); h2_io_set_add(m->ready_ios, io); if (bb) { status = out_write(m, io, f, bb, iowait); } have_out_data_for(m, stream_id); } else { status = APR_ECONNABORTED; } return status; }
apr_status_t h2_mplx_process(h2_mplx *m, int stream_id, const h2_request *req, int eos, h2_stream_pri_cmp *cmp, void *ctx) { apr_status_t status; AP_DEBUG_ASSERT(m); if (m->aborted) { return APR_ECONNABORTED; } status = apr_thread_mutex_lock(m->lock); if (APR_SUCCESS == status) { h2_io *io = open_io(m, stream_id); io->request = req; io->request_body = !eos; if (eos) { status = h2_io_in_close(io); } h2_tq_add(m->q, io->id, cmp, ctx); ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, m->c, "h2_mplx(%ld-%d): process", m->c->id, stream_id); H2_MPLX_IO_IN(APLOG_TRACE2, m, io, "h2_mplx_process"); apr_thread_mutex_unlock(m->lock); } if (status == APR_SUCCESS) { workers_register(m); } return status; }
apr_status_t h2_conn_setup(h2_ctx *ctx, conn_rec *c, request_rec *r) { h2_session *session; if (!workers) { ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02911) "workers not initialized"); return APR_EGENERAL; } if (r) { session = h2_session_rcreate(r, ctx, workers); } else { session = h2_session_create(c, ctx, workers); } h2_ctx_session_set(ctx, session); switch (h2_conn_mpm_type()) { case H2_MPM_EVENT: fix_event_master_conn(session); break; default: break; } return APR_SUCCESS; }
void h2_mplx_request_done(h2_mplx **pm, int stream_id, const h2_request **preq) { h2_mplx *m = *pm; int acquired; if (enter_mutex(m, &acquired) == APR_SUCCESS) { h2_io *io = h2_io_set_get(m->stream_ios, stream_id); ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c, "h2_mplx(%ld): request(%d) done", m->id, stream_id); if (io) { io->worker_done = 1; if (io->orphaned) { io_destroy(m, io, 0); if (m->join_wait) { apr_thread_cond_signal(m->join_wait); } } else { /* hang around until the stream deregisteres */ } } if (preq) { /* someone wants another request, if we have */ *preq = pop_request(m); } if (!preq || !*preq) { /* No request to hand back to the worker, NULLify reference * and decrement count */ *pm = NULL; } leave_mutex(m, acquired); } }
static int before_frame_send_cb(nghttp2_session *ngh2, const nghttp2_frame *frame, void *userp) { h2_session *session = (h2_session *)userp; (void)ngh2; if (session->aborted) { return NGHTTP2_ERR_CALLBACK_FAILURE; } /* Set the need to flush output when we have added one of the * following frame types */ switch (frame->hd.type) { case NGHTTP2_RST_STREAM: case NGHTTP2_WINDOW_UPDATE: case NGHTTP2_PUSH_PROMISE: case NGHTTP2_PING: case NGHTTP2_GOAWAY: session->flush = 1; break; default: break; } if (APLOGctrace2(session->c)) { char buffer[256]; frame_print(frame, buffer, sizeof(buffer)/sizeof(buffer[0])); ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, session->c, "h2_session(%ld): before_frame_send %s", session->id, buffer); } return 0; }
/* h2_io_on_read_cb implementation that offers the data read * directly to the session for consumption. */ static apr_status_t session_receive(const char *data, apr_size_t len, apr_size_t *readlen, int *done, void *puser) { h2_session *session = (h2_session *)puser; AP_DEBUG_ASSERT(session); if (len > 0) { ssize_t n = nghttp2_session_mem_recv(session->ngh2, (const uint8_t *)data, len); if (n < 0) { ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_EGENERAL, session->c, "h2_session: nghttp2_session_mem_recv error %d", (int)n); if (nghttp2_is_fatal((int)n)) { *done = 1; h2_session_abort_int(session, (int)n); return APR_EGENERAL; } } else { *readlen = n; } } return APR_SUCCESS; }
void h2_slave_destroy(conn_rec *slave) { ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, slave, "h2_slave(%s): destroy", slave->log_id); slave->sbh = NULL; apr_pool_destroy(slave->pool); }
void h2_session_destroy(h2_session *session) { AP_DEBUG_ASSERT(session); if (session->mplx) { h2_mplx_release_and_join(session->mplx, session->iowait); session->mplx = NULL; } if (session->streams) { if (h2_stream_set_size(session->streams)) { ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c, "h2_session(%ld): destroy, %d streams open", session->id, (int)h2_stream_set_size(session->streams)); } h2_stream_set_destroy(session->streams); session->streams = NULL; } if (session->ngh2) { nghttp2_session_del(session->ngh2); session->ngh2 = NULL; } h2_conn_io_destroy(&session->io); if (session->iowait) { apr_thread_cond_destroy(session->iowait); session->iowait = NULL; } if (session->pool) { apr_pool_destroy(session->pool); } }
static int on_header_cb(nghttp2_session *ngh2, const nghttp2_frame *frame, const uint8_t *name, size_t namelen, const uint8_t *value, size_t valuelen, uint8_t flags, void *userp) { h2_session *session = (h2_session *)userp; h2_stream * stream; apr_status_t status; (void)ngh2; (void)flags; if (session->aborted) { return NGHTTP2_ERR_CALLBACK_FAILURE; } stream = h2_stream_set_get(session->streams, frame->hd.stream_id); if (!stream) { ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, session->c, APLOGNO(02920) "h2_session: stream(%ld-%d): on_header for unknown stream", session->id, (int)frame->hd.stream_id); return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; } status = h2_stream_write_header(stream, (const char *)name, namelen, (const char *)value, valuelen); if (status != APR_SUCCESS) { return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; } return 0; }
/* Start submitting the response to a stream request. This is possible * once we have all the response headers. The response body will be * read by the session using the callback we supply. */ apr_status_t h2_session_handle_response(h2_session *session, h2_stream *stream) { apr_status_t status = APR_SUCCESS; int rv = 0; AP_DEBUG_ASSERT(session); AP_DEBUG_ASSERT(stream); AP_DEBUG_ASSERT(stream->response); if (stream->response->ngheader) { rv = submit_response(session, stream->response); } else { rv = nghttp2_submit_rst_stream(session->ngh2, NGHTTP2_FLAG_NONE, stream->id, NGHTTP2_PROTOCOL_ERROR); } if (nghttp2_is_fatal(rv)) { status = APR_EGENERAL; h2_session_abort_int(session, rv); ap_log_cerror(APLOG_MARK, APLOG_ERR, status, session->c, APLOGNO(02940) "submit_response: %s", nghttp2_strerror(rv)); } return status; }
/* Return the responder URI object which should be used in the given * configuration for the given certificate, or NULL if none can be * determined. */ static apr_uri_t *determine_responder_uri(SSLSrvConfigRec *sc, X509 *cert, conn_rec *c, apr_pool_t *p) { apr_uri_t *u = apr_palloc(p, sizeof *u); const char *s; apr_status_t rv; /* Use default responder URL if forced by configuration, else use * certificate-specified responder, falling back to default if * necessary and possible. */ if (sc->server->ocsp_force_default == TRUE) { s = sc->server->ocsp_responder; } else { s = extract_responder_uri(cert, p); if (s == NULL && sc->server->ocsp_responder) { s = sc->server->ocsp_responder; } } if (s == NULL) { ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01918) "no OCSP responder specified in certificate and " "no default configured"); return NULL; } rv = apr_uri_parse(p, s, u); if (rv || !u->hostname) { ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(01919) "failed to parse OCSP responder URI '%s'", s); return NULL; } if (strcasecmp(u->scheme, "http") != 0) { ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(01920) "cannot handle OCSP responder URI '%s'", s); return NULL; } if (!u->port) { u->port = apr_uri_port_of_scheme(u->scheme); } return u; }
void h2_session_log_stats(h2_session *session) { AP_DEBUG_ASSERT(session); ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, session->c, "h2_session(%ld): %d open streams", session->id, (int)h2_stream_set_size(session->streams)); h2_stream_set_iter(session->streams, log_stream, session); }