1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17/** 18 * @file http_core.h 19 * @brief CORE HTTP Daemon 20 * 21 * @defgroup APACHE_CORE_HTTPD Core HTTP Daemon 22 * @ingroup APACHE_CORE 23 * @{ 24 */ 25 26#ifndef APACHE_HTTP_CORE_H 27#define APACHE_HTTP_CORE_H 28 29#include "apr.h" 30#include "apr_hash.h" 31#include "apr_optional.h" 32#include "util_filter.h" 33 34#if APR_HAVE_STRUCT_RLIMIT 35#include <sys/time.h> 36#include <sys/resource.h> 37#endif 38 39 40#ifdef __cplusplus 41extern "C" { 42#endif 43 44/* **************************************************************** 45 * 46 * The most basic server code is encapsulated in a single module 47 * known as the core, which is just *barely* functional enough to 48 * serve documents, though not terribly well. 49 * 50 * Largely for NCSA back-compatibility reasons, the core needs to 51 * make pieces of its config structures available to other modules. 52 * The accessors are declared here, along with the interpretation 53 * of one of them (allow_options). 54 */ 55 56/** 57 * @defgroup APACHE_CORE_HTTPD_ACESSORS Acessors 58 * 59 * @brief File/Directory Accessor directives 60 * 61 * @{ 62 */ 63 64/** No directives */ 65#define OPT_NONE 0 66/** Indexes directive */ 67#define OPT_INDEXES 1 68/** SSI is enabled without exec= permission */ 69#define OPT_INCLUDES 2 70/** FollowSymLinks directive */ 71#define OPT_SYM_LINKS 4 72/** ExecCGI directive */ 73#define OPT_EXECCGI 8 74/** directive unset */ 75#define OPT_UNSET 16 76/** IncludesNOEXEC directive */ 77#define OPT_INCNOEXEC 32 78/** SymLinksIfOwnerMatch directive */ 79#define OPT_SYM_OWNER 64 80/** MultiViews directive */ 81#define OPT_MULTI 128 82/** All directives */ 83#define OPT_ALL (OPT_INDEXES|OPT_INCLUDES|OPT_INCNOEXEC|OPT_SYM_LINKS|OPT_EXECCGI) 84/** @} */ 85 86#ifdef CORE_PRIVATE 87/* For internal use only - since 2.2.12, the OPT_INCNOEXEC bit is 88 * internally replaced by OPT_INC_WITH_EXEC. The internal semantics 89 * of the two SSI-related bits are hence: 90 * 91 * OPT_INCLUDES => "enable SSI, without exec= permission" 92 * OPT_INC_WITH_EXEC => "iff OPT_INCLUDES is set, also enable exec=" 93 * 94 * The set of options exposed via ap_allow_options() retains the 95 * semantics of OPT_INCNOEXEC by flipping the bit. */ 96#define OPT_INC_WITH_EXEC OPT_INCNOEXEC 97#endif 98 99/** 100 * @defgroup get_remote_host Remote Host Resolution 101 * @ingroup APACHE_CORE_HTTPD 102 * @{ 103 */ 104/** REMOTE_HOST returns the hostname, or NULL if the hostname 105 * lookup fails. It will force a DNS lookup according to the 106 * HostnameLookups setting. 107 */ 108#define REMOTE_HOST (0) 109 110/** REMOTE_NAME returns the hostname, or the dotted quad if the 111 * hostname lookup fails. It will force a DNS lookup according 112 * to the HostnameLookups setting. 113 */ 114#define REMOTE_NAME (1) 115 116/** REMOTE_NOLOOKUP is like REMOTE_NAME except that a DNS lookup is 117 * never forced. 118 */ 119#define REMOTE_NOLOOKUP (2) 120 121/** REMOTE_DOUBLE_REV will always force a DNS lookup, and also force 122 * a double reverse lookup, regardless of the HostnameLookups 123 * setting. The result is the (double reverse checked) hostname, 124 * or NULL if any of the lookups fail. 125 */ 126#define REMOTE_DOUBLE_REV (3) 127 128/** @} // get_remote_host */ 129 130/** all of the requirements must be met */ 131#define SATISFY_ALL 0 132/** any of the requirements must be met */ 133#define SATISFY_ANY 1 134/** There are no applicable satisfy lines */ 135#define SATISFY_NOSPEC 2 136 137/** Make sure we don't write less than 8000 bytes at any one time. 138 */ 139#define AP_MIN_BYTES_TO_WRITE 8000 140 141/** default maximum of internal redirects */ 142# define AP_DEFAULT_MAX_INTERNAL_REDIRECTS 10 143 144/** default maximum subrequest nesting level */ 145# define AP_DEFAULT_MAX_SUBREQ_DEPTH 10 146 147/** 148 * Retrieve the value of Options for this request 149 * @param r The current request 150 * @return the Options bitmask 151 */ 152AP_DECLARE(int) ap_allow_options(request_rec *r); 153 154/** 155 * Retrieve the value of the AllowOverride for this request 156 * @param r The current request 157 * @return the overrides bitmask 158 */ 159AP_DECLARE(int) ap_allow_overrides(request_rec *r); 160 161/** 162 * Retrieve the value of the DefaultType directive, or text/plain if not set 163 * @param r The current request 164 * @return The default type 165 */ 166AP_DECLARE(const char *) ap_default_type(request_rec *r); 167 168/** 169 * Retrieve the document root for this server 170 * @param r The current request 171 * @warning Don't use this! If your request went through a Userdir, or 172 * something like that, it'll screw you. But it's back-compatible... 173 * @return The document root 174 */ 175AP_DECLARE(const char *) ap_document_root(request_rec *r); 176 177/** 178 * Lookup the remote client's DNS name or IP address 179 * @ingroup get_remote_host 180 * @param conn The current connection 181 * @param dir_config The directory config vector from the request 182 * @param type The type of lookup to perform. One of: 183 * <pre> 184 * REMOTE_HOST returns the hostname, or NULL if the hostname 185 * lookup fails. It will force a DNS lookup according to the 186 * HostnameLookups setting. 187 * REMOTE_NAME returns the hostname, or the dotted quad if the 188 * hostname lookup fails. It will force a DNS lookup according 189 * to the HostnameLookups setting. 190 * REMOTE_NOLOOKUP is like REMOTE_NAME except that a DNS lookup is 191 * never forced. 192 * REMOTE_DOUBLE_REV will always force a DNS lookup, and also force 193 * a double reverse lookup, regardless of the HostnameLookups 194 * setting. The result is the (double reverse checked) 195 * hostname, or NULL if any of the lookups fail. 196 * </pre> 197 * @param str_is_ip unless NULL is passed, this will be set to non-zero on output when an IP address 198 * string is returned 199 * @return The remote hostname 200 */ 201AP_DECLARE(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config, int type, int *str_is_ip); 202 203/** 204 * Retrieve the login name of the remote user. Undef if it could not be 205 * determined 206 * @param r The current request 207 * @return The user logged in to the client machine 208 */ 209AP_DECLARE(const char *) ap_get_remote_logname(request_rec *r); 210 211/* Used for constructing self-referencing URLs, and things like SERVER_PORT, 212 * and SERVER_NAME. 213 */ 214/** 215 * build a fully qualified URL from the uri and information in the request rec 216 * @param p The pool to allocate the URL from 217 * @param uri The path to the requested file 218 * @param r The current request 219 * @return A fully qualified URL 220 */ 221AP_DECLARE(char *) ap_construct_url(apr_pool_t *p, const char *uri, request_rec *r); 222 223/** 224 * Get the current server name from the request 225 * @param r The current request 226 * @return the server name 227 */ 228AP_DECLARE(const char *) ap_get_server_name(request_rec *r); 229 230/** 231 * Get the current server port 232 * @param r The current request 233 * @return The server's port 234 */ 235AP_DECLARE(apr_port_t) ap_get_server_port(const request_rec *r); 236 237/** 238 * Return the limit on bytes in request msg body 239 * @param r The current request 240 * @return the maximum number of bytes in the request msg body 241 */ 242AP_DECLARE(apr_off_t) ap_get_limit_req_body(const request_rec *r); 243 244/** 245 * Return the limit on bytes in XML request msg body 246 * @param r The current request 247 * @return the maximum number of bytes in XML request msg body 248 */ 249AP_DECLARE(size_t) ap_get_limit_xml_body(const request_rec *r); 250 251/** 252 * Install a custom response handler for a given status 253 * @param r The current request 254 * @param status The status for which the custom response should be used 255 * @param string The custom response. This can be a static string, a file 256 * or a URL 257 */ 258AP_DECLARE(void) ap_custom_response(request_rec *r, int status, const char *string); 259 260/** 261 * Check if the current request is beyond the configured max. number of redirects or subrequests 262 * @param r The current request 263 * @return true (is exceeded) or false 264 */ 265AP_DECLARE(int) ap_is_recursion_limit_exceeded(const request_rec *r); 266 267/** 268 * Check for a definition from the server command line 269 * @param name The define to check for 270 * @return 1 if defined, 0 otherwise 271 */ 272AP_DECLARE(int) ap_exists_config_define(const char *name); 273/* FIXME! See STATUS about how */ 274AP_DECLARE_NONSTD(int) ap_core_translate(request_rec *r); 275 276/* Authentication stuff. This is one of the places where compatibility 277 * with the old config files *really* hurts; they don't discriminate at 278 * all between different authentication schemes, meaning that we need 279 * to maintain common state for all of them in the core, and make it 280 * available to the other modules through interfaces. 281 */ 282 283/** @see require_line */ 284typedef struct require_line require_line; 285 286/** 287 * @brief A structure to keep track of authorization requirements 288*/ 289struct require_line { 290 /** Where the require line is in the config file. */ 291 apr_int64_t method_mask; 292 /** The complete string from the command line */ 293 char *requirement; 294}; 295 296/** 297 * Return the type of authorization required for this request 298 * @param r The current request 299 * @return The authorization required 300 */ 301AP_DECLARE(const char *) ap_auth_type(request_rec *r); 302 303/** 304 * Return the current Authorization realm 305 * @param r The current request 306 * @return The current authorization realm 307 */ 308AP_DECLARE(const char *) ap_auth_name(request_rec *r); 309 310/** 311 * How the requires lines must be met. 312 * @param r The current request 313 * @return How the requirements must be met. One of: 314 * <pre> 315 * SATISFY_ANY -- any of the requirements must be met. 316 * SATISFY_ALL -- all of the requirements must be met. 317 * SATISFY_NOSPEC -- There are no applicable satisfy lines 318 * </pre> 319 */ 320AP_DECLARE(int) ap_satisfies(request_rec *r); 321 322/** 323 * Retrieve information about all of the requires directives for this request 324 * @param r The current request 325 * @return An array of all requires directives for this request 326 */ 327AP_DECLARE(const apr_array_header_t *) ap_requires(request_rec *r); 328 329#ifdef CORE_PRIVATE 330 331/** 332 * Core is also unlike other modules in being implemented in more than 333 * one file... so, data structures are declared here, even though most of 334 * the code that cares really is in http_core.c. Also, another accessor. 335 */ 336AP_DECLARE_DATA extern module core_module; 337 338/** 339 * @brief Per-request configuration 340*/ 341typedef struct { 342 /** bucket brigade used by getline for look-ahead and 343 * ap_get_client_block for holding left-over request body */ 344 struct apr_bucket_brigade *bb; 345 346 /** an array of per-request working data elements, accessed 347 * by ID using ap_get_request_note() 348 * (Use ap_register_request_note() during initialization 349 * to add elements) 350 */ 351 void **notes; 352 353 /** There is a script processor installed on the output filter chain, 354 * so it needs the default_handler to deliver a (script) file into 355 * the chain so it can process it. Normally, default_handler only 356 * serves files on a GET request (assuming the file is actual content), 357 * since other methods are not content-retrieval. This flag overrides 358 * that behavior, stating that the "content" is actually a script and 359 * won't actually be delivered as the response for the non-GET method. 360 */ 361 int deliver_script; 362 363 /** Custom response strings registered via ap_custom_response(), 364 * or NULL; check per-dir config if nothing found here 365 */ 366 char **response_code_strings; /* from ap_custom_response(), not from 367 * ErrorDocument 368 */ 369 /** Should addition of charset= be suppressed for this request? 370 */ 371 int suppress_charset; 372} core_request_config; 373 374/* Standard entries that are guaranteed to be accessible via 375 * ap_get_request_note() for each request (additional entries 376 * can be added with ap_register_request_note()) 377 */ 378#define AP_NOTE_DIRECTORY_WALK 0 379#define AP_NOTE_LOCATION_WALK 1 380#define AP_NOTE_FILE_WALK 2 381#define AP_NUM_STD_NOTES 3 382 383/** 384 * Reserve an element in the core_request_config->notes array 385 * for some application-specific data 386 * @return An integer key that can be passed to ap_get_request_note() 387 * during request processing to access this element for the 388 * current request. 389 */ 390AP_DECLARE(apr_size_t) ap_register_request_note(void); 391 392/** 393 * Retrieve a pointer to an element in the core_request_config->notes array 394 * @param r The request 395 * @param note_num A key for the element: either a value obtained from 396 * ap_register_request_note() or one of the predefined AP_NOTE_* 397 * values. 398 * @return NULL if the note_num is invalid, otherwise a pointer to the 399 * requested note element. 400 * @remark At the start of a request, each note element is NULL. The 401 * handle provided by ap_get_request_note() is a pointer-to-pointer 402 * so that the caller can point the element to some app-specific 403 * data structure. The caller should guarantee that any such 404 * structure will last as long as the request itself. 405 */ 406AP_DECLARE(void **) ap_get_request_note(request_rec *r, apr_size_t note_num); 407 408 409typedef unsigned char allow_options_t; 410typedef unsigned char overrides_t; 411 412/* 413 * Bits of info that go into making an ETag for a file 414 * document. Why a long? Because char historically 415 * proved too short for Options, and int can be different 416 * sizes on different platforms. 417 */ 418typedef unsigned long etag_components_t; 419 420#define ETAG_UNSET 0 421#define ETAG_NONE (1 << 0) 422#define ETAG_MTIME (1 << 1) 423#define ETAG_INODE (1 << 2) 424#define ETAG_SIZE (1 << 3) 425#define ETAG_BACKWARD (ETAG_MTIME | ETAG_INODE | ETAG_SIZE) 426#define ETAG_ALL (ETAG_MTIME | ETAG_INODE | ETAG_SIZE) 427 428/** 429 * @brief Server Signature Enumeration 430 */ 431typedef enum { 432 srv_sig_unset, 433 srv_sig_off, 434 srv_sig_on, 435 srv_sig_withmail 436} server_signature_e; 437 438/** 439 * @brief Per-directory configuration 440 */ 441typedef struct { 442 /** path of the directory/regex/etc. see also d_is_fnmatch/absolute below */ 443 char *d; 444 /** the number of slashes in d */ 445 unsigned d_components; 446 447 /** If (opts & OPT_UNSET) then no absolute assignment to options has 448 * been made. 449 * invariant: (opts_add & opts_remove) == 0 450 * Which said another way means that the last relative (options + or -) 451 * assignment made to each bit is recorded in exactly one of opts_add 452 * or opts_remove. 453 */ 454 allow_options_t opts; 455 allow_options_t opts_add; 456 allow_options_t opts_remove; 457 overrides_t override; 458 allow_options_t override_opts; 459 460 /* MIME typing --- the core doesn't do anything at all with this, 461 * but it does know what to slap on a request for a document which 462 * goes untyped by other mechanisms before it slips out the door... 463 */ 464 465 char *ap_default_type; 466 467 /* Authentication stuff. Groan... */ 468 469 int *satisfy; /* for every method one */ 470 char *ap_auth_type; 471 char *ap_auth_name; 472 apr_array_header_t *ap_requires; 473 474 /* Custom response config. These can contain text or a URL to redirect to. 475 * if response_code_strings is NULL then there are none in the config, 476 * if it's not null then it's allocated to sizeof(char*)*RESPONSE_CODES. 477 * This lets us do quick merges in merge_core_dir_configs(). 478 */ 479 480 char **response_code_strings; /* from ErrorDocument, not from 481 * ap_custom_response() */ 482 483 /* Hostname resolution etc */ 484#define HOSTNAME_LOOKUP_OFF 0 485#define HOSTNAME_LOOKUP_ON 1 486#define HOSTNAME_LOOKUP_DOUBLE 2 487#define HOSTNAME_LOOKUP_UNSET 3 488 unsigned int hostname_lookups : 4; 489 490 signed int content_md5 : 2; /* calculate Content-MD5? */ 491 492#define USE_CANONICAL_NAME_OFF (0) 493#define USE_CANONICAL_NAME_ON (1) 494#define USE_CANONICAL_NAME_DNS (2) 495#define USE_CANONICAL_NAME_UNSET (3) 496 unsigned use_canonical_name : 2; 497 498 /* since is_fnmatch(conf->d) was being called so frequently in 499 * directory_walk() and its relatives, this field was created and 500 * is set to the result of that call. 501 */ 502 unsigned d_is_fnmatch : 1; 503 504 /* should we force a charset on any outgoing parameterless content-type? 505 * if so, which charset? 506 */ 507#define ADD_DEFAULT_CHARSET_OFF (0) 508#define ADD_DEFAULT_CHARSET_ON (1) 509#define ADD_DEFAULT_CHARSET_UNSET (2) 510 unsigned add_default_charset : 2; 511 const char *add_default_charset_name; 512 513 /* System Resource Control */ 514#ifdef RLIMIT_CPU 515 struct rlimit *limit_cpu; 516#endif 517#if defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS) 518 struct rlimit *limit_mem; 519#endif 520#ifdef RLIMIT_NPROC 521 struct rlimit *limit_nproc; 522#endif 523 apr_off_t limit_req_body; /* limit on bytes in request msg body */ 524 long limit_xml_body; /* limit on bytes in XML request msg body */ 525 526 /* logging options */ 527 528 server_signature_e server_signature; 529 530 int loglevel; 531 532 /* Access control */ 533 apr_array_header_t *sec_file; 534 ap_regex_t *r; 535 536 const char *mime_type; /* forced with ForceType */ 537 const char *handler; /* forced with SetHandler */ 538 const char *output_filters; /* forced with SetOutputFilters */ 539 const char *input_filters; /* forced with SetInputFilters */ 540 int accept_path_info; /* forced with AcceptPathInfo */ 541 542 apr_hash_t *ct_output_filters; /* added with AddOutputFilterByType */ 543 544 /* 545 * What attributes/data should be included in ETag generation? 546 */ 547 etag_components_t etag_bits; 548 etag_components_t etag_add; 549 etag_components_t etag_remove; 550 551 /* 552 * Run-time performance tuning 553 */ 554#define ENABLE_MMAP_OFF (0) 555#define ENABLE_MMAP_ON (1) 556#define ENABLE_MMAP_UNSET (2) 557 unsigned int enable_mmap : 2; /* whether files in this dir can be mmap'ed */ 558 559#define ENABLE_SENDFILE_OFF (0) 560#define ENABLE_SENDFILE_ON (1) 561#define ENABLE_SENDFILE_UNSET (2) 562 unsigned int enable_sendfile : 2; /* files in this dir can be mmap'ed */ 563 unsigned int allow_encoded_slashes : 1; /* URLs may contain %2f w/o being 564 * pitched indiscriminately */ 565 566#define USE_CANONICAL_PHYS_PORT_OFF (0) 567#define USE_CANONICAL_PHYS_PORT_ON (1) 568#define USE_CANONICAL_PHYS_PORT_UNSET (2) 569 unsigned use_canonical_phys_port : 2; 570 571 572 unsigned int decode_encoded_slashes : 1; /* whether to decode encoded slashes in URLs */ 573 574#define AP_MAXRANGES_UNSET -1 575#define AP_MAXRANGES_DEFAULT -2 576#define AP_MAXRANGES_UNLIMITED -3 577#define AP_MAXRANGES_NORANGES 0 578 /** Number of Ranges before returning HTTP_OK. **/ 579 int max_ranges; 580 581} core_dir_config; 582 583/* Per-server core configuration */ 584 585typedef struct { 586 587#ifdef GPROF 588 char *gprof_dir; 589#endif 590 591 /* Name translations --- we want the core to be able to do *something* 592 * so it's at least a minimally functional web server on its own (and 593 * can be tested that way). But let's keep it to the bare minimum: 594 */ 595 const char *ap_document_root; 596 597 /* Access control */ 598 599 char *access_name; 600 apr_array_header_t *sec_dir; 601 apr_array_header_t *sec_url; 602 603 /* recursion backstopper */ 604 int redirect_limit; /* maximum number of internal redirects */ 605 int subreq_limit; /* maximum nesting level of subrequests */ 606 607 const char *protocol; 608 apr_table_t *accf_map; 609 610 /* TRACE control */ 611#define AP_TRACE_UNSET -1 612#define AP_TRACE_DISABLE 0 613#define AP_TRACE_ENABLE 1 614#define AP_TRACE_EXTENDED 2 615 int trace_enable; 616 617} core_server_config; 618 619/* for AddOutputFiltersByType in core.c */ 620void ap_add_output_filters_by_type(request_rec *r); 621 622/* for http_config.c */ 623void ap_core_reorder_directories(apr_pool_t *, server_rec *); 624 625/* for mod_perl */ 626AP_CORE_DECLARE(void) ap_add_per_dir_conf(server_rec *s, void *dir_config); 627AP_CORE_DECLARE(void) ap_add_per_url_conf(server_rec *s, void *url_config); 628AP_CORE_DECLARE(void) ap_add_file_conf(core_dir_config *conf, void *url_config); 629AP_CORE_DECLARE_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, void *dummy, const char *arg); 630 631/* Core filters; not exported. */ 632int ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, 633 ap_input_mode_t mode, apr_read_type_e block, 634 apr_off_t readbytes); 635apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *b); 636 637#endif /* CORE_PRIVATE */ 638 639AP_DECLARE(const char*) ap_get_server_protocol(server_rec* s); 640AP_DECLARE(void) ap_set_server_protocol(server_rec* s, const char* proto); 641 642/* ---------------------------------------------------------------------- 643 * 644 * Runtime status/management 645 */ 646 647typedef enum { 648 ap_mgmt_type_string, 649 ap_mgmt_type_long, 650 ap_mgmt_type_hash 651} ap_mgmt_type_e; 652 653typedef union { 654 const char *s_value; 655 long i_value; 656 apr_hash_t *h_value; 657} ap_mgmt_value; 658 659typedef struct { 660 const char *description; 661 const char *name; 662 ap_mgmt_type_e vtype; 663 ap_mgmt_value v; 664} ap_mgmt_item_t; 665 666/* Handles for core filters */ 667extern AP_DECLARE_DATA ap_filter_rec_t *ap_subreq_core_filter_handle; 668extern AP_DECLARE_DATA ap_filter_rec_t *ap_core_output_filter_handle; 669extern AP_DECLARE_DATA ap_filter_rec_t *ap_content_length_filter_handle; 670extern AP_DECLARE_DATA ap_filter_rec_t *ap_core_input_filter_handle; 671 672/** 673 * This hook provdes a way for modules to provide metrics/statistics about 674 * their operational status. 675 * 676 * @param p A pool to use to create entries in the hash table 677 * @param val The name of the parameter(s) that is wanted. This is 678 * tree-structured would be in the form ('*' is all the tree, 679 * 'module.*' all of the module , 'module.foo.*', or 680 * 'module.foo.bar' ) 681 * @param ht The hash table to store the results. Keys are item names, and 682 * the values point to ap_mgmt_item_t structures. 683 * @ingroup hooks 684 */ 685AP_DECLARE_HOOK(int, get_mgmt_items, 686 (apr_pool_t *p, const char * val, apr_hash_t *ht)) 687 688/* ---------------------------------------------------------------------- */ 689 690/* ---------------------------------------------------------------------- 691 * 692 * I/O logging with mod_logio 693 */ 694 695APR_DECLARE_OPTIONAL_FN(void, ap_logio_add_bytes_out, 696 (conn_rec *c, apr_off_t bytes)); 697 698APR_DECLARE_OPTIONAL_FN(void, ap_logio_add_bytes_in, 699 (conn_rec *c, apr_off_t bytes)); 700 701/* ---------------------------------------------------------------------- 702 * 703 * ident lookups with mod_ident 704 */ 705 706APR_DECLARE_OPTIONAL_FN(const char *, ap_ident_lookup, 707 (request_rec *r)); 708 709/* ---------------------------------------------------------------------- */ 710 711#ifdef __cplusplus 712} 713#endif 714 715#endif /* !APACHE_HTTP_CORE_H */ 716/** @} */ 717