/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 MODULES_CONTEXTSPLIT_CS_HOOKS_H_
#define MODULES_CONTEXTSPLIT_CS_HOOKS_H_

#ifdef __cpluscplus
extern "C" {
#endif

#include "httpd.h"
#include "http_core.h"
#include "mpm_common.h"

/*--------------------------------------------------------------------------*
 *                                                                          *
 * Declare routines for each of the callback hook. Note that                *
 * these may be called for situations that don't relate primarily to our    *
 * function - e.g. the fixup handler shouldn't assume that the request has  *
 * to do with "contextsplit" stuff.                                         *
 *                                                                          *
 * With the exception of the content handler, all of our routines will be   *
 * called for each request, unless an earlier handler from another module   *
 * aborted the sequence.                                                    *
 *                                                                          *
 * There are three types of hooks (see include/ap_config.h):                *
 *                                                                          *
 * VOID      : No return code, run all handlers declared by any module      *
 * RUN_FIRST : Run all handlers until one returns something other           *
 *             than DECLINED. Hook runner result is result of last callback *
 * RUN_ALL   : Run all handlers until one returns something other than OK   *
 *             or DECLINED. The hook runner returns that other value. If    *
 *             all hooks run, the hook runner returns OK.                   *
 *                                                                          *
 * Handlers that are declared as "int" can return the following:            *
 *                                                                          *
 *  OK          Handler accepted the request and did its thing with it.     *
 *  DECLINED    Handler took no action.                                     *
 *  HTTP_mumble Handler looked at request and found it wanting.             *
 *                                                                          *
 * See include/httpd.h for a list of HTTP_mumble status codes.  Handlers    *
 * that are not declared as int return a valid pointer, or NULL if they     *
 * DECLINE to handle their phase for that specific request.  Exceptions, if *
 * any, are noted with each routine.                                        *
 *--------------------------------------------------------------------------*/


/*************************************************************
 * These hooks are useful hooks to the configuration and startup
 * of the server.
 **************************************************************/
/*
 * The process initialiser hook, called when a server process is started.
 *
 * This is a VOID hook: all defined handlers get called.
 */
void
cs_hookv_child_init(apr_pool_t *p, server_rec *s);

/*
 * This is not a hook, instead it is a function that can be registered to
 * do any saving, cleaning up, etc, when the process ends gracefully.
 */
apr_status_t
cs_nonhook_child_exit(void *data);

/*
 * This routine is called before the server processes the configuration
 * files.  There is no return value.
 */
int
cs_hooka_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                        apr_pool_t *ptemp);

/*
 * This routine is called after the server processes the configuration
 * files.  At this point the module may review and adjust its configuration
 * settings in relation to one another and report any problems.  On restart,
 * this routine will be called twice, once in the startup process (which
 * exits shortly after this phase) and once in the running server process.
 *
 * The return value is OK, DECLINED, or HTTP_mumble.  If we return OK, the
 * server will still call any remaining modules with an handler for this
 * phase.
 *
 * This is a RUN_ALL hook.
 *
 */
int
cs_hooka_check_config(apr_pool_t *pconf, apr_pool_t *plog,
                          apr_pool_t *ptemp, server_rec *s);


/*
 * This routine is called when the -t command-line option is supplied.
 * It executes only once, in the startup process, after the check_config
 * phase and just before the process exits.  At this point the module
 * may output any information useful in configuration testing.
 *
 * This is a VOID hook: all defined handlers get called.
 */
void
cs_hookv_test_config(apr_pool_t *pconf, server_rec *s);

/*
 * The runner for this hook is aliased to ap_default_port(), which the
 * core and other modules call when they need to know the default port
 * for a particular server.  This is used for instance to omit the
 * port number from a Redirect response Location header URL if the port
 * number is equal to the default port for the service (like 80 for http).
 *
 * This is a RUN_FIRST hook: the first handler to return a non-zero
 * value is the last one executed.  The http_core module inserts a
 * fallback handler (with APR_HOOK_REALLY_LAST order specifier) that
 * returns 80.
 */
apr_port_t
cs_hookf_default_port(const request_rec *r);

/*
 * The hook runner for ap_hook_http_scheme is aliased to ap_http_scheme(),
 * a routine that the core and other modules call when they need to know
 * the URL scheme for the request.  For instance, mod_ssl returns "https"
 * if the server_rec associated with the request has SSL enabled.
 *
 * This hook was named 'ap_hook_http_method' in httpd 2.0.
 *
 * This is a RUN_FIRST hook: the first handler to return a non NULL
 * value aborts the handler chain.  The http_core module inserts a
 * fallback handler (with APR_HOOK_REALLY_LAST preference) that returns
 * "http".
 */
const char *
cs_hookf_http_scheme(const request_rec *r);


/*
 * This routine is called to perform any module-specific log file
 * openings. It is invoked just before the post_config phase
 *
 * The return value is OK, DECLINED, or HTTP_mumble.  If we return OK, the
 * server will still call any remaining modules with an handler for this
 * phase.
 *
 * This is a RUN_ALL hook.
 */
int
cs_hooka_open_logs(apr_pool_t *pconf, apr_pool_t *plog,
                        apr_pool_t *ptemp, server_rec *s);

/*
 * This routine is called after the server finishes the configuration
 * process.  At this point the module may review and adjust its configuration
 * settings in relation to one another and report any problems.  On restart,
 * this routine will be called only once, in the running server process.
 *
 * The return value is OK, DECLINED, or HTTP_mumble.  If we return OK, the
 * server will still call any remaining modules with an handler for this
 * phase.
 */
int
cs_hooka_post_config(apr_pool_t *pconf, apr_pool_t *plog,
                          apr_pool_t *ptemp, server_rec *s);


/*************************************************************
 * These hooks are useful hooks in the protocol stack that are
 * associated with a connection rather than a request.
 **************************************************************/
/*
 * This routine is called just after the server accepts the connection,
 * but before it is handed off to a protocol module to be served.  The point
 * of this hook is to allow modules an opportunity to modify the connection
 * as soon as possible. The core server uses this phase to setup the
 * connection record based on the type of connection that is being used.
 *
 * This is a RUN_ALL hook.
 */
int
cs_hooka_pre_connection(conn_rec *c, void *csd);

/* This routine is used to actually process the connection that was received.
 * Only protocol modules should implement this hook, as it gives them an
 * opportunity to replace the standard HTTP processing with processing for
 * some other protocol.  Both echo and POP3 modules are available as
 * examples.
 *
 * This is a RUN_FIRST hook.
 */
int
cs_hookf_process_connection(conn_rec *c);

/*************************************************************
 * These hooks are useful hooks on the datapath.
 *
 * Where nothing is needed at present, the function is a stub
 * for use, if required, in future.
 **************************************************************/
/*
 * The quick_handler hook presents modules with a very powerful opportunity to
 * serve their content in a very early request phase.  Note that this handler
 * can not serve any requests from the file system because hooks like
 * map_to_storage have not run.  The quick_handler hook also runs before any
 * authentication and access control.
 *
 * This hook is used by mod_cache to serve cached content.
 *
 * This is a RUN_FIRST hook. Return OK if you have served the request,
 * DECLINED if you want processing to continue, or a HTTP_* error code to stop
 * processing the request.
 */
int
cs_hookf_quick_handler(request_rec *r, int lookup_uri);

/*
 * Sample content handler.  All this does is display the call list that has
 * been built up so far.
 *
 * This routine gets called for every request, unless another handler earlier
 * in the callback chain has already handled the request. It is up to us to
 * test the request_rec->handler field and see whether we are meant to handle
 * this request.
 *
 * The content handler gets to write directly to the client using calls like
 * ap_rputs() and ap_rprintf()
 *
 * This is a RUN_FIRST hook.
 *
 * Useful things to note:
 * 1) checking if the request if for you
 *   		if (strcmp(r->handler, "contextsplit")) {
 *      		 return DECLINED;
 *   		}
 * 2) setting the content type of the data to be returned
 *    note that headers can done by http core instead of here
 *   		ap_set_content_type(r, "text/html");
 * 3) sending of headers - the documentation is contradictory on this
 *    I think it is done automatically and you have to try hard to
 *    avoid it. The asis module does though - this is to "send as is"
 *    expexting the header information to be in the file.
 * 4) Actual output content generation and sending
 *   		ap_rputs(DOCTYPE_HTML_3_2, r);
 *   		ap_rputs("<HTML>\n", r);
 *   		ap_rputs(" <HEAD>\n", r);
 *   ap_rprintf(r, "<TITLE>Apache HTTP Server version: \"%s\"</TITLE>\n",
            ap_get_server_banner());
 *   		...
 *
 */
int
cs_hookf_handler(request_rec *r);

/*
 * This routine is called just before the handler gets invoked. It allows
 * a module to insert a previously defined filter into the filter chain.
 *
 * This is a VOID hook: all defined handlers get called.
 */
void
cs_hookv_insert_filter(request_rec *r);

/*
 * This routine is called after the request has been read but before any other
 * phases have been processed.  This allows us to make decisions based upon
 * the input header fields.
 *
 * This is a HOOK_VOID hook.
 */
void
cs_hookv_pre_read_request(request_rec *r, conn_rec *c);

/*
 * This routine is called after the request has been read but before any other
 * phases have been processed.  This allows us to make decisions based upon
 * the input header fields.
 *
 * This is a RUN_ALL hook.
 */
int
cs_hooka_post_read_request(request_rec *r);

/*
 * This routine gives our module an opportunity to translate the URI into an
 * actual filename.  If we don't do anything special, the server's default
 * rules (Alias directives and the like) will continue to be followed.
 *
 * This is a RUN_FIRST hook.
 */
int
cs_hookf_translate_name(request_rec *r);

/*
 * This routine maps r->filename to a physical file on disk.  Useful for
 * overriding default core behavior, including skipping mapping for
 * requests that are not file based.
 *
 * This is a RUN_FIRST hook.
 */
int
cs_hookf_map_to_storage(request_rec *r);

/*
 * this routine gives our module another chance to examine the request
 * headers and to take special action. This is the first phase whose
 * hooks' configuration directives can appear inside the <Directory>
 * and similar sections, because at this stage the URI has been mapped
 * to the filename. For example this phase can be used to block evil
 * clients, while little resources were wasted on these.
 *
 * This is a RUN_ALL hook.
 */
int
cs_hooka_header_parser(request_rec *r);

/*
 * This routine is called to check for any module-specific restrictions placed
 * upon the requested resource.  (See the mod_access_compat module for an
 * example.)
 *
 * This is a RUN_ALL hook. The first handler to return a status other than OK
 * or DECLINED (for instance, HTTP_FORBIDDEN) aborts the callback chain.
 */
int
cs_hooka_check_access(request_rec *r);

/*
 * This routine is called to check the authentication information sent with
 * the request (such as looking up the user in a database and verifying that
 * the [encrypted] password sent matches the one in the database).
 *
 * This is a RUN_FIRST hook. The return value is OK, DECLINED, or some
 * HTTP_mumble error (typically HTTP_UNAUTHORIZED).
 */
int
cs_hookf_check_authn(request_rec *r);

/*
 * This routine is called to check to see if the resource being requested
 * requires authorisation.
 *
 * This is a RUN_FIRST hook. The return value is OK, DECLINED, or
 * HTTP_mumble.  If we return OK, no other modules are called during this
 * phase.
 *
 * If *all* modules return DECLINED, the request is aborted with a server
 * error.
 */
int
cs_hookf_check_authz(request_rec *r);

/*
 * This routine is called to determine and/or set the various document type
 * information bits, like Content-type (via r->content_type), language, et
 * cetera.
 *
 * This is a RUN_FIRST hook.
 */
int
cs_hookf_type_checker(request_rec *r);

/*
 * This routine is called to perform any module-specific fixing of header
 * fields, et cetera.  It is invoked just before any content-handler.
 *
 * This is a RUN_ALL HOOK.
 */
int
cs_hooka_fixups(request_rec *r);


/*************************************************************
 * These hooks are included as points where server logging may
 * take place, or where there may be reasons to implement functionality
 * in the future, or where it may be useful to generate debugging output.
 **************************************************************/

/*
 * This routine is called to perform any module-specific logging activities
 * over and above the normal server things.
 *
 * This is a RUN_ALL hook.
 */
int
cs_hooka_log_transaction(request_rec *r);


/*************************************************************
 * These hooks are included as part of the error handling stack.
 **************************************************************/
/*
 * This routine is called to insert a previously defined error filter into
 * the filter chain as the request is being processed.
 *
 * This is a VOID hook: all defined handlers get called.
 */
void
cs_hookv_insert_error_filter(request_rec *r);

/*************************************************************
 * These hooks are included to provide a complete set of hooks,
 * to allow any future development to make use of them (such as
 * for debugging).
 *
 * In most cases, their use is not obvious, documentation of the
 * function is sketchy to non-existent and there is no obvious reason
 * to use the function.
 *
 * HERE THERE BE DRAGONS
 *
 **************************************************************/

#ifdef HAVE_UNIX_SUEXEC

/*
 * This routine is called to find out under which user id to run suexec
 * Unless our module runs CGI programs, there is no reason for us to
 * mess with this information.
 *
 * This is a RUN_FIRST hook. The return value is a pointer to an
 * ap_unix_identity_t or NULL.
 */
ap_unix_identity_t *
cs_hookf_get_suexec_identity(const request_rec *r);
#endif

/*
 * This routine is called to create a connection. This hook is implemented
 * by the Apache core: there is no known reason a module should override
 * it.
 *
 * This is a RUN_FIRST hook.
 *
 * Return NULL to decline, a valid conn_rec pointer to accept.
 */
conn_rec *
cs_hookf_create_connection(apr_pool_t *p, server_rec *server,
                    apr_socket_t *csd, long conn_id,
                    void *sbh, apr_bucket_alloc_t *alloc);

/*
 * This hook is defined in server/core.c, but it is not actually called
 * or documented.
 *
 * This is a RUN_ALL hook.
 */
int
cs_hooka_get_mgmt_items(apr_pool_t *p, const char *val, apr_hash_t *ht);


/*
 * This routine gets called shortly after the request_rec structure
 * is created. It provides the opportunity to manipulate the request
 * at a very early stage.
 *
 * This is a RUN_ALL hook.
 */
int
cs_hooka_create_request(request_rec *r);

/*
 * This routine gets called during the startup of the MPM.
 * No known existing module implements this hook.
 *
 * This is a RUN_ALL hook.
 */
int
cs_hooka_pre_mpm(apr_pool_t *p, ap_scoreboard_e sb_type);

/*
 * This hook gets run periodically by a maintenance function inside
 * the MPM. Its exact purpose is unknown and undocumented at this time.
 *
 * This is a RUN_ALL hook
 */
int
cs_hooka_monitor(apr_pool_t *p, server_rec *s);

#ifdef __cpluscplus
}
#endif

#endif /* MODULES_CONTEXTSPLIT_CS_HOOKS_H_ */
