17#include <nghttp2/nghttp2.h>
31#define H2MIN(x,y) ((x) < (y) ? (x) : (y))
43#if defined(AP_MODULE_FLAG_NONE)
78 const char *
init_key =
"mod_proxy_http2_init_counter";
81 (void)
plog;(void)ptemp;
92 "mod_proxy_http2 (v%s, nghttp2 %s), initializing...",
130 "HTTP2: canonicalising URL %s",
url);
138 "error parsing URL %s: %s",
url,
err);
161#ifdef PROXY_CANONENC_NOENCODEDSLASHENCODING
187 "To be forwarded path contains control "
188 "characters or spaces");
193 "To be forwarded query string contains control "
194 "characters or spaces");
221 ctx->p_conn->connection->local_addr->port));
225 "pass request body failed to %pI (%s) from %s (%s)",
226 ctx->p_conn->addr,
ctx->p_conn->hostname ?
238 "h2_proxy_session(%s): request done, touched=%d, error=%d",
262 ctx->has_reusable_session = 0;
270 APLOGNO(03372)
"session unavailable");
275 "eng(%s): run session %s",
ctx->id, session->
id);
281 while (!
ctx->cfront->aborted && !
ctx->r_done) {
287 APLOGNO(03375)
"eng(%s): end of session %s",
288 ctx->id, session->
id);
299 if (
ctx->cfront->aborted) {
302 APLOGNO(03374)
"eng(%s): master connection gone",
ctx->id);
319 const char *proxy_func;
329 if ((
url[0] !=
'h' &&
url[0] !=
'H') ||
url[1] !=
'2') {
333 if (
u ==
NULL ||
u[1] !=
'/' ||
u[2] !=
'/' ||
u[3] ==
'\0') {
343 if (
url[2] !=
'c' &&
url[2] !=
'C') {
357 ctx->proxy_func = proxy_func;
358 ctx->is_ssl = is_ssl;
359 ctx->worker = worker;
361 ctx->req_buffer_size = (32*1024);
365 ctx->r_may_retry = 1;
372 "H2: serving URL %s",
url);
386 ctx->p_conn->is_ssl =
ctx->is_ssl;
395 sizeof(
ctx->server_portstr))) !=
OK) {
405 "H2: failed to make connection to backend: %s",
406 ctx->p_conn->hostname);
414 "setup new connection: is_ssl=%d %s %s %s",
415 ctx->p_conn->is_ssl,
ctx->p_conn->ssl_hostname,
421 if (!
ctx->p_conn->data &&
ctx->is_ssl) {
425 "proxy-request-alpn-protos",
"h2");
431 if (
ctx->r_status !=
OK &&
ctx->r_may_retry && !
ctx->cfront->aborted) {
434 ctx->p_conn->close = 1;
435#if AP_MODULE_MAGIC_AT_LEAST(20140207, 2)
446 "giving up after %d reconnects, request-done=%d",
455 ctx->p_conn->close = 1;
457#if AP_MODULE_MAGIC_AT_LEAST(20140207, 2)
466 APLOGNO(03377)
"leaving handler");
467 if (
ctx->r_status !=
OK) {
473 return ctx->r_status;
apr_size_t const unsigned char unsigned int unsigned int d
#define AP_MODULE_FLAG_ALWAYS_MERGE
void ap_hook_post_config(ap_HOOK_post_config_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
#define AP_DECLARE_MODULE(foo)
#define ap_set_module_config(v, m, val)
request_rec int int apr_table_t const char * path
#define ap_get_core_module_config(v)
int ap_map_http_request_error(apr_status_t rv, int status)
void ap_die(int type, request_rec *r)
const char apr_port_t port
apr_brigade_flush void * ctx
const char apr_ssize_t int flags
const char apr_ssize_t slen
#define APR_RETRIEVE_OPTIONAL_FN(name)
#define HTTP_SERVICE_UNAVAILABLE
int ap_proxy_connect_backend(const char *proxy_function, proxy_conn_rec *conn, proxy_worker *worker, server_rec *s)
char * ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp, char **passwordp, char **hostp, apr_port_t *port)
int ap_proxy_release_connection(const char *proxy_function, proxy_conn_rec *conn, server_rec *s)
int ap_proxy_acquire_connection(const char *proxy_function, proxy_conn_rec **conn, proxy_worker *worker, server_rec *s)
char * ap_proxy_canonenc_ex(apr_pool_t *p, const char *x, int len, enum enctype t, int flags, int proxyreq)
#define PROXY_CANONENC_NOENCODEDSLASHENCODING
void proxy_hook_canon_handler(proxy_HOOK_canon_handler_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
int ap_proxy_connection_create_ex(const char *proxy_function, proxy_conn_rec *conn, request_rec *r)
apr_port_t ap_proxy_port_of_scheme(const char *scheme)
int ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, proxy_server_conf *conf, proxy_worker *worker, proxy_conn_rec *conn, apr_uri_t *uri, char **url, const char *proxyname, apr_port_t proxyport, char *server_portstr, int server_portstr_size)
void proxy_hook_scheme_handler(proxy_HOOK_scheme_handler_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
char * ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t, int forcedec, int proxyreq)
#define STANDARD20_MODULE_STUFF
#define ap_strchr_c(s, c)
const char * ap_scan_vchar_obstext(const char *ptr)
int ap_cstr_casecmpn(const char *s1, const char *s2, apr_size_t n)
void const char apr_status_t(* cleanup)(void *))
apr_vformatter_buff_t * c
#define apr_pcalloc(p, size)
apr_int32_t apr_int32_t apr_int32_t err
int h2_proxy_session_is_reusable(h2_proxy_session *session)
apr_status_t h2_proxy_session_submit(h2_proxy_session *session, const char *url, request_rec *r, int standalone)
apr_status_t h2_proxy_session_process(h2_proxy_session *session)
void h2_proxy_session_cancel_all(h2_proxy_session *session)
h2_proxy_session * h2_proxy_session_setup(const char *id, proxy_conn_rec *p_conn, proxy_server_conf *conf, int h2_front, unsigned char window_bits_connection, unsigned char window_bits_stream, h2_proxy_request_done *done)
void h2_proxy_session_cleanup(h2_proxy_session *session, h2_proxy_request_done *done)
#define H2_PROXY_REQ_URL_NOTE
unsigned char h2_proxy_log2(int n)
#define MOD_HTTP2_VERSION
static const char * http_scheme(const request_rec *r)
static int http2_is_h2(conn_rec *)
Proxy Extension Module for Apache.
static int(* is_h2)(conn_rec *c)
static apr_status_t ctx_run(h2_proxy_ctx *ctx)
static void register_hook(apr_pool_t *p)
static apr_status_t add_request(h2_proxy_session *session, request_rec *r)
static int h2_proxy_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
static void session_req_done(h2_proxy_session *session, request_rec *r, apr_status_t status, int touched, int error_code)
static void request_done(h2_proxy_ctx *ctx, request_rec *r, apr_status_t status, int touched, int error_code)
static int proxy_http2_handler(request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, const char *proxyname, apr_port_t proxyport)
static int proxy_http2_canon(request_rec *r, char *url)
static sed_label_t * search(sed_commands_t *commands)
Structure to store things which are per connection.
Per-directory configuration.
apr_size_t req_buffer_size
A structure that represents the current request.
struct ap_conf_vector_t * per_dir_config
A structure to store information for each virtual server.
typedef int(WSAAPI *apr_winapi_fpt_WSAPoll)(IN OUT LPWSAPOLLFD fdArray