blob: 16767fb785928a72da636b7cfe26d12d911184c2 [file] [log] [blame]
/* 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 __mod_h2__h2_session__
#define __mod_h2__h2_session__
#include "h2_conn_io.h"
/**
* A HTTP/2 connection, a session with a specific client.
*
* h2_session sits on top of a httpd conn_rec* instance and takes complete
* control of the connection data. It receives protocol frames from the
* client. For new HTTP/2 streams it creates h2_task(s) that are sent
* via callback to a dispatcher (see h2_conn.c).
* h2_session keeps h2_io's for each ongoing stream which buffer the
* payload for that stream.
*
* New incoming HEADER frames are converted into a h2_stream+h2_task instance
* that both represent a HTTP/2 stream, but may have separate lifetimes. This
* allows h2_task to be scheduled in other threads without semaphores
* all over the place. It allows task memory to be freed independant of
* session lifetime and sessions may close down while tasks are still running.
*
*
*/
struct apr_thread_mutext_t;
struct apr_thread_cond_t;
struct h2_config;
struct h2_mplx;
struct h2_priority;
struct h2_push;
struct h2_response;
struct h2_session;
struct h2_stream;
struct h2_task;
struct h2_workers;
struct nghttp2_session;
typedef struct h2_session h2_session;
struct h2_session {
long id; /* identifier of this session, unique
* inside a httpd process */
conn_rec *c; /* the connection this session serves */
request_rec *r; /* the request that started this in case
* of 'h2c', NULL otherwise */
int aborted; /* this session is being aborted */
int reprioritize; /* scheduled streams priority needs to
* be re-evaluated */
apr_size_t frames_received; /* number of http/2 frames received */
apr_size_t max_stream_count; /* max number of open streams */
apr_size_t max_stream_mem; /* max buffer memory for a single stream */
apr_pool_t *pool; /* pool to use in session handling */
apr_bucket_brigade *bbtmp; /* brigade for keeping temporary data */
struct apr_thread_cond_t *iowait; /* our cond when trywaiting for data */
h2_conn_io io; /* io on httpd conn filters */
struct h2_mplx *mplx; /* multiplexer for stream data */
struct h2_stream *last_stream; /* last stream worked with */
struct h2_stream_set *streams; /* streams handled by this session */
int max_stream_received; /* highest stream id created */
int max_stream_handled; /* highest stream id handled successfully */
apr_pool_t *spare; /* spare stream pool */
struct nghttp2_session *ngh2; /* the nghttp2 session (internal use) */
struct h2_workers *workers; /* for executing stream tasks */
};
/**
* Create a new h2_session for the given connection.
* The session will apply the configured parameter.
* @param c the connection to work on
* @param cfg the module config to apply
* @param workers the worker pool to use
* @return the created session
*/
h2_session *h2_session_create(conn_rec *c, struct h2_config *cfg,
struct h2_workers *workers);
/**
* Create a new h2_session for the given request.
* The session will apply the configured parameter.
* @param r the request that was upgraded
* @param cfg the module config to apply
* @param workers the worker pool to use
* @return the created session
*/
h2_session *h2_session_rcreate(request_rec *r, struct h2_config *cfg,
struct h2_workers *workers);
/**
* Process the given HTTP/2 session until it is ended or a fatal
* error occured.
*
* @param session the sessionm to process
*/
apr_status_t h2_session_process(h2_session *session);
/**
* Destroy the session and all objects it still contains. This will not
* destroy h2_task instances that have not finished yet.
* @param session the session to destroy
*/
void h2_session_destroy(h2_session *session);
/**
* Cleanup the session and all objects it still contains. This will not
* destroy h2_task instances that have not finished yet.
* @param session the session to destroy
*/
void h2_session_eoc_callback(h2_session *session);
/**
* Called once at start of session.
* Sets up the session and sends the initial SETTINGS frame.
* @param session the session to start
* @param rv error codes in libnghttp2 lingo are returned here
* @return APR_SUCCESS if all went well
*/
apr_status_t h2_session_start(h2_session *session, int *rv);
/**
* Called when an error occured and the session needs to shut down.
* @param session the session to shut down
* @param reason the apache status that caused the shutdown
* @param rv the nghttp2 reason for shutdown, set to 0 if you have none.
*
*/
apr_status_t h2_session_abort(h2_session *session, apr_status_t reason, int rv);
/**
* Called before a session gets destroyed, might flush output etc.
*/
apr_status_t h2_session_close(h2_session *session);
/* Start submitting the response to a stream request. This is possible
* once we have all the response headers. */
apr_status_t h2_session_handle_response(h2_session *session,
struct h2_stream *stream);
/* Get the h2_stream for the given stream idenrtifier. */
struct h2_stream *h2_session_get_stream(h2_session *session, int stream_id);
/**
* Create and register a new stream under the given id.
*
* @param session the session to register in
* @param stream_id the new stream identifier
* @return the new stream
*/
struct h2_stream *h2_session_open_stream(h2_session *session, int stream_id);
/**
* Returns if client settings have push enabled.
* @param != 0 iff push is enabled in client settings
*/
int h2_session_push_enabled(h2_session *session);
/**
* Destroy the stream and release it everywhere. Reclaim all resources.
* @param session the session to which the stream belongs
* @param stream the stream to destroy
*/
apr_status_t h2_session_stream_destroy(h2_session *session,
struct h2_stream *stream);
/**
* Submit a push promise on the stream and schedule the new steam for
* processing..
*
* @param session the session to work in
* @param is the stream initiating the push
* @param push the push to promise
* @return the new promised stream or NULL
*/
struct h2_stream *h2_session_push(h2_session *session,
struct h2_stream *is, struct h2_push *push);
apr_status_t h2_session_set_prio(h2_session *session,
struct h2_stream *stream,
struct h2_priority *prio);
#endif /* defined(__mod_h2__h2_session__) */