Main Page | Modules | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages | Examples

http_core.h

Go to the documentation of this file.
00001 /* Copyright 1999-2005 The Apache Software Foundation or its licensors, as
00002  * applicable.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #ifndef APACHE_HTTP_CORE_H
00018 #define APACHE_HTTP_CORE_H
00019 
00020 #include "apr.h"
00021 #include "apr_hash.h"
00022 #include "apr_optional.h"
00023 #include "util_filter.h"
00024 
00025 #if APR_HAVE_STRUCT_RLIMIT
00026 #include <sys/time.h>
00027 #include <sys/resource.h>
00028 #endif
00029 
00030 
00031 #ifdef __cplusplus
00032 extern "C" {
00033 #endif
00034 
00035 /**
00036  * @package CORE HTTP Daemon
00037  */
00038 
00039 /* ****************************************************************
00040  *
00041  * The most basic server code is encapsulated in a single module
00042  * known as the core, which is just *barely* functional enough to
00043  * serve documents, though not terribly well.
00044  *
00045  * Largely for NCSA back-compatibility reasons, the core needs to
00046  * make pieces of its config structures available to other modules.
00047  * The accessors are declared here, along with the interpretation
00048  * of one of them (allow_options).
00049  */
00050 
00051 #define OPT_NONE 0
00052 #define OPT_INDEXES 1
00053 #define OPT_INCLUDES 2
00054 #define OPT_SYM_LINKS 4
00055 #define OPT_EXECCGI 8
00056 #define OPT_UNSET 16
00057 #define OPT_INCNOEXEC 32
00058 #define OPT_SYM_OWNER 64
00059 #define OPT_MULTI 128
00060 #define OPT_ALL (OPT_INDEXES|OPT_INCLUDES|OPT_SYM_LINKS|OPT_EXECCGI)
00061 
00062 /* options for get_remote_host() */
00063 /* REMOTE_HOST returns the hostname, or NULL if the hostname
00064  * lookup fails.  It will force a DNS lookup according to the
00065  * HostnameLookups setting.
00066  */
00067 #define REMOTE_HOST (0)
00068 
00069 /* REMOTE_NAME returns the hostname, or the dotted quad if the
00070  * hostname lookup fails.  It will force a DNS lookup according
00071  * to the HostnameLookups setting.
00072  */
00073 #define REMOTE_NAME (1)
00074 
00075 /* REMOTE_NOLOOKUP is like REMOTE_NAME except that a DNS lookup is
00076  * never forced.
00077  */
00078 #define REMOTE_NOLOOKUP (2)
00079 
00080 /* REMOTE_DOUBLE_REV will always force a DNS lookup, and also force
00081  * a double reverse lookup, regardless of the HostnameLookups
00082  * setting.  The result is the (double reverse checked) hostname,
00083  * or NULL if any of the lookups fail.
00084  */
00085 #define REMOTE_DOUBLE_REV (3)
00086 
00087 #define SATISFY_ALL 0
00088 #define SATISFY_ANY 1
00089 #define SATISFY_NOSPEC 2
00090 
00091 /* Make sure we don't write less than 8000 bytes at any one time.
00092  */
00093 #define AP_MIN_BYTES_TO_WRITE  8000
00094 
00095 /* default maximum of internal redirects */
00096 # define AP_DEFAULT_MAX_INTERNAL_REDIRECTS 10
00097 
00098 /* default maximum subrequest nesting level */
00099 # define AP_DEFAULT_MAX_SUBREQ_DEPTH 10
00100 
00101 /**
00102  * Retrieve the value of Options for this request
00103  * @param r The current request
00104  * @return the Options bitmask
00105  * @deffunc int ap_allow_options(request_rec *r)
00106  */
00107 AP_DECLARE(int) ap_allow_options(request_rec *r);
00108 
00109 /**
00110  * Retrieve the value of the AllowOverride for this request
00111  * @param r The current request
00112  * @return the overrides bitmask
00113  * @deffunc int ap_allow_overrides(request_rec *r)
00114  */
00115 AP_DECLARE(int) ap_allow_overrides(request_rec *r);
00116 
00117 /**
00118  * Retrieve the value of the DefaultType directive, or text/plain if not set
00119  * @param r The current request
00120  * @return The default type
00121  * @deffunc const char *ap_default_type(request_rec *r)
00122  */
00123 AP_DECLARE(const char *) ap_default_type(request_rec *r);     
00124 
00125 /**
00126  * Retrieve the document root for this server
00127  * @param r The current request
00128  * @warning Don't use this!  If your request went through a Userdir, or 
00129  * something like that, it'll screw you.  But it's back-compatible...
00130  * @return The document root
00131  * @deffunc const char *ap_document_root(request_rec *r)
00132  */
00133 AP_DECLARE(const char *) ap_document_root(request_rec *r);
00134 
00135 /**
00136  * Lookup the remote client's DNS name or IP address
00137  * @param conn The current connection
00138  * @param dir_config The directory config vector from the request
00139  * @param type The type of lookup to perform.  One of:
00140  * <pre>
00141  *     REMOTE_HOST returns the hostname, or NULL if the hostname
00142  *                 lookup fails.  It will force a DNS lookup according to the
00143  *                 HostnameLookups setting.
00144  *     REMOTE_NAME returns the hostname, or the dotted quad if the
00145  *                 hostname lookup fails.  It will force a DNS lookup according
00146  *                 to the HostnameLookups setting.
00147  *     REMOTE_NOLOOKUP is like REMOTE_NAME except that a DNS lookup is
00148  *                     never forced.
00149  *     REMOTE_DOUBLE_REV will always force a DNS lookup, and also force
00150  *                   a double reverse lookup, regardless of the HostnameLookups
00151  *                   setting.  The result is the (double reverse checked) 
00152  *                   hostname, or NULL if any of the lookups fail.
00153  * </pre>
00154  * @param str_is_ip unless NULL is passed, this will be set to non-zero on output when an IP address 
00155  *        string is returned
00156  * @return The remote hostname
00157  * @deffunc const char *ap_get_remote_host(conn_rec *conn, void *dir_config, int type, int *str_is_ip)
00158  */
00159 AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config, int type, int *str_is_ip);
00160 
00161 /**
00162  * Retrieve the login name of the remote user.  Undef if it could not be
00163  * determined
00164  * @param r The current request
00165  * @return The user logged in to the client machine
00166  * @deffunc const char *ap_get_remote_logname(request_rec *r)
00167  */
00168 AP_DECLARE(const char *) ap_get_remote_logname(request_rec *r);
00169 
00170 /* Used for constructing self-referencing URLs, and things like SERVER_PORT,
00171  * and SERVER_NAME.
00172  */
00173 /**
00174  * build a fully qualified URL from the uri and information in the request rec
00175  * @param p The pool to allocate the URL from
00176  * @param uri The path to the requested file
00177  * @param r The current request
00178  * @return A fully qualified URL
00179  * @deffunc char *ap_construct_url(apr_pool_t *p, const char *uri, request_rec *r)
00180  */
00181 AP_DECLARE(char *) ap_construct_url(apr_pool_t *p, const char *uri, request_rec *r);
00182 
00183 /**
00184  * Get the current server name from the request
00185  * @param r The current request
00186  * @return the server name
00187  * @deffunc const char *ap_get_server_name(request_rec *r)
00188  */
00189 AP_DECLARE(const char *) ap_get_server_name(request_rec *r);
00190 
00191 /**
00192  * Get the current server port
00193  * @param The current request
00194  * @return The server's port
00195  * @deffunc apr_port_t ap_get_server_port(const request_rec *r)
00196  */
00197 AP_DECLARE(apr_port_t) ap_get_server_port(const request_rec *r);
00198 
00199 /**
00200  * Return the limit on bytes in request msg body 
00201  * @param r The current request
00202  * @return the maximum number of bytes in the request msg body
00203  * @deffunc apr_off_t ap_get_limit_req_body(const request_rec *r)
00204  */
00205 AP_DECLARE(apr_off_t) ap_get_limit_req_body(const request_rec *r);
00206 
00207 /**
00208  * Return the limit on bytes in XML request msg body
00209  * @param r The current request
00210  * @return the maximum number of bytes in XML request msg body
00211  * @deffunc size_t ap_get_limit_xml_body(const request_rec *r)
00212  */
00213 AP_DECLARE(size_t) ap_get_limit_xml_body(const request_rec *r);
00214 
00215 /**
00216  * Install a custom response handler for a given status
00217  * @param r The current request
00218  * @param status The status for which the custom response should be used
00219  * @param string The custom response.  This can be a static string, a file
00220  *               or a URL
00221  */
00222 AP_DECLARE(void) ap_custom_response(request_rec *r, int status, const char *string);
00223 
00224 /**
00225  * Check if the current request is beyond the configured max. number of redirects or subrequests
00226  * @param r The current request
00227  * @return true (is exceeded) or false
00228  * @deffunc int ap_is_recursion_limit_exceeded(const request_rec *r)
00229  */
00230 AP_DECLARE(int) ap_is_recursion_limit_exceeded(const request_rec *r);
00231 
00232 /**
00233  * Check for a definition from the server command line
00234  * @param name The define to check for
00235  * @return 1 if defined, 0 otherwise
00236  * @deffunc int ap_exists_config_define(const char *name)
00237  */
00238 AP_DECLARE(int) ap_exists_config_define(const char *name);
00239 /* FIXME! See STATUS about how */
00240 AP_DECLARE_NONSTD(int) ap_core_translate(request_rec *r);
00241 
00242 /* Authentication stuff.  This is one of the places where compatibility
00243  * with the old config files *really* hurts; they don't discriminate at
00244  * all between different authentication schemes, meaning that we need
00245  * to maintain common state for all of them in the core, and make it
00246  * available to the other modules through interfaces.
00247  */
00248 typedef struct require_line require_line;
00249 
00250 /** A structure to keep track of authorization requirements */
00251 struct require_line {
00252     /** Where the require line is in the config file. */
00253     apr_int64_t method_mask;
00254     /** The complete string from the command line */
00255     char *requirement;
00256 };
00257      
00258 /**
00259  * Return the type of authorization required for this request
00260  * @param r The current request
00261  * @return The authorization required
00262  * @deffunc const char *ap_auth_type(request_rec *r)
00263  */
00264 AP_DECLARE(const char *) ap_auth_type(request_rec *r);
00265 
00266 /**
00267  * Return the current Authorization realm
00268  * @param r The current request
00269  * @return The current authorization realm
00270  * @deffunc const char *ap_auth_name(request_rec *r)
00271  */
00272 AP_DECLARE(const char *) ap_auth_name(request_rec *r);     
00273 
00274 /**
00275  * How the requires lines must be met.
00276  * @param r The current request
00277  * @return How the requirements must be met.  One of:
00278  * <pre>
00279  *      SATISFY_ANY    -- any of the requirements must be met.
00280  *      SATISFY_ALL    -- all of the requirements must be met.
00281  *      SATISFY_NOSPEC -- There are no applicable satisfy lines
00282  * </pre>
00283  * @deffunc int ap_satisfies(request_rec *r)
00284  */
00285 AP_DECLARE(int) ap_satisfies(request_rec *r);
00286 
00287 /**
00288  * Retrieve information about all of the requires directives for this request
00289  * @param r The current request
00290  * @return An array of all requires directives for this request
00291  * @deffunc const apr_array_header_t *ap_requires(request_rec *r)
00292  */
00293 AP_DECLARE(const apr_array_header_t *) ap_requires(request_rec *r);    
00294 
00295 #ifdef CORE_PRIVATE
00296 
00297 /*
00298  * Core is also unlike other modules in being implemented in more than
00299  * one file... so, data structures are declared here, even though most of
00300  * the code that cares really is in http_core.c.  Also, another accessor.
00301  */
00302 
00303 AP_DECLARE_DATA extern module core_module;
00304 
00305 /* Per-request configuration */
00306 
00307 typedef struct {
00308     /* bucket brigade used by getline for look-ahead and 
00309      * ap_get_client_block for holding left-over request body */
00310     struct apr_bucket_brigade *bb;
00311 
00312     /* an array of per-request working data elements, accessed
00313      * by ID using ap_get_request_note()
00314      * (Use ap_register_request_note() during initialization
00315      * to add elements)
00316      */
00317     void **notes;
00318 
00319     /* There is a script processor installed on the output filter chain,
00320      * so it needs the default_handler to deliver a (script) file into
00321      * the chain so it can process it. Normally, default_handler only
00322      * serves files on a GET request (assuming the file is actual content),
00323      * since other methods are not content-retrieval. This flag overrides
00324      * that behavior, stating that the "content" is actually a script and
00325      * won't actually be delivered as the response for the non-GET method.
00326      */
00327     int deliver_script;
00328 
00329     /* Custom response strings registered via ap_custom_response(),
00330      * or NULL; check per-dir config if nothing found here
00331      */
00332     char **response_code_strings; /* from ap_custom_response(), not from
00333                                    * ErrorDocument
00334                                    */
00335 } core_request_config;
00336 
00337 /* Standard entries that are guaranteed to be accessible via
00338  * ap_get_request_note() for each request (additional entries
00339  * can be added with ap_register_request_note())
00340  */
00341 #define AP_NOTE_DIRECTORY_WALK 0
00342 #define AP_NOTE_LOCATION_WALK  1
00343 #define AP_NOTE_FILE_WALK      2
00344 #define AP_NUM_STD_NOTES       3
00345 
00346 /**
00347  * Reserve an element in the core_request_config->notes array
00348  * for some application-specific data
00349  * @return An integer key that can be passed to ap_get_request_note()
00350  *         during request processing to access this element for the
00351  *         current request.
00352  */
00353 AP_DECLARE(apr_size_t) ap_register_request_note(void);
00354 
00355 /**
00356  * Retrieve a pointer to an element in the core_request_config->notes array
00357  * @param r The request
00358  * @param note_num  A key for the element: either a value obtained from
00359  *        ap_register_request_note() or one of the predefined AP_NOTE_*
00360  *        values.
00361  * @return NULL if the note_num is invalid, otherwise a pointer to the
00362  *         requested note element.
00363  * @remark At the start of a request, each note element is NULL.  The
00364  *         handle provided by ap_get_request_note() is a pointer-to-pointer
00365  *         so that the caller can point the element to some app-specific
00366  *         data structure.  The caller should guarantee that any such
00367  *         structure will last as long as the request itself.
00368  */
00369 AP_DECLARE(void **) ap_get_request_note(request_rec *r, apr_size_t note_num);
00370 
00371 /* Per-directory configuration */
00372 
00373 typedef unsigned char allow_options_t;
00374 typedef unsigned char overrides_t;
00375 
00376 /*
00377  * Bits of info that go into making an ETag for a file
00378  * document.  Why a long?  Because char historically
00379  * proved too short for Options, and int can be different
00380  * sizes on different platforms.
00381  */
00382 typedef unsigned long etag_components_t;
00383 
00384 #define ETAG_UNSET 0
00385 #define ETAG_NONE  (1 << 0)
00386 #define ETAG_MTIME (1 << 1)
00387 #define ETAG_INODE (1 << 2)
00388 #define ETAG_SIZE  (1 << 3)
00389 #define ETAG_BACKWARD (ETAG_MTIME | ETAG_INODE | ETAG_SIZE)
00390 #define ETAG_ALL   (ETAG_MTIME | ETAG_INODE | ETAG_SIZE)
00391 
00392 typedef enum {
00393     srv_sig_unset,
00394     srv_sig_off,
00395     srv_sig_on,
00396     srv_sig_withmail
00397 } server_signature_e;
00398 
00399 typedef struct {
00400     /* path of the directory/regex/etc. see also d_is_fnmatch/absolute below */
00401     char *d;
00402     /* the number of slashes in d */
00403     unsigned d_components;
00404 
00405     /* If (opts & OPT_UNSET) then no absolute assignment to options has
00406      * been made.
00407      * invariant: (opts_add & opts_remove) == 0
00408      * Which said another way means that the last relative (options + or -)
00409      * assignment made to each bit is recorded in exactly one of opts_add
00410      * or opts_remove.
00411      */
00412     allow_options_t opts;
00413     allow_options_t opts_add;
00414     allow_options_t opts_remove;
00415     overrides_t override;
00416     
00417     /* MIME typing --- the core doesn't do anything at all with this,
00418      * but it does know what to slap on a request for a document which
00419      * goes untyped by other mechanisms before it slips out the door...
00420      */
00421     
00422     char *ap_default_type;
00423   
00424     /* Authentication stuff.  Groan... */
00425     
00426     int *satisfy; /* for every method one */
00427     char *ap_auth_type;
00428     char *ap_auth_name;
00429     apr_array_header_t *ap_requires;
00430 
00431     /* Custom response config. These can contain text or a URL to redirect to.
00432      * if response_code_strings is NULL then there are none in the config,
00433      * if it's not null then it's allocated to sizeof(char*)*RESPONSE_CODES.
00434      * This lets us do quick merges in merge_core_dir_configs().
00435      */
00436   
00437     char **response_code_strings; /* from ErrorDocument, not from
00438                                    * ap_custom_response() */
00439 
00440     /* Hostname resolution etc */
00441 #define HOSTNAME_LOOKUP_OFF     0
00442 #define HOSTNAME_LOOKUP_ON      1
00443 #define HOSTNAME_LOOKUP_DOUBLE  2
00444 #define HOSTNAME_LOOKUP_UNSET   3
00445     unsigned int hostname_lookups : 4;
00446 
00447     signed int do_rfc1413 : 2;   /* See if client is advertising a username? */
00448 
00449     signed int content_md5 : 2;  /* calculate Content-MD5? */
00450 
00451 #define USE_CANONICAL_NAME_OFF   (0)
00452 #define USE_CANONICAL_NAME_ON    (1)
00453 #define USE_CANONICAL_NAME_DNS   (2)
00454 #define USE_CANONICAL_NAME_UNSET (3)
00455     unsigned use_canonical_name : 2;
00456 
00457     /* since is_fnmatch(conf->d) was being called so frequently in
00458      * directory_walk() and its relatives, this field was created and
00459      * is set to the result of that call.
00460      */
00461     unsigned d_is_fnmatch : 1;
00462 
00463     /* should we force a charset on any outgoing parameterless content-type?
00464      * if so, which charset?
00465      */
00466 #define ADD_DEFAULT_CHARSET_OFF   (0)
00467 #define ADD_DEFAULT_CHARSET_ON    (1)
00468 #define ADD_DEFAULT_CHARSET_UNSET (2)
00469     unsigned add_default_charset : 2;
00470     const char *add_default_charset_name;
00471 
00472     /* System Resource Control */
00473 #ifdef RLIMIT_CPU
00474     struct rlimit *limit_cpu;
00475 #endif
00476 #if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS)
00477     struct rlimit *limit_mem;
00478 #endif
00479 #ifdef RLIMIT_NPROC
00480     struct rlimit *limit_nproc;
00481 #endif
00482     apr_off_t limit_req_body;      /* limit on bytes in request msg body */
00483     long limit_xml_body;           /* limit on bytes in XML request msg body */
00484 
00485     /* logging options */
00486 
00487     server_signature_e server_signature;
00488 
00489     int loglevel;
00490     
00491     /* Access control */
00492     apr_array_header_t *sec_file;
00493     regex_t *r;
00494 
00495     const char *mime_type;       /* forced with ForceType  */
00496     const char *handler;         /* forced with SetHandler */
00497     const char *output_filters;  /* forced with SetOutputFilters */
00498     const char *input_filters;   /* forced with SetInputFilters */
00499     int accept_path_info;        /* forced with AcceptPathInfo */
00500 
00501     apr_hash_t *ct_output_filters; /* added with AddOutputFilterByType */
00502 
00503     /*
00504      * What attributes/data should be included in ETag generation?
00505      */
00506     etag_components_t etag_bits;
00507     etag_components_t etag_add;
00508     etag_components_t etag_remove;
00509 
00510     /*
00511      * Run-time performance tuning
00512      */
00513 #define ENABLE_MMAP_OFF    (0)
00514 #define ENABLE_MMAP_ON     (1)
00515 #define ENABLE_MMAP_UNSET  (2)
00516     unsigned int enable_mmap : 2;  /* whether files in this dir can be mmap'ed */
00517 
00518 #define ENABLE_SENDFILE_OFF    (0)
00519 #define ENABLE_SENDFILE_ON     (1)
00520 #define ENABLE_SENDFILE_UNSET  (2)
00521     unsigned int enable_sendfile : 2;  /* files in this dir can be mmap'ed */
00522     unsigned int allow_encoded_slashes : 1; /* URLs may contain %2f w/o being
00523                                              * pitched indiscriminately */
00524 } core_dir_config;
00525 
00526 /* Per-server core configuration */
00527 
00528 typedef struct {
00529   
00530 #ifdef GPROF
00531     char *gprof_dir;
00532 #endif
00533 
00534     /* Name translations --- we want the core to be able to do *something*
00535      * so it's at least a minimally functional web server on its own (and
00536      * can be tested that way).  But let's keep it to the bare minimum:
00537      */
00538     const char *ap_document_root;
00539   
00540     /* Access control */
00541 
00542     char *access_name;
00543     apr_array_header_t *sec_dir;
00544     apr_array_header_t *sec_url;
00545 
00546     /* recursion backstopper */
00547     int redirect_limit; /* maximum number of internal redirects */
00548     int subreq_limit;   /* maximum nesting level of subrequests */
00549 } core_server_config;
00550 
00551 /* for AddOutputFiltersByType in core.c */
00552 void ap_add_output_filters_by_type(request_rec *r);
00553 
00554 /* for http_config.c */
00555 void ap_core_reorder_directories(apr_pool_t *, server_rec *);
00556 
00557 /* for mod_perl */
00558 AP_CORE_DECLARE(void) ap_add_per_dir_conf(server_rec *s, void *dir_config);
00559 AP_CORE_DECLARE(void) ap_add_per_url_conf(server_rec *s, void *url_config);
00560 AP_CORE_DECLARE(void) ap_add_file_conf(core_dir_config *conf, void *url_config);
00561 AP_CORE_DECLARE_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, void *dummy, const char *arg);
00562 
00563 #endif
00564 
00565 
00566 /* ----------------------------------------------------------------------
00567  *
00568  * Runtime status/management
00569  */
00570 
00571 typedef enum {
00572     ap_mgmt_type_string,
00573     ap_mgmt_type_long,
00574     ap_mgmt_type_hash
00575 } ap_mgmt_type_e;
00576 
00577 typedef union {
00578     const char *s_value;
00579     long i_value;
00580     apr_hash_t *h_value;
00581 } ap_mgmt_value;
00582 
00583 typedef struct {
00584     const char *description;
00585     const char *name;
00586     ap_mgmt_type_e vtype;
00587     ap_mgmt_value v;
00588 } ap_mgmt_item_t;
00589 
00590 /* Handles for core filters */
00591 extern AP_DECLARE_DATA ap_filter_rec_t *ap_subreq_core_filter_handle;
00592 extern AP_DECLARE_DATA ap_filter_rec_t *ap_core_output_filter_handle;
00593 extern AP_DECLARE_DATA ap_filter_rec_t *ap_content_length_filter_handle;
00594 extern AP_DECLARE_DATA ap_filter_rec_t *ap_net_time_filter_handle;
00595 extern AP_DECLARE_DATA ap_filter_rec_t *ap_core_input_filter_handle;
00596 
00597 /**
00598  * This hook provdes a way for modules to provide metrics/statistics about
00599  * their operational status.
00600  *
00601  * @param p A pool to use to create entries in the hash table
00602  * @param val The name of the parameter(s) that is wanted. This is
00603  *            tree-structured would be in the form ('*' is all the tree,
00604  *            'module.*' all of the module , 'module.foo.*', or
00605  *            'module.foo.bar' )
00606  * @param ht The hash table to store the results. Keys are item names, and
00607  *           the values point to ap_mgmt_item_t structures.
00608  * @ingroup hooks
00609  */
00610 AP_DECLARE_HOOK(int, get_mgmt_items,
00611                 (apr_pool_t *p, const char * val, apr_hash_t *ht))
00612 
00613 /* ---------------------------------------------------------------------- */
00614 
00615 /* ----------------------------------------------------------------------
00616  *
00617  * I/O logging with mod_logio
00618  */
00619 
00620 APR_DECLARE_OPTIONAL_FN(void, ap_logio_add_bytes_out,
00621                         (conn_rec *c, apr_off_t bytes));
00622 
00623 /* ---------------------------------------------------------------------- */
00624 
00625 #ifdef __cplusplus
00626 }
00627 #endif
00628 
00629 #endif  /* !APACHE_HTTP_CORE_H */