The core ensures that the right information is available to the modules at the right time by matching requests to the appropriate virtual server and directory information before invoking the various functions in the modules. This, and other information, is packaged in a request_rec structure, defined in httpd.h:
struct request_rec { ap_pool *pool; conn_rec *connection; server_rec *server; request_rec *next; /* If we wind up getting redirected, * pointer to the request we redirected to. */ request_rec *prev; /* If this is an internal redirect, * pointer to where we redirected *from*. */ request_rec *main; /* If this is a subrequest (see request.h), * pointer back to the main request. */ /* Info about the request itself... we begin with stuff that only * protocol.c should ever touch... */ char *the_request; /* First line of request, so we can log it */ int assbackwards; /* HTTP/0.9, "simple" request */ int proxyreq; /* A proxy request (calculated during * post_read_request or translate_name) */ int header_only; /* HEAD request, as opposed to GET */ char *protocol; /* Protocol, as given to us, or HTTP/0.9 */ int proto_num; /* Number version of protocol; 1.1 = 1001 */ const char *hostname; /* Host, as set by full URI or Host: */ time_t request_time; /* When the request started */ char *status_line; /* Status line, if set by script */ int status; /* In any case */ /* Request method, two ways; also, protocol, etc. Outside of protocol.c, * look, but don't touch. */ char *method; /* GET, HEAD, POST, etc. */ int method_number; /* M_GET, M_POST, etc. */ /* allowed is a bitvector of the allowed methods. A handler must ensure that the request method is one that it is capable of handling. Generally modules should DECLINE any request methods they do not handle. Prior to aborting the handler like this, the handler should set r->allowed to the list of methods that it is willing to handle. This bitvector is used to construct the "Allow:" header required for OPTIONS requests, and METHOD_NOT_ALLOWED and NOT_IMPLEMENTED status codes. Since the default_handler deals with OPTIONS, all modules can usually decline to deal with OPTIONS. TRACE is always allowed; modules don't need to set it explicitly. Since the default_handler will always handle a GET, a module which does *not* implement GET should probably return METHOD_NOT_ALLOWED. Unfortunately, this means that a Script GET handler can't be installed by mod_actions. */ int allowed; /* Allowed methods - for 405, OPTIONS, etc. */ int sent_bodyct; /* Byte count in stream is for body */ long bytes_sent; /* Body byte count, for easy access */ time_t mtime; /* Time the resource was last modified */ /* HTTP/1.1 connection-level features */ int chunked; /* Sending chunked transfer-coding */ int byterange; /* Number of byte ranges */ char *boundary; /* Multipart/byteranges boundary */ const char *range; /* The Range: header */ long clength; /* The "real" content length */ long remaining; /* Bytes left to read */ long read_length; /* Bytes that have been read */ int read_body; /* How the request body should be read */ int read_chunked; /* Reading chunked transfer-coding */ /* MIME header environments, in and out. Also, an array containing * environment variables to be passed to subprocesses, so people can * write modules to add to that environment. * * The difference between headers_out and err_headers_out is that the * latter are printed even on error and persist across internal redirects * (so the headers printed for ErrorDocument handlers will have them). * * The 'notes' table is for notes from one module to another, with no * other set purpose in mind... */ table *headers_in; table *headers_out; table *err_headers_out; table *subprocess_env; table *notes; /* content_type, handler, content_encoding, content_language, and all * content_languages MUST be lowercased strings. They may be pointers * to static strings; they should not be modified in place. */ char *content_type; /* Break these out --- we dispatch on 'em */ char *handler; /* What we *really* dispatch on */ char *content_encoding; char *content_language; array_header *content_languages; /* Array of (char*) */ int no_cache; int no_local_copy; /* What object is being requested (either directly, or via include * or content-negotiation mapping). */ char *unparsed_uri; /* The URI without any parsing performed */ char *uri; /* The path portion of the URI */ char *filename; char *path_info; char *args; /* QUERY_ARGS, if any */ struct stat finfo; /* ST_MODE set to zero if no such file */ uri_components parsed_uri; /* Components of URI, dismantled */ /* Various other config info, which may change with .htaccess files. * These are config vectors, with one void* pointer for each module * (the thing pointed to being the module's business). */ void *per_dir_config; /* Options set in config files, etc. */ void *request_config; /* Notes on *this* request */ /* * A linked list of the configuration directives in the .htaccess files * accessed by this request. * N.B. Always add to the head of the list, _never_ to the end. * That way, a subrequest's list can (temporarily) point to a parent's * list. */ const struct htaccess_result *htaccess; };
Copyright © 2003 O'Reilly & Associates. All rights reserved.