http_request.c revision 44c46ef733836b32585d135d2d90856e7cfd9929
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse/* ====================================================================
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Copyright (c) 1995-1999 The Apache Group. All rights reserved.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Redistribution and use in source and binary forms, with or without
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * modification, are permitted provided that the following conditions
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * are met:
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * 1. Redistributions of source code must retain the above copyright
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * notice, this list of conditions and the following disclaimer.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * 2. Redistributions in binary form must reproduce the above copyright
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * notice, this list of conditions and the following disclaimer in
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * the documentation and/or other materials provided with the
33bdcae1f7a1a65e351dda2a766a0cf28b1e695dnd * distribution.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * 3. All advertising materials mentioning features or use of this
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * software must display the following acknowledgment:
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * "This product includes software developed by the Apache Group
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * for use in the Apache HTTP server project (http://www.apache.org/)."
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * 4. The names "Apache Server" and "Apache Group" must not be used to
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * endorse or promote products derived from this software without
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * prior written permission. For written permission, please contact
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * apache@apache.org.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * 5. Products derived from this software may not be called "Apache"
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * nor may "Apache" appear in their names without prior written
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * permission of the Apache Group.
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * 6. Redistributions of any form whatsoever must retain the following
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * acknowledgment:
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * "This product includes software developed by the Apache Group
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * for use in the Apache HTTP server project (http://www.apache.org/)."
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * OF THE POSSIBILITY OF SUCH DAMAGE.
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * ====================================================================
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * This software consists of voluntary contributions made by many
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * individuals on behalf of the Apache Group and was originally based
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * on public domain software written at the National Center for
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * Supercomputing Applications, University of Illinois, Urbana-Champaign.
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * For more information on the Apache Group and the Apache HTTP server
d86ef5503dcbc38e87c0e03cd3e1f16458cb6323rse * project, please see <http://www.apache.org/>.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * http_request.c: functions to get and process requests
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Rob McCool 3/21/93
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Thoroughly revamped by rst for Apache. NB this file reads
e18e68b42830409bf48de0df9eed3fe363664aa7aaron * best from the bottom up.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrseIMPLEMENT_HOOK_RUN_FIRST(int,translate_name,(request_rec *r),(r),DECLINED)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrseIMPLEMENT_HOOK_RUN_FIRST(int,check_user_id,(request_rec *r),(r),DECLINED)
05413593151a238718198cc04ca849b2426be106rseIMPLEMENT_HOOK_RUN_ALL(int,fixups,(request_rec *r),(r),OK,DECLINED)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrseIMPLEMENT_HOOK_RUN_FIRST(int,type_checker,(request_rec *r),(r),DECLINED)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrseIMPLEMENT_HOOK_RUN_ALL(int,access_checker,(request_rec *r),(r),OK,DECLINED)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrseIMPLEMENT_HOOK_RUN_FIRST(int,auth_checker,(request_rec *r),(r),DECLINED)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse/*****************************************************************
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse * Getting and checking directory configuration. Also checks the
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * FollowSymlinks and FollowSymOwner stuff, since this is really the
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * only place that can happen (barring a new mid_dir_walk callout).
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * We can't do it as an access_checker module function which gets
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * called with the final per_dir_config, since we could have a directory
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * with FollowSymLinks disabled, which contains a symlink to another
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * with a .htaccess file which turns FollowSymLinks back on --- and
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * access in such a case must be denied. So, whatever it is that
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * checks FollowSymLinks needs to know the state of the options as
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * they change, all the way down.
421d9002d73db52972bcca8f4497fe5d603b6b8eaaron * We don't want people able to serve up pipes, or unix sockets, or other
421d9002d73db52972bcca8f4497fe5d603b6b8eaaron * scary things. Note that symlink tests are performed later.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse "object is not a file, directory or symlink: %s",
421d9002d73db52972bcca8f4497fe5d603b6b8eaaron /* OS/2 doesn't have symlinks */
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse * Strip trailing '/', if any, off what we're checking; trailing slashes
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * make some systems follow symlinks to directories even in lstat().
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse * After we've done the lstat, put it back. Also, don't bother checking
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * '/' at all...
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse * Note that we don't have to worry about multiple slashes here because of
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse * no2slash() below...
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Note that we don't reject accesses to nonexistent files (multiviews or
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * the like may cons up a way to run the transaction anyway)...
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse /* OK, it's a symlink. May still be OK with OPT_SYM_OWNER */
87a1c79b7b37702a254920ca5214fb282a4fb085dougm return (fi.st_uid == lfi.st_uid) ? OK : HTTP_FORBIDDEN;
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse/* Dealing with the file system to get PATH_INFO
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse /* assume path_info already set */
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse /* If the directory is x:\, then we don't want to strip
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * the trailing slash since x: is not a valid directory.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse if (strlen(path) == 3 && path[1] == ':' && path[2] == '/')
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse /* If UNC name == //machine/share/, do not
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * advance over the trailing slash. Any other
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * UNC name is OK to strip the slash.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse if (strlen(path) > 2 && path[0] == '/' && path[1] == '/' &&
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse /* Advance over trailing slashes ... NOT part of filename
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * if file is not a UNC name (Win32 only).
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse /* See if the pathname ending here exists... */
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse /* We must not stat() filenames that may cause os-specific system
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * problems, such as "/file/aux" on DOS-abused filesystems.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * So pretend that they do not exist by returning an ENOENT error.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * This will force us to drop that part of the path and keep
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * looking back for a "real" file that exists, while still allowing
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * the "invalid" path parts within the PATH_INFO.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Aha! Found something. If it was a directory, we will search
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * contents of that directory for a multi_match, so the PATH_INFO
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * argument starts with the component after that.
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse /* must set this to zero, some stat()s may have corrupted it
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * even if they returned an error.
184f5da95d14895f7f33c90b8b8f70653afb0d92wrowe#if defined(EACCES)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse#error comments at this line in the source for a workaround.
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * If ENOENT || ENOTDIR is not defined in one of the your OS's
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * include files, Apache does not know how to check to see why the
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * stat() of the index file failed; there are cases where it can fail
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * even though the file exists. This means that it is possible for
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * someone to get a directory listing of a directory even though
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * there is an index (eg. index.html) file in it. If you do not have
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * a problem with this, delete the above #error lines and start the
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * compile again. If you need to do this, please submit a bug report
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * from http://www.apache.org/bug_report.html letting us know that
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * you needed to do this. Please be sure to include the operating
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * system you are using.
a0e0d20b666cfc453ac76506079eb50e03997eefdougm#endif /* ENOENT && ENOTDIR */
a0e0d20b666cfc453ac76506079eb50e03997eefdougm core_server_config *sconf = ap_get_module_config(r->server->module_config,
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * Are we dealing with a file? If not, we can (hopefuly) safely assume we
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * have a handler that doesn't require one, but for safety's sake, and so
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * we have something find_types() can get something out of, fake one. But
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * don't run through the directory entries.
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * Go down the directory hierarchy. Where we have to check for symlinks,
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * do so. Where a .htaccess file has permission to override anything,
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * try to find one. If either of these things fails, we could poke
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * around, see why, and adjust the lookup_rec accordingly --- this might
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * save us a call to get_path_info (with the attendant stat()s); however,
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * for the moment, that's not worth the trouble.
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * Fake filenames (i.e. proxy:) only match Directory sections.
22357f10585a847ebf7b084cbe1db07ba071aeb6dougm for (j = 0; j < num_sec; ++j) {
dd7c683f683624b082d430935b594df7406782c2dougm if (!ap_regexec(entry_core->r, r->filename, 0, NULL, 0))
6a26d195dfba3a91f8352cabd4547afa77675bb1aaron else if (!strncmp(r->filename, entry_dir, strlen(entry_dir)))
b40799adcfd0f0a2a465c2934585986f7bbc9bbcwrowe r->filename = ap_os_case_canonical_filename(r->pool, r->filename);
3c65aa88903de7330a07e133dfda779842fadad4wrowe r->filename = ap_os_canonical_filename(r->pool, r->filename);
b40799adcfd0f0a2a465c2934585986f7bbc9bbcwrowe ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
98f81eac9530d487f05013cda9df99755bb59689trawick * We will use test_dirname as scratch space while we build directory
98f81eac9530d487f05013cda9df99755bb59689trawick * names during the walk. Profiling shows directory_walk to be a busy
98f81eac9530d487f05013cda9df99755bb59689trawick * function so we try to avoid allocating lots of extra memory here.
98f81eac9530d487f05013cda9df99755bb59689trawick * We need 2 extra bytes, one for trailing \0 and one because
98f81eac9530d487f05013cda9df99755bb59689trawick * make_dirstr_prefix will add potentially one extra /.
98f81eac9530d487f05013cda9df99755bb59689trawick test_dirname = ap_palloc(r->pool, test_filename_len + 2);
e62985c7a1b46a5036a247f35bddac1308985758dougm /* If the name is a UNC name, then do not walk through the
8464a9c46b967001e38fe3c8afff51a649e9de51dougm * machine and share name (e.g. \\machine\share\)
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm if (num_dirs > 3 && test_filename[0] == '/' && test_filename[1] == '/')
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm /* j keeps track of which section we're on, see core_reorder_directories */
3c65aa88903de7330a07e133dfda779842fadad4wrowe * XXX: this could be made faster by only copying the next component
8464a9c46b967001e38fe3c8afff51a649e9de51dougm * rather than copying the entire thing all over.
e18e68b42830409bf48de0df9eed3fe363664aa7aaron ap_make_dirstr_prefix(test_dirname, test_filename, i);
e62985c7a1b46a5036a247f35bddac1308985758dougm * Do symlink checks first, because they are done with the
9e530d1e49062250c345bfd45810e145b4f435eddougm * permissions appropriate to the *parent* directory...
3c65aa88903de7330a07e133dfda779842fadad4wrowe if ((res = check_symlinks(test_dirname, core_dir->opts))) {
3c65aa88903de7330a07e133dfda779842fadad4wrowe ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
* from access.conf.
for (; j < num_sec; ++j) {
char *entry_dir;
void *this_conf;
if (entry_core->r
if (this_conf) {
if (overrides_here) {
if (res)
return res;
if (htaccess_conf) {
* There's two types of IS_SPECIAL sections (see http_core.c), and we've
for (; j < num_sec; ++j) {
if (entry_core->r) {
* S_ISDIR test. But if you accessed /symlink/index.html, for example,
return res;
&core_module);
char *test_location;
char *entry_url;
if (!num_url) {
return OK;
/* Location and LocationMatch differ on their behaviour w.r.t. multiple
for (j = 0; j < num_url; ++j) {
if (entry_core->r) {
if (this_conf)
return OK;
char *test_file;
++test_file;
if (num_files) {
char *entry_file;
for (j = 0; j < num_files; ++j) {
if (entry_core->r) {
if (this_conf)
return OK;
return rr;
const char *new_file,
const request_rec *r)
int res;
char *udir;
if (res) {
return rnew;
return rnew;
if (res) {
return rnew;
return rnew;
const request_rec *r)
const request_rec *r)
int res;
char *fdir;
return rnew;
if (!res) {
return rnew;
return rnew;
return rnew;
if (!res) {
if (res
return rnew;
#ifndef CHARSET_EBCDIC
return retval;
int recursive_error = 0;
(void) ap_discard_request_body(r);
const char *error_notes;
if (!reqs_arr)
int access_status;
if (access_status) {
if (!r->proxyreq) {
switch (ap_satisfies(r)) {
case SATISFY_ALL:
case SATISFY_NOSPEC:
if (ap_some_auth_required(r)) {
case SATISFY_ANY:
if (!ap_some_auth_required(r)) {
if (! (r->proxyreq
return new;
int access_status;
* A whole lot of this really ought to be shared with http_protocol.c...
return NULL;
return new;
if (r->handler)
return r->mtime;