| /* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de) |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef h2_proxy_session_h |
| #define h2_proxy_session_h |
| |
| #define H2_ALEN(a) (sizeof(a)/sizeof((a)[0])) |
| |
| #include <nghttp2/nghttp2.h> |
| |
| struct h2_proxy_iqueue; |
| struct h2_proxy_ihash_t; |
| |
| typedef enum { |
| H2_PROXYS_ST_INIT, /* send initial SETTINGS, etc. */ |
| H2_PROXYS_ST_DONE, /* finished, connection close */ |
| H2_PROXYS_ST_IDLE, /* no streams to process */ |
| H2_PROXYS_ST_BUSY, /* read/write without stop */ |
| H2_PROXYS_ST_WAIT, /* waiting for tasks reporting back */ |
| H2_PROXYS_ST_LOCAL_SHUTDOWN, /* we announced GOAWAY */ |
| H2_PROXYS_ST_REMOTE_SHUTDOWN, /* client announced GOAWAY */ |
| } h2_proxys_state; |
| |
| typedef enum { |
| H2_PROXYS_EV_INIT, /* session was initialized */ |
| H2_PROXYS_EV_LOCAL_GOAWAY, /* we send a GOAWAY */ |
| H2_PROXYS_EV_REMOTE_GOAWAY, /* remote send us a GOAWAY */ |
| H2_PROXYS_EV_CONN_ERROR, /* connection error */ |
| H2_PROXYS_EV_PROTO_ERROR, /* protocol error */ |
| H2_PROXYS_EV_CONN_TIMEOUT, /* connection timeout */ |
| H2_PROXYS_EV_NO_IO, /* nothing has been read or written */ |
| H2_PROXYS_EV_STREAM_SUBMITTED, /* stream has been submitted */ |
| H2_PROXYS_EV_STREAM_DONE, /* stream has been finished */ |
| H2_PROXYS_EV_STREAM_RESUMED, /* stream signalled availability of headers/data */ |
| H2_PROXYS_EV_DATA_READ, /* connection data has been read */ |
| H2_PROXYS_EV_NGH2_DONE, /* nghttp2 wants neither read nor write anything */ |
| H2_PROXYS_EV_PRE_CLOSE, /* connection will close after this */ |
| } h2_proxys_event_t; |
| |
| |
| typedef struct h2_proxy_session h2_proxy_session; |
| typedef void h2_proxy_request_done(h2_proxy_session *s, request_rec *r, |
| apr_status_t status, int touched); |
| |
| struct h2_proxy_session { |
| const char *id; |
| conn_rec *c; |
| proxy_conn_rec *p_conn; |
| proxy_server_conf *conf; |
| apr_pool_t *pool; |
| nghttp2_session *ngh2; /* the nghttp2 session itself */ |
| |
| unsigned int aborted : 1; |
| unsigned int check_ping : 1; |
| unsigned int h2_front : 1; /* if front-end connection is HTTP/2 */ |
| |
| h2_proxy_request_done *done; |
| void *user_data; |
| |
| unsigned char window_bits_stream; |
| unsigned char window_bits_connection; |
| |
| h2_proxys_state state; |
| apr_interval_time_t wait_timeout; |
| |
| struct h2_proxy_ihash_t *streams; |
| struct h2_proxy_iqueue *suspended; |
| apr_size_t remote_max_concurrent; |
| int last_stream_id; /* last stream id processed by backend, or 0 */ |
| apr_time_t last_frame_received; |
| |
| apr_bucket_brigade *input; |
| apr_bucket_brigade *output; |
| }; |
| |
| 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); |
| |
| apr_status_t h2_proxy_session_submit(h2_proxy_session *s, const char *url, |
| request_rec *r, int standalone); |
| |
| /** |
| * Perform a step in processing the proxy session. Will return aftert |
| * one read/write cycle and indicate session status by status code. |
| * @param s the session to process |
| * @return APR_EAGAIN when processing needs to be invoked again |
| * APR_SUCCESS when all streams have been processed, session still live |
| * APR_EOF when the session has been terminated |
| */ |
| apr_status_t h2_proxy_session_process(h2_proxy_session *s); |
| |
| void h2_proxy_session_cancel_all(h2_proxy_session *s); |
| |
| void h2_proxy_session_cleanup(h2_proxy_session *s, h2_proxy_request_done *done); |
| |
| void h2_proxy_session_update_window(h2_proxy_session *s, |
| conn_rec *c, apr_off_t bytes); |
| |
| #define H2_PROXY_REQ_URL_NOTE "h2-proxy-req-url" |
| |
| #endif /* h2_proxy_session_h */ |