manoj 99/03/17 09:02:13
Modified: pthreads ABOUT_APACHE INSTALL Makefile.tmpl README.configure config.layout configure pthreads/conf httpd.conf-dist httpd.conf-dist-win mime.types pthreads/htdocs/manual content-negotiation.html handler.html index.html sections.html pthreads/htdocs/manual/misc API.html FAQ.html pthreads/htdocs/manual/mod core.html directives.html mod_alias.html mod_negotiation.html mod_so.html pthreads/htdocs/manual/vhosts details.html name-based.html pthreads/src ApacheCore.def CHANGES Configure Makefile.tmpl Makefile_win32.txt Makefile_win32_debug.txt pthreads/src/ap ap_execve.c pthreads/src/helpers GuessOS PrintPath TestCompile binbuild.sh buildinfo.sh find-dbm-lib install.sh slo.sh pthreads/src/include alloc.h ap_config.h ap_ctype.h ap_mmn.h http_config.h http_request.h httpd.h pthreads/src/main alloc.c buff.c gen_test_char.c http_config.c http_core.c http_log.c http_main.c http_protocol.c http_request.c scoreboard.c util.c util_date.c util_script.c pthreads/src/modules/proxy mod_proxy.c mod_proxy.h proxy_cache.c proxy_connect.c proxy_ftp.c proxy_http.c proxy_util.c pthreads/src/modules/standard mod_cgi.c mod_include.c mod_negotiation.c mod_rewrite.c mod_rewrite.h mod_so.c mod_userdir.c pthreads/src/os/bs2000 os.h pthreads/src/os/os2 os.h util_os2.c pthreads/src/os/win32 os.h util_win32.c pthreads/src/os/win32/installer/installdll install.c install.dsp install.mak pthreads/src/os/win32/installer/installdll/test resource.h test.c test.mak test.rc pthreads/src/support ab.1 ab.c apachectl apachectl.1 apxs.pl dbmmanage.1 htpasswd.c httpd.exp suexec.c Log: Update apache-pthreads to the current state of Apache 1.3 as of around 9PM PST, Mar 16. Revision Changes Path 1.2 +17 -14 apache-apr/pthreads/ABOUT_APACHE Index: ABOUT_APACHE =================================================================== RCS file: /home/cvs/apache-apr/pthreads/ABOUT_APACHE,v retrieving revision 1.1 retrieving revision 1.2 diff -u -u -r1.1 -r1.2 --- ABOUT_APACHE 1999/01/21 23:08:29 1.1 +++ ABOUT_APACHE 1999/03/17 16:59:14 1.2 @@ -3,7 +3,7 @@ http://www.apache.org/ - September 1998 + February 1999 The Apache Project is a collaborative software development effort aimed at creating a robust, commercial-grade, featureful, and freely-available @@ -65,17 +65,20 @@ Less than a year after the group was formed, the Apache server passed NCSA's httpd as the #1 server on the Internet. +The survey by Netcraft (http://www.netcraft.com/survey/) shows that Apache +is today more widely used than all other web servers combined. + ============================================================================ -Current Apache Group in alphabetical order as of 23 September 1998: +Current Apache Group in alphabetical order as of 14 February 1999: - Brian Behlendorf Organic Online, California + Brian Behlendorf O'Reilly and Associates, California Ken Coar IBM Corporation, Research Triangle Park, NC, USA Mark J. Cox C2Net Europe, UK - Lars Eilebrecht Kreuztal, Germany + Lars Eilebrecht Cable & Wireless ECRC, Munich, Germany Ralf S. Engelschall Munich, Germany. Roy T. Fielding UC Irvine, California - Dean Gaudet Transmeta Corporation, California + Dean Gaudet Critical Path, California Rob Hartill Internet Movie DB, UK Ben Hyde Gensym, Massachusetts Jim Jagielski jaguNET ISP, Maryland @@ -85,11 +88,11 @@ Doug MacEachern Freelance Consultant, Summer Seasons, Earth Aram W. Mirzadeh Qosina Corporation, New York Sameer Parekh C2Net, California - Marc Slemko Canada Cliff Skolnick Freelance, California + Marc Slemko Canada Bill Stoddard IBM Corp., Research Triangle Park, NC Paul Sutton C2Net Europe, UK - Randy Terbush Zyzzyva ISP, Nebraska + Randy Terbush Covalent Technologies, Nebraska Dirk-Willem van Gulik Freelance Consultant, Italy Apache Emeritae (old group members now off doing other things) @@ -101,13 +104,15 @@ Other major contributors - Rob McCool (original author of the NCSA httpd), + Howard Fear (mod_include), Florent Guillaume (language negotiation), + Koen Holtman (rewrite of mod_negotiation), + Kevin Hughes (creator of all those nifty icons), + Rasmus Lerdorf (mod_info, mod_php, mod_php3), Brandon Long and Beth Frank (NCSA Server Development Team, post-1.3), + Ambarish Malpani (Beginning of the NT port), + Rob McCool (original author of the NCSA httpd 1.3), Paul Richards (convinced the group to use remote CVS after 1.0), - Kevin Hughes (creator of all those nifty icons), - Henry Spencer (author of the regex library), Garey Smiley (OS/2 port), - Howard Fear (mod_include), Florent Guillaume (language negotiation), - Ambarish Malpani (NT port). + Garey Smiley (OS/2 port), Henry Spencer (author of the regex library). Many 3rd-party modules, frequently used and recommended, are also freely-available and linked from the related projects page: @@ -233,5 +238,3 @@ ============================================================================ Roy Fielding, June 1997 - -If you are interested in other WWW history, see <http://www.webhistory.org/> 1.3 +10 -9 apache-apr/pthreads/INSTALL Index: INSTALL =================================================================== RCS file: /home/cvs/apache-apr/pthreads/INSTALL,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- INSTALL 1999/02/07 06:28:58 1.2 +++ INSTALL 1999/03/17 16:59:16 1.3 @@ -76,7 +76,7 @@ under all operating systems therefore you cannot use the DSO mechanism on all platforms. And Apache currently has only limited built-in knowledge on how to compile shared objects because this is heavily - platform-dependend. The current state is this: + platform-dependent. The current state is this: o Out-of-the-box supported platforms are: - Linux - SunOS - UnixWare @@ -238,14 +238,15 @@ to automatically include a simple third-party module to the Apache build process. - Use the --activate-module=FILE option to on-the-fly add an entry for an - existing module source file in the configuration file. FILE has to be a - valid path under src/modules/ of the Apache source tree, i.e. it already - has to be copied to this location before. The module is automatically - enabled. Use this option to automatically include a complex third-party - module to the Apache build process where, for instance a module like - mod_perl or mod_php3 consisting of more than one file which are created by - a third-party configuration scheme. + Use the --activate-module=FILE option to add an entry for an existing + module source file into the configuration file on-the-fly. FILE has to be + a valid path beginning with "src/modules/", and the file has to have been + copied to this location in the Apache source tree before running + configure. The module is automatically enabled. Use this option to + automatically include a complex third-party module to the Apache build + process where, for instance a module like mod_perl or mod_php3 consisting + of more than one file which are created by a third-party configuration + scheme. Use the --enable-module=NAME and --disable-module=NAME options to enable or disable a particular already distributed module from the Apache 1.3 +46 -30 apache-apr/pthreads/Makefile.tmpl Index: Makefile.tmpl =================================================================== RCS file: /home/cvs/apache-apr/pthreads/Makefile.tmpl,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- Makefile.tmpl 1999/02/07 06:28:59 1.2 +++ Makefile.tmpl 1999/03/17 16:59:16 1.3 @@ -81,10 +81,16 @@ RM = rm -f MKDIR = $(TOP)/$(AUX)/mkdir.sh INSTALL = $(TOP)/$(AUX)/install.sh -c -INSTALL_PROGRAM = $(INSTALL) -s -m 755 -INSTALL_DSO = $(INSTALL) -m 755 -INSTALL_SCRIPT = $(INSTALL) -m 755 -INSTALL_DATA = $(INSTALL) -m 644 +IFLAGS_PROGRAM = -m 755 -s +IFLAGS_CORE = -m 755 +IFLAGS_DSO = -m 755 +IFLAGS_SCRIPT = -m 755 +IFLAGS_DATA = -m 644 +INSTALL_PROGRAM = $(INSTALL) $(IFLAGS_PROGRAM) +INSTALL_CORE = $(INSTALL) $(IFLAGS_CORE) +INSTALL_DSO = $(INSTALL) $(IFLAGS_DSO) +INSTALL_SCRIPT = $(INSTALL) $(IFLAGS_SCRIPT) +INSTALL_DATA = $(INSTALL) $(IFLAGS_DATA) PERL = @PERL@ TAR = @TAR@ TAROPT = @TAROPT@ @@ -106,6 +112,9 @@ mandir = @mandir@ sysconfdir = @sysconfdir@ datadir = @datadir@ +iconsdir = $(datadir)/icons +htdocsdir = $(datadir)/htdocs +cgidir = $(datadir)/cgi-bin includedir = @includedir@ localstatedir = @localstatedir@ runtimedir = @runtimedir@ @@ -240,9 +249,9 @@ $(MKDIR) $(root)$(mandir)/man1 $(MKDIR) $(root)$(mandir)/man8 $(MKDIR) $(root)$(sysconfdir) - $(MKDIR) $(root)$(datadir)/htdocs - $(MKDIR) $(root)$(datadir)/icons - $(MKDIR) $(root)$(datadir)/cgi-bin + $(MKDIR) $(root)$(htdocsdir) + $(MKDIR) $(root)$(iconsdir) + $(MKDIR) $(root)$(cgidir) $(MKDIR) $(root)$(includedir) $(MKDIR) $(root)$(runtimedir) $(MKDIR) $(root)$(logfiledir) @@ -253,12 +262,18 @@ # shared object files. install-programs: @echo "===> [programs: Installing Apache $(TARGET) program and shared objects]" - $(INSTALL_PROGRAM) $(TOP)/$(SRC)/$(TARGET) $(root)$(sbindir)/$(TARGET) + [EMAIL PROTECTED] [ ".`grep '^[ ]*AddModule.*mod_so\.o' $(TOP)/$(SRC)/Configuration.apaci`" != . ]; then \ + echo "$(INSTALL_CORE) $(TOP)/$(SRC)/$(TARGET) $(root)$(sbindir)/$(TARGET)"; \ + $(INSTALL_CORE) $(TOP)/$(SRC)/$(TARGET) $(root)$(sbindir)/$(TARGET); \ + else \ + echo "$(INSTALL_PROGRAM) $(TOP)/$(SRC)/$(TARGET) $(root)$(sbindir)/$(TARGET)"; \ + $(INSTALL_PROGRAM) $(TOP)/$(SRC)/$(TARGET) $(root)$(sbindir)/$(TARGET); \ + fi [EMAIL PROTECTED] [ ".`grep 'SUBTARGET=target_shared' $(TOP)/$(SRC)/Makefile`" != . ]; then \ SHLIB_SUFFIX_NAME="`grep '^SHLIB_SUFFIX_NAME=' $(TOP)/$(SRC)/Makefile | sed -e 's:^.*=::'`"; \ SHLIB_SUFFIX_LIST="`grep '^SHLIB_SUFFIX_LIST=' $(TOP)/$(SRC)/Makefile | sed -e 's:^.*=::'`"; \ - echo "$(INSTALL_DSO) $(TOP)/$(SRC)/lib$(TARGET).ep $(root)$(libexecdir)/lib$(TARGET).ep"; \ - $(INSTALL_DSO) $(TOP)/$(SRC)/lib$(TARGET).ep $(root)$(libexecdir)/lib$(TARGET).ep; \ + echo "$(INSTALL_CORE) $(TOP)/$(SRC)/lib$(TARGET).ep $(root)$(libexecdir)/lib$(TARGET).ep"; \ + $(INSTALL_CORE) $(TOP)/$(SRC)/lib$(TARGET).ep $(root)$(libexecdir)/lib$(TARGET).ep; \ echo "$(INSTALL_DSO) $(TOP)/$(SRC)/lib$(TARGET).$${SHLIB_SUFFIX_NAME} $(root)$(libexecdir)/lib$(TARGET).$${SHLIB_SUFFIX_NAME}"; \ $(INSTALL_DSO) $(TOP)/$(SRC)/lib$(TARGET).$${SHLIB_SUFFIX_NAME} $(root)$(libexecdir)/lib$(TARGET).$${SHLIB_SUFFIX_NAME}; \ if [ ".$${SHLIB_SUFFIX_LIST}" != . ]; then \ @@ -300,7 +315,7 @@ install-support: @echo "===> [support: Installing Apache support programs and scripts]" $(INSTALL_PROGRAM) $(TOP)/$(SRC)/support/ab $(root)$(sbindir)/ab - $(INSTALL_DATA) $(TOP)/$(SRC)/support/ab.1 $(root)$(mandir)/man1/ab.1 + $(INSTALL_DATA) $(TOP)/$(SRC)/support/ab.8 $(root)$(mandir)/man8/ab.8 @if [ ".$(TARGET)" = .httpd ]; then \ apachectl='apachectl'; \ else \ @@ -311,8 +326,8 @@ -e 's;HTTPD=.*;HTTPD=$(sbindir)/$(TARGET);' \ < $(TOP)/$(SRC)/support/apachectl > $(TOP)/$(SRC)/.apaci.install.tmp && \ $(INSTALL_SCRIPT) $(TOP)/$(SRC)/.apaci.install.tmp $(root)$(sbindir)/$${apachectl}; \ - echo "$(INSTALL_DATA) $(TOP)/$(SRC)/support/apachectl.1 $(root)$(mandir)/man1/$${apachectl}.1"; \ - $(INSTALL_DATA) $(TOP)/$(SRC)/support/apachectl.1 $(root)$(mandir)/man1/$${apachectl}.1 + echo "$(INSTALL_DATA) $(TOP)/$(SRC)/support/apachectl.8 $(root)$(mandir)/man8/$${apachectl}.8"; \ + $(INSTALL_DATA) $(TOP)/$(SRC)/support/apachectl.8 $(root)$(mandir)/man8/$${apachectl}.8 $(INSTALL_PROGRAM) $(TOP)/$(SRC)/support/htpasswd $(root)$(bindir)/htpasswd $(INSTALL_DATA) $(TOP)/$(SRC)/support/htpasswd.1 $(root)$(mandir)/man1/htpasswd.1 $(INSTALL_PROGRAM) $(TOP)/$(SRC)/support/htdigest $(root)$(bindir)/htdigest @@ -364,31 +379,31 @@ # icons and distributed CGI scripts. install-data: @echo "===> [data: Installing initial data files]" - [EMAIL PROTECTED] [ -f $(root)$(datadir)/htdocs/index.html ]; then \ - echo "[PRESERVING EXISTING DATA SUBDIR: $(root)$(datadir)/htdocs/]"; \ + [EMAIL PROTECTED] [ -f $(root)$(htdocsdir)/index.html ]; then \ + echo "[PRESERVING EXISTING DATA SUBDIR: $(root)$(htdocsdir)/]"; \ else \ - echo "Copying tree $(TOP)/htdocs/ -> $(root)$(datadir)/htdocs/"; \ + echo "Copying tree $(TOP)/htdocs/ -> $(root)$(htdocsdir)/"; \ (cd $(TOP)/htdocs/ && $(TAR) $(TAROPT) - *) |\ - (cd $(root)$(datadir)/htdocs/ && $(TAR) -xf -); \ - find $(root)$(datadir)/htdocs/ -type d -exec chmod a+rx {} \; ; \ - find $(root)$(datadir)/htdocs/ -type f -exec chmod a+r {} \; ; \ + (cd $(root)$(htdocsdir)/ && $(TAR) -xf -); \ + find $(root)$(htdocsdir)/ -type d -exec chmod a+rx {} \; ; \ + find $(root)$(htdocsdir)/ -type f -exec chmod a+r {} \; ; \ fi - [EMAIL PROTECTED] [ -f $(root)$(datadir)/cgi-bin/printenv ]; then \ - echo "[PRESERVING EXISTING DATA SUBDIR: $(root)$(datadir)/cgi-bin/]"; \ + [EMAIL PROTECTED] [ -f $(root)$(cgidir)/printenv ]; then \ + echo "[PRESERVING EXISTING DATA SUBDIR: $(root)$(cgidir)/]"; \ else \ for script in printenv test-cgi; do \ cat $(TOP)/cgi-bin/$${script} |\ sed -e 's;^#!/.*perl;#!$(PERL);' \ > $(TOP)/$(SRC)/.apaci.install.tmp; \ - echo "$(INSTALL_DATA) $(TOP)/conf/$${script}[*] $(root)$(datadir)/cgi-bin/$${script}"; \ - $(INSTALL_DATA) $(TOP)/$(SRC)/.apaci.install.tmp $(root)$(datadir)/cgi-bin/$${script}; \ + echo "$(INSTALL_DATA) $(TOP)/conf/$${script}[*] $(root)$(cgidir)/$${script}"; \ + $(INSTALL_DATA) $(TOP)/$(SRC)/.apaci.install.tmp $(root)$(cgidir)/$${script}; \ done; \ fi - @echo "Copying tree $(TOP)/icons/ -> $(root)$(datadir)/icons/"; \ + @echo "Copying tree $(TOP)/icons/ -> $(root)$(iconsdir)/"; \ (cd $(TOP)/icons/ && $(TAR) $(TAROPT) - *) |\ - (cd $(root)$(datadir)/icons/ && $(TAR) -xf -); \ - find $(root)$(datadir)/icons/ -type d -exec chmod a+rx {} \; ;\ - find $(root)$(datadir)/icons/ -type f -exec chmod a+r {} \; + (cd $(root)$(iconsdir)/ && $(TAR) -xf -); \ + find $(root)$(iconsdir)/ -type d -exec chmod a+rx {} \; ;\ + find $(root)$(iconsdir)/ -type f -exec chmod a+r {} \; @echo "<=== [data]" # create the initial configuration by providing default files @@ -412,11 +427,12 @@ echo ""; \ cat $(TOP)/conf/$${conf}-dist ) |\ sed -e '/# LoadModule/r $(TOP)/$(SRC)/.apaci.install.conf' \ - -e 's;@@ServerRoot@@/htdocs;$(datadir)/htdocs;' \ - -e 's;@@ServerRoot@@/icons;$(datadir)/icons;' \ - -e 's;@@ServerRoot@@/cgi-bin;$(datadir)/cgi-bin;' \ + -e 's;@@ServerRoot@@/htdocs;$(htdocsdir);' \ + -e 's;@@ServerRoot@@/icons;$(iconsdir);' \ + -e 's;@@ServerRoot@@/cgi-bin;$(cgidir);' \ -e 's;@@ServerRoot@@/proxy;$(proxycachedir);' \ -e 's;@@ServerRoot@@;$(prefix);g' \ + -e 's;httpd.conf;$(TARGET).conf;' \ -e 's;logs/accept.lock;$(runtimedir)/$(TARGET).lock;' \ -e 's;logs/apache_runtime_status;$(runtimedir)/$(TARGET).scoreboard;' \ -e 's;logs/httpd.pid;$(runtimedir)/$(TARGET).pid;' \ 1.3 +19 -0 apache-apr/pthreads/README.configure Index: README.configure =================================================================== RCS file: /home/cvs/apache-apr/pthreads/README.configure,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- README.configure 1999/02/07 06:28:59 1.2 +++ README.configure 1999/03/17 16:59:17 1.3 @@ -284,3 +284,22 @@ $ make $ make install + 3. You can also use APXS: + + $ cd apache-1.3.X + $ ./configure --prefix=/path/to/apache --enable-shared=max + $ make + $ make install + + $ cd php-3.0.X + $ ./configure --with-apxs=/path/to/apache/bin/apxs \ + --with-config-file-path=/path/to/apache + $ make + $ make install + + At this point don't forget to edit your conf/httpd.conf file and + make sure the file contains the line: + + AddType application/x-httpd-php3 .php3 + + Then restart your server. 1.2 +17 -0 apache-apr/pthreads/config.layout Index: config.layout =================================================================== RCS file: /home/cvs/apache-apr/pthreads/config.layout,v retrieving revision 1.1 retrieving revision 1.2 diff -u -u -r1.1 -r1.2 --- config.layout 1999/02/07 06:28:59 1.1 +++ config.layout 1999/03/17 16:59:19 1.2 @@ -60,3 +60,20 @@ logfiledir: logs proxycachedir: proxy </Layout> + +# Apple's Mac OS X Server Layout +<Layout Rhapsody> + prefix: /Local/Library/WebServer + exec_prefix: /usr + bindir: $exec_prefix/bin + sbindir: $exec_prefix/sbin + libexecdir: /System/Library/Apache/Modules + mandir: $exec_prefix/share/man + sysconfdir: $prefix/Configuration + datadir: $prefix + includedir: /System/Library/Frameworks/Apache.framework/Versions/1.3/Headers + localstatedir: /private/var + runtimedir: $prefix/Logs + logfiledir: $prefix/Logs + proxycachedir: $prefix/ProxyCache +</Layout> 1.3 +22 -5 apache-apr/pthreads/configure Index: configure =================================================================== RCS file: /home/cvs/apache-apr/pthreads/configure,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- configure 1999/02/07 06:28:59 1.2 +++ configure 1999/03/17 16:59:19 1.3 @@ -617,7 +617,7 @@ file="$apc_optarg" case $file in src/modules/* ) ;; - *) echo "configure:Error: Module source already has to stay below src/modules/ to be activated" 1>&2 + *) echo "configure:Error: Module source already has to be below src/modules/ to be activated" 1>&2 exit 1 ;; esac @@ -729,6 +729,10 @@ suexec ) suexec=1 ;; + * ) + echo "configure:Error: invalid option '$apc_option'" 1>&2 + exit 1 + ;; esac ;; --disable-*) @@ -787,6 +791,10 @@ ;; esac ;; + * ) + echo "configure:Error: invalid option '$apc_option'" 1>&2 + exit 1 + ;; esac ;; --permute-module=*:*) @@ -946,10 +954,19 @@ eval "$var=\"$val\"" # expand value eval "val=\$$var" - # add target suffix when requested - if [ ".`echo $val | grep $thetarget`" = . ]; then - eval "autosuffix=\$autosuffix_$var" - if [ "x$autosuffix" = "xyes" ]; then + # automatically add target suffix to path when it's + # requested (path has a trailing plus in config.layout) and + # looks reasonable (i.e. when "apache" or target-name + # still not part of path) + eval "autosuffix=\$autosuffix_$var" + if [ "x$autosuffix" = "xyes" ]; then + addtarget=no + if [ "x`echo $val | grep apache`" = "x" ]; then + if [ "x`echo $val | grep $thetarget`" = "x" ]; then + addtarget=yes + fi + fi + if [ "x$addtarget" = "xyes" ]; then eval "$var=\"\$$var/$thetarget\"" fi fi 1.4 +5 -6 apache-apr/pthreads/conf/httpd.conf-dist Index: httpd.conf-dist =================================================================== RCS file: /home/cvs/apache-apr/pthreads/conf/httpd.conf-dist,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- httpd.conf-dist 1999/03/07 00:50:28 1.3 +++ httpd.conf-dist 1999/03/17 16:59:28 1.4 @@ -86,7 +86,7 @@ ScoreBoardFile logs/apache_runtime_status # -# In the standard configuration, the server will process httpd.conf, +# In the standard configuration, the server will process this file, # srm.conf, and access.conf in that order. The latter two files are # now distributed empty, as it is recommended that all directives # be kept in a single file for simplicity. The commented-out values @@ -132,8 +132,7 @@ # It does this by periodically checking how many servers are waiting # for a request. If there are fewer than MinSpareServers, it creates # a new spare. If there are more than MaxSpareServers, some of the -# spares die off. The default values in httpd.conf-dist are probably OK -# for most sites. +# spares die off. The default values are probably OK for most sites. # MinSpareServers 5 MaxSpareServers 10 @@ -649,10 +648,10 @@ # AddType allows you to tweak mime.types without actually editing it, or to # make certain files to be certain types. # -# For example, the PHP3 module (not part of the Apache distribution) -# will typically use: +# For example, the PHP3 module (not part of the Apache distribution - see +# http://www.php.net) will typically use: # -#AddType application/x-httpd-php3 .phtml +#AddType application/x-httpd-php3 .php3 #AddType application/x-httpd-php3-source .phps # 1.3 +7 -7 apache-apr/pthreads/conf/httpd.conf-dist-win Index: httpd.conf-dist-win =================================================================== RCS file: /home/cvs/apache-apr/pthreads/conf/httpd.conf-dist-win,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- httpd.conf-dist-win 1999/02/07 06:29:01 1.2 +++ httpd.conf-dist-win 1999/03/17 16:59:29 1.3 @@ -89,13 +89,6 @@ #AccessConfig conf/access.conf # -# ExtendedStatus controls whether Apache will generate "full" status -# information (ExtendedStatus On) or just basic information (ExtendedStatus -# Off) when the "server-status" handler is called. The default is Off. -# -#ExtendedStatus On - -# # Timeout: The number of seconds before receives and sends time out. # Timeout 300 @@ -185,6 +178,13 @@ #LoadModule speling_module modules/ApacheModuleSpeling.dll #LoadModule status_module modules/ApacheModuleStatus.dll #LoadModule usertrack_module modules/ApacheModuleUserTrack.dll + +# +# ExtendedStatus controls whether Apache will generate "full" status +# information (ExtendedStatus On) or just basic information (ExtendedStatus +# Off) when the "server-status" handler is called. The default is Off. +# +#ExtendedStatus On ### Section 2: 'Main' server configuration # 1.3 +1 -0 apache-apr/pthreads/conf/mime.types Index: mime.types =================================================================== RCS file: /home/cvs/apache-apr/pthreads/conf/mime.types,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- mime.types 1999/02/07 06:29:01 1.2 +++ mime.types 1999/03/17 16:59:34 1.3 @@ -197,6 +197,7 @@ audio/x-realaudio ra audio/x-wav wav chemical/x-pdb pdb xyz +image/bmp bmp image/cgm image/g3fax image/gif gif 1.20 +92 -75 apache-apr/pthreads/htdocs/manual/content-negotiation.html Index: content-negotiation.html =================================================================== RCS file: /home/cvs/apache-apr/pthreads/htdocs/manual/content-negotiation.html,v retrieving revision 1.19 retrieving revision 1.20 diff -u -u -r1.19 -r1.20 --- content-negotiation.html 1998/12/04 17:37:06 1.19 +++ content-negotiation.html 1999/03/17 16:59:39 1.20 @@ -70,12 +70,17 @@ Accept-Language, Accept-Charset and Accept-Encoding request headers. <P> -The terms used in content negotiation are: a <STRONG>resource</STRONG> is an -item which can be requested of a server, which might be selected as -the result of a content negotiation algorithm. If a resource is -available in several formats, these are called <STRONG>representations</STRONG> -or <STRONG>variants</STRONG>. The ways in which the variants for a particular -resource vary are called the <STRONG>dimensions</STRONG> of negotiation. +A <STRONG>resource</STRONG> is a conceptual entity identified by a URI +(RFC 2396). An HTTP server like Apache provides access to +<STRONG>representations</STRONG> of the resource(s) within its namespace, +with each representation in the form of a sequence of bytes with a +defined media type, character set, encoding, etc. Each resource may be +associated with zero, one, or more than one representation +at any given time. If multiple representations are available, +the resource is referred to as <STRONG>negotiable</STRONG> and each of its +representations is termed a <STRONG>variant</STRONG>. The ways in which the +variants for a negotiable resource vary are called the +<STRONG>dimensions</STRONG> of negotiation. <H2>Negotiation in Apache</H2> @@ -86,9 +91,9 @@ <UL> <LI> Using a type map (<EM>i.e.</EM>, a <CODE>*.var</CODE> file) which - names the files containing the variants explicitly - <LI> Or using a 'MultiViews' search, where the server does an implicit - filename pattern match, and chooses from among the results. + names the files containing the variants explicitly, or + <LI> Using a 'MultiViews' search, where the server does an implicit + filename pattern match and chooses from among the results. </UL> <H3>Using a type-map file</H3> @@ -98,25 +103,25 @@ named <CODE>type-map</CODE> (or, for backwards-compatibility with older Apache configurations, the mime type <CODE>application/x-type-map</CODE>). Note that to use this feature, -you've got to have a <CODE>SetHandler</CODE> some place which defines a +you must have a handler set in the configuration that defines a file suffix as <CODE>type-map</CODE>; this is best done with a -<PRE> +<PRE> AddHandler type-map var - </PRE> -in <CODE>srm.conf</CODE>. See comments in the sample config files for -details. <P> +in the server configuration file. See the comments in the sample config +file for more details. <P> + Type map files have an entry for each available variant; these entries -consist of contiguous RFC822-format header lines. Entries for +consist of contiguous HTTP-format header lines. Entries for different variants are separated by blank lines. Blank lines are illegal within an entry. It is conventional to begin a map file with an entry for the combined entity as a whole (although this is not required, and if present will be ignored). An example map file is: -<PRE> +<PRE> URI: foo URI: foo.en.html @@ -124,13 +129,14 @@ Content-language: en URI: foo.fr.de.html - Content-type: text/html; charset=iso-8859-2 + Content-type: text/html;charset=iso-8859-2 Content-language: fr, de </PRE> If the variants have different source qualities, that may be indicated by the "qs" parameter to the media type, as in this picture (available as jpeg, gif, or ASCII-art): + <PRE> URI: foo @@ -142,14 +148,22 @@ URI: foo.txt Content-type: text/plain; qs=0.01 - </PRE> <P> -qs values can vary between 0.000 and 1.000. Note that any variant with +qs values can vary in the range 0.000 to 1.000. Note that any variant with a qs value of 0.000 will never be chosen. Variants with no 'qs' -parameter value are given a qs factor of 1.0. <P> +parameter value are given a qs factor of 1.0. The qs parameter indicates +the relative 'quality' of this variant compared to the other available +variants, independent of the client's capabilities. For example, a jpeg +file is usually of higher source quality than an ascii file if it is +attempting to represent a photograph. However, if the resource being +represented is an original ascii art, then an ascii representation would +have a higher source quality than a jpeg representation. A qs value +is therefore specific to a given variant depending on the nature of +the resource it represents. +<P> The full list of headers recognized is: <DL> @@ -160,22 +174,24 @@ the same server (!), and they must refer to files to which the client would be granted access if they were to be requested directly. - <DT> <CODE>Content-type:</CODE> + <DT> <CODE>Content-Type:</CODE> <DD> media type --- charset, level and "qs" parameters may be given. These are often referred to as MIME types; typical media types are <CODE>image/gif</CODE>, <CODE>text/plain</CODE>, or <CODE>text/html; level=3</CODE>. - <DT> <CODE>Content-language:</CODE> + <DT> <CODE>Content-Language:</CODE> <DD> The languages of the variant, specified as an Internet standard - language code (<EM>e.g.</EM>, <CODE>en</CODE> for English, + language tag from RFC 1766 (<EM>e.g.</EM>, <CODE>en</CODE> for English, <CODE>kr</CODE> for Korean, <EM>etc.</EM>). - <DT> <CODE>Content-encoding:</CODE> + <DT> <CODE>Content-Encoding:</CODE> <DD> If the file is compressed, or otherwise encoded, rather than containing the actual raw data, this says how that was done. - For compressed files (the only case where this generally comes - up), content encoding should be - <CODE>x-compress</CODE>, or <CODE>x-gzip</CODE>, as appropriate. - <DT> <CODE>Content-length:</CODE> + Apache only recognizes encodings that are defined by an + <A HREF="mod/mod_mime.html#addencoding">AddEncoding</A> directive. + This normally includes the encodings <CODE>x-compress</CODE> + for compress'd files, and <CODE>x-gzip</CODE> for gzip'd files. + The <CODE>x-</CODE> prefix is ignored for encoding comparisons. + <DT> <CODE>Content-Length:</CODE> <DD> The size of the file. Clients can ask to receive a given media type only if the variant isn't too big; specifying a content length in the map allows the server to compare against these @@ -185,17 +201,15 @@ <H3>Multiviews</H3> <P> -This is a per-directory option, meaning it can be set with an -<CODE>Options</CODE> directive within a <CODE><Directory></CODE>, +<CODE>MultiViews</CODE> is a per-directory option, meaning it can be set with +an <CODE>Options</CODE> directive within a <CODE><Directory></CODE>, <CODE><Location></CODE> or <CODE><Files></CODE> section in <CODE>access.conf</CODE>, or (if <CODE>AllowOverride</CODE> is properly set) in <CODE>.htaccess</CODE> files. Note that <CODE>Options All</CODE> does not set <CODE>MultiViews</CODE>; you -have to ask for it by name. (Fixing this is a one-line change to -<CODE>http_core.h</CODE>). +have to ask for it by name. <P> - The effect of <CODE>MultiViews</CODE> is as follows: if the server receives a request for <CODE>/some/dir/foo</CODE>, if <CODE>/some/dir</CODE> has <CODE>MultiViews</CODE> enabled, and @@ -204,23 +218,22 @@ type map which names all those files, assigning them the same media types and content-encodings it would have if the client had asked for one of them by name. It then chooses the best match to the client's -requirements, and forwards them along. +requirements. <P> - -This applies to searches for the file named by the +<CODE>MultiViews</CODE> may also apply to searches for the file named by the <CODE>DirectoryIndex</CODE> directive, if the server is trying to -index a directory; if the configuration files specify -<PRE> +index a directory. If the configuration files specify +<PRE> DirectoryIndex index +</PRE> -</PRE> then the server will arbitrate between <CODE>index.html</CODE> +then the server will arbitrate between <CODE>index.html</CODE> and <CODE>index.html3</CODE> if both are present. If neither are present, and <CODE>index.cgi</CODE> is there, the server will run it. <P> - If one of the files found when reading the directive is a CGI script, it's not obvious what should happen. The code gives that case special treatment --- if the request was a POST, or a GET with @@ -233,7 +246,7 @@ After Apache has obtained a list of the variants for a given resource, either from a type-map file or from the filenames in the directory, it -applies a algorithm to decide on the 'best' variant to return, if +applies an algorithm to decide on the 'best' variant to return, if any. To do this it calculates a quality value for each variant in each of the dimensions of variance. It is not necessary to know any of the details of how negotiation actually takes place in order to use Apache's @@ -247,22 +260,28 @@ <H3>Dimensions of Negotiation</H3> <TABLE> -<TR><TH>Dimension +<TR valign="top"> +<TH>Dimension <TH>Notes -<TR><TD>Media Type -<TD>Browser indicates preferences on Accept: header. Each item +<TR valign="top"> +<TD>Media Type +<TD>Browser indicates preferences with the Accept header field. Each item can have an associated quality factor. Variant description can also -have a quality factor. -<TR><TD>Language -<TD>Browser indicates preferences on Accept-Language: header. Each -item -can have a quality factor. Variants can be associated with none, one -or more languages. -<TR><TD>Encoding -<TD>Browser indicates preference with Accept-Encoding: header. -<TR><TD>Charset -<TD>Browser indicates preference with Accept-Charset: header. Variants -can indicate a charset as a parameter of the media type. +have a quality factor (the "qs" parameter). +<TR valign="top"> +<TD>Language +<TD>Browser indicates preferences with the Accept-Language header field. +Each item can have a quality factor. Variants can be associated with none, one +or more than one language. +<TR valign="top"> +<TD>Encoding +<TD>Browser indicates preference with the Accept-Encoding header field. +Each item can have a quality factor. +<TR valign="top"> +<TD>Charset +<TD>Browser indicates preference with the Accept-Charset header field. +Each item can have a quality factor. +Variants can indicate a charset as a parameter of the media type. </TABLE> <H3>Apache Negotiation Algorithm</H3> @@ -270,13 +289,13 @@ <P> Apache uses an algorithm to select the 'best' variant (if any) to return to the browser. This algorithm is not configurable. It operates -like this: +as follows: <OL> <LI> -Firstly, for each dimension of the negotiation, the appropriate -Accept header is checked and a quality assigned to this each -variant. If the Accept header for any dimension means that this +First, for each dimension of the negotiation, the appropriate +<EM>Accept*</EM> header field is checked and a quality assigned to each +variant. If the <EM>Accept*</EM> header for any dimension means that this variant is not acceptable, eliminate it. If no variants remain, go to step 4. @@ -284,7 +303,7 @@ the following tests is applied in order. Any variants not selected at each stage are eliminated. After each test, if only one variant remains, it is selected as the best match. If more than one variant -remains, move onto the next test. +remains, move on to the next test. <OL> <LI>Multiply the quality factor from the Accept header with the @@ -301,6 +320,11 @@ <LI>Select the variants with the highest 'level' media parameter (used to give the version of text/html media types). +<LI>Select only variants with acceptable charset media parameters, + as given on the Accept-Charset header line. Charset ISO-8859-1 + is acceptable unless explicitly excluded. Variants not associated + with a particular charset are assumed to be in ISO-8859-1. + <LI>Select the variants with the best encoding. If there are variants with an encoding that is acceptable to the user-agent, select only these variants. Otherwise if there is a mix of encoded @@ -308,16 +332,11 @@ If either all variants are encoded or all variants are not encoded, select all variants. -<LI>Select only variants with acceptable charset media parameters, - as given on the Accept-Charset header line. Charset ISO-8859-1 - is always acceptable. Variants not associated with a particular - charset are assumed to be in ISO-8859-1. - <LI>Select the variants with the smallest content length <LI>Select the first variant of those remaining (this will be either the -first listed in the type-map file, or the first read from the directory) -and go to stage 3. + first listed in the type-map file, or the first read from the directory) + and go to stage 3. </OL> @@ -326,7 +345,7 @@ dimensions of negotiation (browsers and caches can use this information when caching the resource). End. -<LI>To get here means no variant was selected (because non are acceptable +<LI>To get here means no variant was selected (because none are acceptable to the browser). Return a 406 status (meaning "No acceptable representation") with a response body consisting of an HTML document listing the available variants. Also set the HTTP Vary header to indicate the @@ -508,12 +527,11 @@ <H2>Note on Caching</H2> <P> -When a cache stores a document, it associates it with the request URL. +When a cache stores a representation, it associates it with the request URL. The next time that URL is requested, the cache can use the stored -document, provided it is still within date. But if the resource is -subject to content negotiation at the server, this would result in -only the first requested variant being cached, and subsequent cache -hits could return the wrong response. To prevent this, +representation. But, if the resource is negotiable at the server, +this might result in only the first requested variant being cached and +subsequent cache hits might return the wrong response. To prevent this, Apache normally marks all responses that are returned after content negotiation as non-cacheable by HTTP/1.0 clients. Apache also supports the HTTP/1.1 protocol features to allow caching of negotiated responses. <P> @@ -522,8 +540,7 @@ browser or a cache), the directive <TT>CacheNegotiatedDocs</TT> can be used to allow caching of responses which were subject to negotiation. This directive can be given in the server config or virtual host, and -takes no arguments. It has no effect on requests from HTTP/1.1 -clients. +takes no arguments. It has no effect on requests from HTTP/1.1 clients. <!--#include virtual="footer.html" --> </BODY> 1.18 +1 -1 apache-apr/pthreads/htdocs/manual/handler.html Index: handler.html =================================================================== RCS file: /home/cvs/apache-apr/pthreads/htdocs/manual/handler.html,v retrieving revision 1.17 retrieving revision 1.18 diff -u -u -r1.17 -r1.18 --- handler.html 1998/11/20 15:56:34 1.17 +++ handler.html 1999/03/17 16:59:41 1.18 @@ -29,7 +29,7 @@ handlers are unrelated to file type. This is advantageous both because it is a more elegant solution, but it also allows for both a type <STRONG>and</STRONG> a handler to be associated with a file (See also -<A HREF="mod/mod_mime#multipleext">Files with Multiple Extensions</A>) +<A HREF="mod/mod_mime.html#multipleext">Files with Multiple Extensions</A>) </P> 1.28 +1 -1 apache-apr/pthreads/htdocs/manual/index.html Index: index.html =================================================================== RCS file: /home/cvs/apache-apr/pthreads/htdocs/manual/index.html,v retrieving revision 1.27 retrieving revision 1.28 diff -u -u -r1.27 -r1.28 --- index.html 1998/12/19 13:17:45 1.27 +++ index.html 1999/03/17 16:59:42 1.28 @@ -27,7 +27,7 @@ <H3><A NAME="ref">Apache Reference Manual</A></H3> <UL> -<LI><A HREF="http://www.apache.org/manual-index.cgi/docs"> +<LI><A HREF="http://www.apache.org/search.html"> <STRONG>Search</STRONG></A> for key words <LI><A HREF="install.html">Compiling and Installing</A> <LI><A HREF="invoking.html">Starting</A> 1.9 +6 -4 apache-apr/pthreads/htdocs/manual/sections.html Index: sections.html =================================================================== RCS file: /home/cvs/apache-apr/pthreads/htdocs/manual/sections.html,v retrieving revision 1.8 retrieving revision 1.9 diff -u -u -r1.8 -r1.9 --- sections.html 1998/07/03 20:12:34 1.8 +++ sections.html 1999/03/17 16:59:43 1.9 @@ -33,9 +33,10 @@ section). Semantically however some things, and the most notable are <CODE>AllowOverride</CODE> and the two options <CODE>FollowSymLinks</CODE> and <CODE>SymLinksIfOwnerMatch</CODE>, -make no sense in <CODE><Location></CODE>. The same for -<CODE><Files></CODE> -- syntactically everything is fine, but -semantically some things are different. +make no sense in <CODE><Location></CODE>, +<CODE><LocationMatch></CODE> or <CODE><DirectoryMatch></CODE>. +The same for <CODE><Files></CODE> -- syntactically everything +is fine, but semantically some things are different. <H2>How the sections are merged</H2> @@ -134,7 +135,8 @@ <LI> It is not possible to use "<CODE>Options FollowSymLinks</CODE>" or "<CODE>Options SymLinksIfOwnerMatch</CODE>" inside a - <CODE><Location></CODE>/<CODE><LocationMatch></CODE> section + <CODE><Location></CODE>, <CODE><LocationMatch></CODE> + or <CODE><DirectoryMatch></CODE> section (the options are simply ignored). Using the options in question is only possible inside a <CODE><Directory></CODE> section (or a <CODE>.htaccess</CODE> file). 1.18 +8 -6 apache-apr/pthreads/htdocs/manual/misc/API.html Index: API.html =================================================================== RCS file: /home/cvs/apache-apr/pthreads/htdocs/manual/misc/API.html,v retrieving revision 1.17 retrieving revision 1.18 diff -u -u -r1.17 -r1.18 --- API.html 1998/09/17 14:14:52 1.17 +++ API.html 1999/03/17 16:59:54 1.18 @@ -360,8 +360,9 @@ order to figure out what icon to use.<P> Such handlers can construct a <EM>sub-request</EM>, using the - functions <CODE>ap_sub_req_lookup_file</CODE> and - <CODE>ap_sub_req_lookup_uri</CODE>; this constructs a new + functions <CODE>ap_sub_req_lookup_file</CODE>, + <CODE>ap_sub_req_lookup_uri</CODE>, and + <CODE>ap_sub_req_method_uri</CODE>; these construct a new <CODE>request_rec</CODE> structure and processes it as you would expect, up to but not including the point of actually sending a response. (These functions skip over the access @@ -370,7 +371,7 @@ (Server-side includes work by building sub-requests and then actually invoking the response handler for them, via the - function <CODE>run_sub_request</CODE>). + function <CODE>ap_run_sub_req</CODE>). </UL> <H3><A NAME="req_return">Handling requests, declining, and returning error @@ -704,7 +705,8 @@ <LI>for the main request this is a subpool of connection->pool; for subrequests it is a subpool of the parent request's pool. </LI> - <LI>exists until the end of the request (<EM>i.e.</EM>, destroy_sub_req, or + <LI>exists until the end of the request (<EM>i.e.</EM>, + ap_destroy_sub_req, or in child_main after process_request has finished) </LI> <LI>note that r itself is allocated from r->pool; <EM>i.e.</EM>, @@ -818,7 +820,7 @@ One final note --- sub-requests have their own resource pools, which are sub-pools of the resource pool for the main request. The polite way to reclaim the resources associated with a sub request which you -have allocated (using the <CODE>ap_sub_req_lookup_...</CODE> functions) +have allocated (using the <CODE>ap_sub_req_...</CODE> functions) is <CODE>ap_destroy_sub_req</CODE>, which frees the resource pool. Before calling this function, be sure to copy anything that you care about which might be allocated in the sub-request's resource pool into @@ -830,7 +832,7 @@ request, and it will be freed anyway when the main request pool is cleared. It is only when you are allocating many, many sub-requests for a single main request that you should seriously consider the -<CODE>ap_destroy...</CODE> functions). +<CODE>ap_destroy_...</CODE> functions). <H2><A NAME="config">Configuration, commands and the like</A></H2> 1.137 +1462 -1386apache-apr/pthreads/htdocs/manual/misc/FAQ.html Index: FAQ.html =================================================================== RCS file: /home/cvs/apache-apr/pthreads/htdocs/manual/misc/FAQ.html,v retrieving revision 1.136 retrieving revision 1.137 diff -u -u -r1.136 -r1.137 --- FAQ.html 1999/01/27 03:36:37 1.136 +++ FAQ.html 1999/03/17 16:59:55 1.137 @@ -14,7 +14,7 @@ <!--#include virtual="header.html" --> <H1 ALIGN="CENTER">Apache Server Frequently Asked Questions</H1> <P> - $Revision: 1.136 $ ($Date: 1999/01/27 03:36:37 $) + $Revision: 1.137 $ ($Date: 1999/03/17 16:59:55 $) </P> <P> The latest version of this FAQ is always available from the main @@ -81,8 +81,8 @@ <!-- PR #2300. --> <!-- - how do I tell what version of Apache I am running? --> <UL> - <LI><STRONG>Background</STRONG> - <OL START=1> + <LI><STRONG>A. Background</STRONG> + <OL> <LI><A HREF="#what">What is Apache?</A> </LI> <LI><A HREF="#why">Why was Apache created?</A> @@ -106,55 +106,100 @@ </LI> </OL> </LI> - <LI><STRONG>Technical Questions</STRONG> - <OL START=11> + <LI><STRONG>B. General Technical Questions</STRONG> + <OL> <LI><A HREF="#what2do">"Why can't I ...? Why won't ... work?" What to do in case of problems</A> </LI> <LI><A HREF="#compatible">How compatible is Apache with my existing NCSA 1.3 setup?</A> </LI> - <LI><A HREF="#CGIoutsideScriptAlias">How do I enable CGI execution - in directories other than the ScriptAlias?</A> + <LI><A HREF="#year2000">Is Apache Year 2000 compliant?</A> </LI> - <LI><A HREF="#premature-script-headers">What does it mean when my - CGIs fail with "<SAMP>Premature end of script - headers</SAMP>"?</A> + <LI><A HREF="#submit_patch">How do I submit a patch to the Apache Group?</A> </LI> - <LI><A HREF="#ssi-part-i">How do I enable SSI (parsed HTML)?</A> + <LI><A HREF="#domination">Why has Apache stolen my favourite site's + Internet address?</A> </LI> - <LI><A HREF="#ssi-part-ii">Why don't my parsed files get cached?</A> + <LI><A HREF="#apspam">Why am I getting spam mail from the Apache site?</A> </LI> - <LI><A HREF="#ssi-part-iii">How can I have my script output parsed?</A> + <LI><A HREF="#redist">May I include the Apache software on a CD or other + package I'm distributing?</A> </LI> - <LI><A HREF="#ssi-part-iv">SSIs don't work for VirtualHosts and/or - user home directories</A> + <LI><A HREF="#zoom">What's the best hardware/operating system/... How do + I get the most out of my Apache Web server?</A> </LI> - <LI><A HREF="#proxy">Does or will Apache act as a Proxy server?</A> + <LI><A HREF="#regex">What are "regular expressions"?</A> </LI> - <LI><A HREF="#multiviews">What are "multiviews"?</A> + </OL> + </LI> + <LI><STRONG>C. Building Apache</STRONG> + <OL> + <LI><A HREF="#bind8.1">Why do I get an error about an undefined + reference to "<SAMP>__inet_ntoa</SAMP>" or other + <SAMP>__inet_*</SAMP> symbols?</A> + </LI> + <LI><A HREF="#cantbuild">Why won't Apache compile with my + system's <SAMP>cc</SAMP>?</A> + </LI> + <LI><A HREF="#linuxiovec">Why do I get complaints about redefinition + of "<CODE>struct iovec</CODE>" when compiling under Linux?</A> + </LI> + <LI><A HREF="#broken-gcc">I'm using gcc and I get some compilation errors, + what is wrong?</A> + </LI> + <LI><A HREF="#glibc-crypt">I'm using RedHat Linux 5.0, or some other + <SAMP>glibc</SAMP>-based Linux system, and I get errors with the + <CODE>crypt</CODE> function when I attempt to build Apache 1.2.</A> + </LI> + </OL> + </LI> + + <LI><STRONG>D. Error Log Messages and Problems Starting Apache</STRONG> + <OL> + <LI><A HREF="#setgid">Why do I get "<SAMP>setgid: Invalid + argument</SAMP>" at startup?</A> + </LI> + <LI><A HREF="#nodelay">Why am I getting "<SAMP>httpd: could not + set socket option TCP_NODELAY</SAMP>" in my error log?</A> + </LI> + <LI><A HREF="#peerreset">Why am I getting "<SAMP>connection + reset by peer</SAMP>" in my error log?</A> + </LI> + <LI><A HREF="#wheres-the-dump">The errorlog says Apache dumped core, + but where's the dump file?</A> + </LI> + <LI><A HREF="#linux-shmget">When I run it under Linux I get "shmget: + function not found", what should I do?</A> + </LI> + <LI><A HREF="#nfslocking">Server hangs, or fails to start, and/or error log + fills with "<SAMP>fcntl: F_SETLKW: No record locks + available</SAMP>" or similar messages</A> </LI> + <LI><A HREF="#aixccbug">Why am I getting "<SAMP>Expected </Directory> + but saw </Directory></SAMP>" when I try to start Apache?</A> + </LI> + <LI><A HREF="#redhat">I'm using RedHat Linux and I have problems with httpd + dying randomly or not restarting properly</A> + </LI> + <LI><A HREF="#stopping">I upgraded from an Apache version earlier + than 1.2.0 and suddenly I have problems with Apache dying randomly + or not restarting properly</A> + </LI> + </OL> + </LI> + + <LI><STRONG>E. Configuration Questions</STRONG> + <OL> <LI><A HREF="#fdlim">Why can't I run more than <<EM>n</EM>> virtual hosts?</A> </LI> <LI><A HREF="#freebsd-setsize">Can I increase <SAMP>FD_SETSIZE</SAMP> on FreeBSD?</A> </LI> - <LI><A HREF="#POSTnotallowed">Why do I keep getting "Method Not - Allowed" for form POST requests?</A> - </LI> - <LI><A HREF="#passwdauth">Can I use my <SAMP>/etc/passwd</SAMP> file - for Web page authentication?</A> - </LI> <LI><A HREF="#errordoc401">Why doesn't my <CODE>ErrorDocument 401</CODE> work?</A> </LI> - <LI><A HREF="#errordocssi">How can I use <CODE>ErrorDocument</CODE> - and SSI to simplify customized error messages?</A> - </LI> - <LI><A HREF="#setgid">Why do I get "<SAMP>setgid: Invalid - argument</SAMP>" at startup?</A> - </LI> <LI><A HREF="#cookies1">Why does Apache send a cookie on every response?</A> </LI> <LI><A HREF="#cookies2">Why don't my cookies work, I even compiled in @@ -163,66 +208,82 @@ <LI><A HREF="#jdk1-and-http1.1">Why do my Java app[let]s give me plain text when I request an URL from an Apache server?</A> </LI> - <LI><A HREF="#putsupport">Why can't I publish to my Apache server - using PUT on Netscape Gold and other programs?</A> + <LI><A HREF="#midi">How do I get Apache to send a MIDI file so the + browser can play it?</A> </LI> - <LI><A HREF="#fastcgi">Why isn't FastCGI included with Apache any - more?</A> + <LI><A HREF="#addlog">How do I add browsers and referrers to my logs?</A> </LI> - <LI><A HREF="#nodelay">Why am I getting "<SAMP>httpd: could not - set socket option TCP_NODELAY</SAMP>" in my error log?</A> + <LI><A HREF="#set-servername">Why does accessing directories only work + when I include the trailing "/" + (<EM>e.g.</EM>, <SAMP>http://foo.domain.com/~user/</SAMP>) but + not when I omit it + (<EM>e.g.</EM>, <SAMP>http://foo.domain.com/~user</SAMP>)?</A> </LI> - <LI><A HREF="#peerreset">Why am I getting "<SAMP>connection - reset by peer</SAMP>" in my error log?</A> + <LI><A HREF="#no-info-directives">Why doesn't mod_info list any + directives?</A> + </LI> + <LI><A HREF="#namevhost">I upgraded to Apache 1.3 and now my + virtual hosts don't work!</A> + </LI> + <LI><A HREF="#redhat-htm">I'm using RedHat Linux and my .htm files are + showing up as HTML source rather than being formatted!</A> + </LI> + <LI><A HREF="#htaccess-work">My <CODE>.htaccess</CODE> files are being + ignored.</A> + </LI> + </OL> + </LI> + + <LI><STRONG>F. Dynamic Content (CGI and SSI)</STRONG> + <OL> + <LI><A HREF="#CGIoutsideScriptAlias">How do I enable CGI execution + in directories other than the ScriptAlias?</A> + </LI> + <LI><A HREF="#premature-script-headers">What does it mean when my + CGIs fail with "<SAMP>Premature end of script + headers</SAMP>"?</A> </LI> + <LI><A HREF="#POSTnotallowed">Why do I keep getting "Method Not + Allowed" for form POST requests?</A> + </LI> <LI><A HREF="#nph-scripts">How can I get my script's output without Apache buffering it? Why doesn't my server push work?</A> </LI> - <LI><A HREF="#linuxiovec">Why do I get complaints about redefinition - of "<CODE>struct iovec</CODE>" when compiling under Linux?</A> + <LI><A HREF="#cgi-spec">Where can I find the "CGI + specification"?</A> </LI> - <LI><A HREF="#wheres-the-dump">The errorlog says Apache dumped core, - but where's the dump file?</A> + <LI><A HREF="#fastcgi">Why isn't FastCGI included with Apache any + more?</A> </LI> - <LI><A HREF="#dnsauth">Why isn't restricting access by host or domain name - working correctly?</A> + <LI><A HREF="#ssi-part-i">How do I enable SSI (parsed HTML)?</A> </LI> - <LI><A HREF="#SSL-i">Why doesn't Apache include SSL?</A> + <LI><A HREF="#ssi-part-ii">Why don't my parsed files get cached?</A> </LI> - <LI><A HREF="#midi">How do I get Apache to send a MIDI file so the - browser can play it?</A> + <LI><A HREF="#ssi-part-iii">How can I have my script output parsed?</A> </LI> - <LI><A HREF="#cantbuild">Why won't Apache compile with my - system's <SAMP>cc</SAMP>?</A> + <LI><A HREF="#ssi-part-iv">SSIs don't work for VirtualHosts and/or + user home directories</A> </LI> - <LI><A HREF="#addlog">How do I add browsers and referrers to my logs?</A> + <LI><A HREF="#errordocssi">How can I use <CODE>ErrorDocument</CODE> + and SSI to simplify customized error messages?</A> </LI> - <LI><A HREF="#bind8.1">Why do I get an error about an undefined - reference to "<SAMP>__inet_ntoa</SAMP>" or other - <SAMP>__inet_*</SAMP> symbols?</A> + <LI><A HREF="#remote-user-var">Why is the environment variable + <SAMP>REMOTE_USER</SAMP> not set?</A> </LI> - <LI><A HREF="#set-servername">Why does accessing directories only work - when I include the trailing "/" - (<EM>e.g.</EM>, <SAMP>http://foo.domain.com/~user/</SAMP>) but - not when I omit it - (<EM>e.g.</EM>, <SAMP>http://foo.domain.com/~user</SAMP>)?</A> + </OL> + </LI> + <LI><STRONG>G. Authentication and Access Restrictions</STRONG> + <OL> + <LI><A HREF="#dnsauth">Why isn't restricting access by host or domain name + working correctly?</A> </LI> <LI><A HREF="#user-authentication">How do I set up Apache to require a username and password to access certain documents?</A> </LI> - <LI><A HREF="#remote-user-var">Why is the environment variable - <SAMP>REMOTE_USER</SAMP> not set?</A> - </LI> <LI><A HREF="#remote-auth-only">How do I set up Apache to allow access to certain documents only if a site is either a local site <EM>or</EM> the user supplies a password and username?</A> </LI> - <LI><A HREF="#no-info-directives">Why doesn't mod_info list any - directives?</A> - </LI> - <LI><A HREF="#linux-shmget">When I run it under Linux I get "shmget: - function not found", what should I do?</A> - </LI> <LI><A HREF="#authauthoritative">Why does my authentication give me a server error?</A> </LI> @@ -231,6 +292,13 @@ </LI> <LI><A HREF="#msql-slow">Why is my mSQL authentication terribly slow?</A> </LI> + <LI><A HREF="#passwdauth">Can I use my <SAMP>/etc/passwd</SAMP> file + for Web page authentication?</A> + </LI> + </OL> + </LI> + <LI><STRONG>H. URL Rewriting</STRONG> + <OL> <LI><A HREF="#rewrite-more-config">Where can I find mod_rewrite rulesets which already solve particular URL-related problems?</A> </LI> @@ -254,53 +322,19 @@ </LI> <LI><A HREF="#rewrite-envwhitespace">How can I use strings with whitespaces in RewriteRule's ENV flag?</A> - </LI> - <LI><A HREF="#cgi-spec">Where can I find the "CGI - specification"?</A> - </LI> - <LI><A HREF="#year2000">Is Apache Year 2000 compliant?</A> - </LI> - <LI><A HREF="#namevhost">I upgraded to Apache 1.3 and now my - virtual hosts don't work!</A> </LI> - <LI><A HREF="#redhat">I'm using RedHat Linux and I have problems with httpd - dying randomly or not restarting properly</A> - </LI> - <LI><A HREF="#stopping">I upgraded from an Apache version earlier - than 1.2.0 and suddenly I have problems with Apache dying randomly - or not restarting properly</A> - </LI> - <LI><A HREF="#redhat-htm">I'm using RedHat Linux and my .htm files are - showing up as HTML source rather than being formatted!</A> - </LI> - <LI><A HREF="#glibc-crypt">I'm using RedHat Linux 5.0, or some other - <SAMP>glibc</SAMP>-based Linux system, and I get errors with the - <CODE>crypt</CODE> function when I attempt to build Apache 1.2.</A> - </LI> - <LI><A HREF="#nfslocking">Server hangs, or fails to start, and/or error log - fills with "<SAMP>fcntl: F_SETLKW: No record locks - available</SAMP>" or similar messages</A> - </LI> - <LI><A HREF="#zoom">What's the best hardware/operating system/... How do - I get the most out of my Apache Web server?</A> - </LI> - <LI><A HREF="#regex">What are "regular expressions"?</A> - </LI> - <LI><A HREF="#broken-gcc">I'm using gcc and I get some compilation errors, - what is wrong?</A> - </LI> - <LI><A HREF="#htaccess-work">My <CODE>.htaccess</CODE> files are being - ignored.</A> - </LI> - <LI><A HREF="#submit_patch">How do I submit a patch to the Apache Group?</A> + </OL> + </LI> + <LI><STRONG>I. Features</STRONG> + <OL> + <LI><A HREF="#proxy">Does or will Apache act as a Proxy server?</A> </LI> - <LI><A HREF="#aixccbug">Why am I getting "<SAMP>Expected </Directory> - but saw </Directory></SAMP>" when I try to start Apache?</A> + <LI><A HREF="#multiviews">What are "multiviews"?</A> </LI> - <LI><A HREF="#domination">Why has Apache stolen my favourite site's - Internet address?</A> + <LI><A HREF="#putsupport">Why can't I publish to my Apache server + using PUT on Netscape Gold and other programs?</A> </LI> - <LI><A HREF="#apspam">Why am I getting spam mail from the Apache site?</A> + <LI><A HREF="#SSL-i">Why doesn't Apache include SSL?</A> </LI> </OL> </LI> @@ -309,10 +343,8 @@ <HR> <H2>The Answers</H2> - <H3> - Background - </H3> -<OL START=1> + <H3>A. Background</H3> +<OL> <LI><A NAME="what"> <STRONG>What is Apache?</STRONG> </A> @@ -480,8 +512,10 @@ <HR> </LI> </OL> - <H3>Technical Questions</H3> -<OL START=11> + + <H3>B. General Technical Questions</H3> +<OL> + <LI><A NAME="what2do"> <STRONG>"Why can't I ...? Why won't ... work?" What to do in case of problems</STRONG> @@ -526,7 +560,8 @@ </P> </LI> <LI><STRONG>Ask in the <SAMP>comp.infosystems.www.servers.unix</SAMP> - USENET newsgroup</STRONG> + or <SAMP>comp.infosystems.www.servers.ms-windows</SAMP> USENET + newsgroup (as appropriate for the platform you use).</STRONG> <P> A lot of common problems never make it to the bug database because there's already high Q&A traffic about them in the @@ -593,298 +628,542 @@ <HR> </LI> - <LI><A NAME="CGIoutsideScriptAlias"> - <STRONG>How do I enable CGI execution in directories other than - the ScriptAlias?</STRONG> + <LI><A NAME="year2000"> + <STRONG>Is Apache Year 2000 compliant?</STRONG> </A> <P> - Apache recognizes all files in a directory named as a - <A HREF="../mod/mod_alias.html#scriptalias"><SAMP>ScriptAlias</SAMP></A> - as being eligible for execution rather than processing as normal - documents. This applies regardless of the file name, so scripts in a - ScriptAlias directory don't need to be named - "<SAMP>*.cgi</SAMP>" or "<SAMP>*.pl</SAMP>" or - whatever. In other words, <EM>all</EM> files in a ScriptAlias - directory are scripts, as far as Apache is concerned. + Yes, Apache is Year 2000 compliant. </P> <P> - To persuade Apache to execute scripts in other locations, such as in - directories where normal documents may also live, you must tell it how - to recognize them - and also that it's okay to execute them. For - this, you need to use something like the - <A HREF="../mod/mod_mime.html#addhandler"><SAMP>AddHandler</SAMP></A> - directive. + Apache internally never stores years as two digits. + On the HTTP protocol level RFC1123-style addresses are generated + which is the only format a HTTP/1.1-compliant server should + generate. To be compatible with older applications Apache + recognizes ANSI C's <CODE>asctime()</CODE> and + RFC850-/RFC1036-style date formats, too. + The <CODE>asctime()</CODE> format uses four-digit years, + but the RFC850 and RFC1036 date formats only define a two-digit year. + If Apache sees such a date with a value less than 70 it assumes that + the century is <SAMP>20</SAMP> rather than <SAMP>19</SAMP>. </P> <P> - <OL> - <LI>In an appropriate section of your server configuration files, add - a line such as - <P> - <DL> - <DD><CODE>AddHandler cgi-script .cgi</CODE> - </DD> - </DL> - <P></P> - <P> - The server will then recognize that all files in that location (and - its logical descendants) that end in "<SAMP>.cgi</SAMP>" - are script files, not documents. - </P> - </LI> - <LI>Make sure that the directory location is covered by an - <A HREF="../mod/core.html#options"><SAMP>Options</SAMP></A> - declaration that includes the <SAMP>ExecCGI</SAMP> option. - </LI> - </OL> - <P></P> + Although Apache is Year 2000 compliant, you may still get problems + if the underlying OS has problems with dates past year 2000 + (<EM>e.g.</EM>, OS calls which accept or return year numbers). + Most (UNIX) systems store dates internally as signed 32-bit integers + which contain the number of seconds since 1<SUP>st</SUP> January 1970, so + the magic boundary to worry about is the year 2038 and not 2000. + But modern operating systems shouldn't cause any trouble + at all. + </P> <P> - In some situations, you might not want to actually - allow all files named "<SAMP>*.cgi</SAMP>" to be executable. - Perhaps all you want is to enable a particular file in a normal directory to - be executable. This can be alternatively accomplished - <EM>via</EM> <A HREF="../mod/mod_rewrite.html"><SAMP>mod_rewrite</SAMP></A> - and the following steps: + Users of Apache 1.2.x should upgrade to a current version of Apache 1.3 + (see <A HREF="../new_features_1_3.html#misc">year-2000 improvements in + Apache 1.3</A> for details). </P> + <HR> + </LI> + + <LI><A NAME="submit_patch"> + <STRONG>How do I submit a patch to the Apache Group?</STRONG></A> + <P> + The Apache Group encourages patches from outside developers. There + are 2 main "types" of patches: small bugfixes and general + improvements. Bugfixes should be submitting using the Apache <A + HREF="http://www.apache.org/bug_report.html">bug report page</A>. + Improvements, modifications, and additions should follow the + instructions below. + </P> + <P> + In general, the first course of action is to be a member of the + <SAMP>new-httpd@apache.org</SAMP> mailing list. This indicates to + the Group that you are closely following the latest Apache + developments. Your patch file should be generated using either + '<CODE>diff -c</CODE>' or '<CODE>diff -u</CODE>' against + the latest CVS tree. To submit your patch, send email to + <SAMP>new-httpd@apache.org</SAMP> with a <SAMP>Subject:</SAMP> line + that starts with <SAMP>[PATCH]</SAMP> and includes a general + description of the patch. In the body of the message, the patch + should be clearly described and then included at the end of the + message. If the patch-file is long, you can note a URL to the file + instead of the file itself. Use of MIME enclosures/attachments + should be avoided. + </P> + <P> + Be prepared to respond to any questions about your patches and + possibly defend your code. If your patch results in a lot of + discussion, you may be asked to submit an updated patch that + incorporate all changes and suggestions. + </P> + <HR> + </LI> + + <LI><A NAME="domination"><STRONG>Why has Apache stolen my favourite site's + Internet address?</STRONG></A> + <P> + The simple answer is: "It hasn't." This misconception is usually + caused by the site in question having migrated to the Apache Web + server software, but not having migrated the site's content yet. When + Apache is installed, the default page that gets installed tells the + Webmaster the installation was successful. The expectation is that + this default page will be replaced with the site's real content. + If it doesn't, complain to the Webmaster, not to the Apache project -- + we just make the software and aren't responsible for what people + do (or don't do) with it. + </P> + <HR> + </LI> + + <LI><A NAME="apspam"><STRONG>Why am I getting spam mail from the + Apache site?</STRONG></A> + <P> + The short answer is: "You aren't." Usually when someone thinks the + Apache site is originating spam, it's because they've traced the + spam to a Web site, and the Web site says it's using Apache. See the + <A HREF="#domination">previous FAQ entry</A> for more details on this + phenomenon. + </P> + <P> + No marketing spam originates from the Apache site. The only mail + that comes from the site goes only to addresses that have been + <EM>requested</EM> to receive the mail. + </P> + <HR> + </LI> + + <LI><A NAME="redist"><STRONG>May I include the Apache software on a + CD or other package I'm distributing?</STRONG></A> + <P> + The detailed answer to this question can be found in the + Apache license, which is included in the Apache distribution in + the file <CODE>LICENSE</CODE>. You can also find it on the Web at + <SAMP><<A HREF="http://www.apache.org/LICENSE.txt" + >http://www.apache.org/LICENSE.txt</A>></SAMP>. + </P> + <HR> + </LI> + + <LI><A NAME="zoom"> + <STRONG>What's the best hardware/operating system/... How do + I get the most out of my Apache Web server?</STRONG> + </A> <P> - <OL> - <LI>Locally add to the corresponding <SAMP>.htaccess</SAMP> file a ruleset - similar to this one: - <P> - <DL> - <DD><CODE>RewriteEngine on - <BR> - RewriteBase /~foo/bar/ - <BR> - RewriteRule ^quux\.cgi$ - [T=application/x-httpd-cgi]</CODE> - </DD> - </DL> - <P></P> - </LI> - <LI>Make sure that the directory location is covered by an - <A HREF="../mod/core.html#options"><SAMP>Options</SAMP></A> - declaration that includes the <SAMP>ExecCGI</SAMP> and - <SAMP>FollowSymLinks</SAMP> option. - </LI> - </OL> - <P></P> + Check out Dean Gaudet's + <A HREF="http://www.apache.org/docs/misc/perf-tuning.html" + >performance tuning page</A>. + </P> <HR> </LI> - <LI><A NAME="premature-script-headers"> - <STRONG>What does it mean when my CGIs fail with - "<SAMP>Premature end of script headers</SAMP>"?</STRONG> + <LI><A NAME="regex"> + <STRONG>What are "regular expressions"?</STRONG></A> + <P> + Regular expressions are a way of describing a pattern - for example, "all + the words that begin with the letter A" or "every 10-digit phone number" + or even "Every sentence with two commas in it, and no capital letter Q". + Regular expressions (aka "regexp"s) are useful in Apache because they + let you apply certain attributes against collections of files or resources + in very flexible ways - for example, all .gif and .jpg files under + any "images" directory could be written as /.*\/images\/.*[jpg|gif]/. + </P> + <P> + The best overview around is probably the one which comes with Perl. + We implement a simple subset of Perl's regexp support, but it's + still a good way to learn what they mean. You can start by going + to the <A + HREF="http://www.perl.com/CPAN-local/doc/manual/html/pod/perlre.html#Version_8_Regular_Expresions" + >CPAN page on regular expressions</A>, and branching out from + there. + </P> + <HR> + </LI> +</OL> + + <H3>C. Building Apache</H3> +<OL> + + <LI><A NAME="bind8.1"> + <STRONG>Why do I get an error about an undefined reference to + "<SAMP>__inet_ntoa</SAMP>" or other + <SAMP>__inet_*</SAMP> symbols?</STRONG> </A> <P> - It means just what it says: the server was expecting a complete set of - HTTP headers (one or more followed by a blank line), and didn't get - them. + If you have installed <A HREF="http://www.isc.org/bind.html">BIND-8</A> + then this is normally due to a conflict between your include files + and your libraries. BIND-8 installs its include files and libraries + <CODE>/usr/local/include/</CODE> and <CODE>/usr/local/lib/</CODE>, while + the resolver that comes with your system is probably installed in + <CODE>/usr/include/</CODE> and <CODE>/usr/lib/</CODE>. If + your system uses the header files in <CODE>/usr/local/include/</CODE> + before those in <CODE>/usr/include/</CODE> but you do not use the new + resolver library, then the two versions will conflict. </P> <P> - The most common cause of this problem is the script dying before - sending the complete set of headers, or possibly any at all, to the - server. To see if this is the case, try running the script standalone - from an interactive session, rather than as a script under the server. - If you get error messages, this is almost certainly the cause of the - "premature end of script headers" message. + To resolve this, you can either make sure you use the include files + and libraries that came with your system or make sure to use the + new include files and libraries. Adding <CODE>-lbind</CODE> to the + <CODE>EXTRA_LDFLAGS</CODE> line in your <SAMP>Configuration</SAMP> + file, then re-running <SAMP>Configure</SAMP>, should resolve the + problem. (Apache versions 1.2.* and earlier use + <CODE>EXTRA_LFLAGS</CODE> instead.) </P> <P> - The second most common cause of this (aside from people not - outputting the required headers at all) is a result of an interaction - with Perl's output buffering. To make Perl flush its buffers - after each output statement, insert the following statements around - the <CODE>print</CODE> or <CODE>write</CODE> statements that send your - HTTP headers: + <STRONG>Note:</STRONG>As of BIND 8.1.1, the bind libraries and files are + installed under <SAMP>/usr/local/bind</SAMP> by default, so you + should not run into this problem. Should you want to use the bind + resolvers you'll have to add the following to the respective lines: </P> <P> <DL> - <DD><CODE>{<BR> - local ($oldbar) = $|;<BR> - $cfh = select (STDOUT);<BR> - $| = 1;<BR> - #<BR> - # print your HTTP headers here<BR> - #<BR> - $| = $oldbar;<BR> - select ($cfh);<BR> - }</CODE> + <DD><CODE>EXTRA_CFLAGS=-I/usr/local/bind/include + <BR> + EXTRA_LDFLAGS=-L/usr/local/bind/lib + <BR> + EXTRA_LIBS=-lbind</CODE> </DD> </DL> <P></P> - <P> - This is generally only necessary when you are calling external - programs from your script that send output to stdout, or if there will - be a long delay between the time the headers are sent and the actual - content starts being emitted. To maximize performance, you should - turn buffer-flushing back <EM>off</EM> (with <CODE>$| = 0</CODE> or the - equivalent) after the statements that send the headers, as displayed - above. - </P> + <HR> + </LI> + + <LI><A NAME="cantbuild"> + <STRONG>Why won't Apache compile with my system's + <SAMP>cc</SAMP>?</STRONG> + </A> <P> - If your script isn't written in Perl, do the equivalent thing for - whatever language you <EM>are</EM> using (<EM>e.g.</EM>, for C, call - <CODE>fflush()</CODE> after writing the headers). + If the server won't compile on your system, it is probably due to one + of the following causes: </P> + <UL> + <LI><STRONG>The <SAMP>Configure</SAMP> script doesn't recognize your system + environment.</STRONG> + <BR> + This might be either because it's completely unknown or because + the specific environment (include files, OS version, <EM>et + cetera</EM>) isn't explicitly handled. If this happens, you may + need to port the server to your OS yourself. + </LI> + <LI><STRONG>Your system's C compiler is garbage.</STRONG> + <BR> + Some operating systems include a default C compiler that is either + not ANSI C-compliant or suffers from other deficiencies. The usual + recommendation in cases like this is to acquire, install, and use + <SAMP>gcc</SAMP>. + </LI> + <LI><STRONG>Your <SAMP>include</SAMP> files may be confused.</STRONG> + <BR> + In some cases, we have found that a compiler installation or system + upgrade has left the C header files in an inconsistent state. Make + sure that your include directory tree is in sync with the compiler and + the operating system. + </LI> + <LI><STRONG>Your operating system or compiler may be out of + revision.</STRONG> + <BR> + Software vendors (including those that develop operating systems) + issue new releases for a reason; sometimes to add functionality, but + more often to fix bugs that have been discovered. Try upgrading + your compiler and/or your operating system. + </LI> + </UL> <P> - Another cause for the "premature end of script headers" - message are the RLimitCPU and RLimitMEM directives. You may - get the message if the CGI script was killed due to a - resource limit. + The Apache Group tests the ability to build the server on many + different platforms. Unfortunately, we can't test all of the OS + platforms there are. If you have verified that none of the above + issues is the cause of your problem, and it hasn't been reported + before, please submit a + <A HREF="http://www.apache.org/bug_report.html">problem report</A>. + Be sure to include <EM>complete</EM> details, such as the compiler + & OS versions and exact error messages. </P> <HR> </LI> - <LI><A NAME="ssi-part-i"> - <STRONG>How do I enable SSI (parsed HTML)?</STRONG> + <LI><A NAME="linuxiovec"> + <STRONG>Why do I get complaints about redefinition + of "<CODE>struct iovec</CODE>" when + compiling under Linux?</STRONG> </A> <P> - SSI (an acronym for Server-Side Include) directives allow static HTML - documents to be enhanced at run-time (<EM>e.g.</EM>, when delivered to - a client by Apache). The format of SSI directives is covered - in the <A HREF="../mod/mod_include.html">mod_include manual</A>; - suffice it to say that Apache supports not only SSI but - xSSI (eXtended SSI) directives. - </P> - <P> - Processing a document at run-time is called <EM>parsing</EM> it; hence - the term "parsed HTML" sometimes used for documents that - contain SSI instructions. Parsing tends to be <EM>extremely</EM> - resource-consumptive, and is not enabled by default. It can also - interfere with the cachability of your documents, which can put a - further load on your server. (see the - <A HREF="#ssi-part-ii">next question</A> for more information about this.) + This is a conflict between your C library includes and your kernel + includes. You need to make sure that the versions of both are matched + properly. There are two workarounds, either one will solve the problem: </P> <P> - To enable SSI processing, you need to - </P> <UL> - <LI>Build your server with the - <A HREF="../mod/mod_include.html"><SAMP>mod_include</SAMP></A> - module. This is normally compiled in by default. + <LI>Remove the definition of <CODE>struct iovec</CODE> from your C + library includes. It is located in <CODE>/usr/include/sys/uio.h</CODE>. + <STRONG>Or,</STRONG> </LI> - <LI>Make sure your server configuration files have an - <A HREF="../mod/core.html#options"><SAMP>Options</SAMP></A> - directive which permits <SAMP>Includes</SAMP>. + <LI>Add <CODE>-DNO_WRITEV</CODE> to the <CODE>EXTRA_CFLAGS</CODE> + line in your <SAMP>Configuration</SAMP> and reconfigure/rebuild. + This hurts performance and should only be used as a last resort. </LI> - <LI>Make sure that the directory where you want the SSI documents to - live is covered by the "server-parsed" content handler, - either explicitly or in some ancestral location. That can be done - with the following - <A HREF="../mod/mod_mime.html#addhandler"><SAMP>AddHandler</SAMP></A> - directive: + </UL> + <P></P> + <HR> + </LI> + + <LI><A NAME="broken-gcc"><STRONG>I'm using gcc and I get some + compilation errors, what is wrong?</STRONG></A> <P> - <DL> - <DD><CODE>AddHandler server-parsed .shtml</CODE> - </DD> - </DL> - <P></P> + GCC parses your system header files and produces a modified subset which + it uses for compiling. This behaviour ties GCC tightly to the version + of your operating system. So, for example, if you were running IRIX 5.3 + when you built GCC and then upgrade to IRIX 6.2 later, you will have to + rebuild GCC. Similarly for Solaris 2.4, 2.5, or 2.5.1 when you upgrade + to 2.6. Sometimes you can type "gcc -v" and it will tell you the version + of the operating system it was built against. + </P> <P> - This indicates that all files ending in ".shtml" in that - location (or its descendants) should be parsed. Note that using - ".html" will cause all normal HTML files to be parsed, - which may put an inordinate load on your server. + If you fail to do this, then it is very likely that Apache will fail + to build. One of the most common errors is with <CODE>readv</CODE>, + <CODE>writev</CODE>, or <CODE>uio.h</CODE>. This is <STRONG>not</STRONG> a + bug with Apache. You will need to re-install GCC. </P> - </LI> - </UL> + <HR> + </LI> + + <LI><A NAME="glibc-crypt"> + <STRONG>I'm using RedHat Linux 5.0, or some other + <SAMP>glibc</SAMP>-based Linux system, and I get errors with the + <CODE>crypt</CODE> function when I attempt to build Apache 1.2.</STRONG> + </A> + <P> - For additional information, see the <CITE>Apache Week</CITE> article on - <A HREF="http://www.apacheweek.com/features/ssi" REL="Help" - ><CITE>Using Server Side Includes</CITE></A>. + <SAMP>glibc</SAMP> puts the <CODE>crypt</CODE> function into a separate + library. Edit your <CODE>src/Configuration</CODE> file and set this: </P> + <DL> + <DD><CODE>EXTRA_LIBS=-lcrypt</CODE> + </DD> + </DL> + <P> + Then re-run <SAMP>src/Configure</SAMP> and re-execute the make. + </P> <HR> </LI> - <LI><A NAME="ssi-part-ii"> - <STRONG>Why don't my parsed files get cached?</STRONG> +</OL> + + + <H3>D. Error Log Messages and Problems Starting Apache</H3> +<OL> + + <LI><A NAME="setgid"> + <STRONG>Why do I get "<SAMP>setgid: Invalid + argument</SAMP>" at startup?</STRONG> </A> <P> - Since the server is performing run-time processing of your SSI - directives, which may change the content shipped to the client, it - can't know at the time it starts parsing what the final size of the - result will be, or whether the parsed result will always be the same. - This means that it can't generate <SAMP>Content-Length</SAMP> or - <SAMP>Last-Modified</SAMP> headers. Caches commonly work by comparing - the <SAMP>Last-Modified</SAMP> of what's in the cache with that being - delivered by the server. Since the server isn't sending that header - for a parsed document, whatever's doing the caching can't tell whether - the document has changed or not - and so fetches it again to be on the - safe side. + Your + <A HREF="../mod/core.html#group"><SAMP>Group</SAMP></A> + directive (probably in <SAMP>conf/httpd.conf</SAMP>) needs to name a + group that actually exists in the <SAMP>/etc/group</SAMP> file (or + your system's equivalent). </P> + <HR> + </LI> + + <LI><A NAME="nodelay"> + <STRONG>Why am I getting "<SAMP>httpd: could not set socket + option TCP_NODELAY</SAMP>" in my error log?</STRONG> + </A> <P> - You can work around this in some cases by causing an - <SAMP>Expires</SAMP> header to be generated. (See the - <A HREF="../mod/mod_expires.html" REL="Help"><SAMP>mod_expires</SAMP></A> - documentation for more details.) Another possibility is to use the - <A HREF="../mod/mod_include.html#xbithack" REL="Help" - ><SAMP>XBitHack Full</SAMP></A> - mechanism, which tells Apache to send (under certain circumstances - detailed in the XBitHack directive description) a - <SAMP>Last-Modified</SAMP> header based upon the last modification - time of the file being parsed. Note that this may actually be lying - to the client if the parsed file doesn't change but the SSI-inserted - content does; if the included content changes often, this can result - in stale copies being cached. + This message almost always indicates that the client disconnected + before Apache reached the point of calling <CODE>setsockopt()</CODE> + for the connection. It shouldn't occur for more than about 1% of the + requests your server handles, and it's advisory only in any case. + </P> + <HR> + </LI> + + <LI><A NAME="peerreset"> + <STRONG>Why am I getting "<SAMP>connection reset by + peer</SAMP>" in my error log?</STRONG> + </A> + <P> + This is a normal message and nothing about which to be alarmed. It simply + means that the client canceled the connection before it had been + completely set up - such as by the end-user pressing the "Stop" + button. People's patience being what it is, sites with response-time + problems or slow network links may experiences this more than + high-capacity ones or those with large pipes to the network. + </P> + <HR> + </LI> + + <LI><A NAME="wheres-the-dump"> + <STRONG>The errorlog says Apache dumped core, but where's the dump + file?</STRONG> + </A> + <P> + In Apache version 1.2, the error log message + about dumped core includes the directory where the dump file should be + located. However, many Unixes do not allow a process that has + called <CODE>setuid()</CODE> to dump core for security reasons; + the typical Apache setup has the server started as root to bind to + port 80, after which it changes UIDs to a non-privileged user to + serve requests. + </P> + <P> + Dealing with this is extremely operating system-specific, and may + require rebuilding your system kernel. Consult your operating system + documentation or vendor for more information about whether your system + does this and how to bypass it. If there <EM>is</EM> a documented way + of bypassing it, it is recommended that you bypass it only for the + <SAMP>httpd</SAMP> server process if possible. + </P> + <P> + The canonical location for Apache's core-dump files is the + <A HREF="../mod/core.html#serverroot">ServerRoot</A> + directory. As of Apache version 1.3, the location can be set <EM>via</EM> + the + <A HREF="../mod/core.html#coredumpdirectory" + ><SAMP>CoreDumpDirectory</SAMP></A> + directive to a different directory. Make sure that this directory is + writable by the user the server runs as (as opposed to the user the server + is <EM>started</EM> as). + </P> + <HR> + </LI> + + <LI><A NAME="linux-shmget"> + <STRONG>When I run it under Linux I get "shmget: + function not found", what should I do?</STRONG> + </A> + <P> + Your kernel has been built without SysV IPC support. You will have + to rebuild the kernel with that support enabled (it's under the + "General Setup" submenu). Documentation for kernel + building is beyond the scope of this FAQ; you should consult the <A + HREF="http://www.linuxhq.com/HOWTO/Kernel-HOWTO.html" >Kernel + HOWTO</A>, or the documentation provided with your distribution, or + a <A HREF="http://www.linuxhq.com/HOWTO/META-FAQ.html" >Linux + newsgroup/mailing list</A>. As a last-resort workaround, you can + comment out the <CODE>#define USE_SHMGET_SCOREBOARD</CODE> + definition in the <SAMP>LINUX</SAMP> section of + <SAMP>src/conf.h</SAMP> and rebuild the server (prior to 1.3b4, + simply removing <CODE>#define HAVE_SHMGET</CODE> would have + sufficed). This will produce a server which is slower and less + reliable. </P> <HR> </LI> - <LI><A NAME="ssi-part-iii"> - <STRONG>How can I have my script output parsed?</STRONG> + <LI><A NAME="nfslocking"> + <STRONG>Server hangs, or fails to start, and/or error log + fills with "<SAMP>fcntl: F_SETLKW: No record locks + available</SAMP>" or similar messages</STRONG> </A> + <P> - So you want to include SSI directives in the output from your CGI - script, but can't figure out how to do it? - The short answer is "you can't." This is potentially - a security liability and, more importantly, it can not be cleanly - implemented under the current server API. The best workaround - is for your script itself to do what the SSIs would be doing. - After all, it's generating the rest of the content. + These are symptoms of a fine locking problem, which usually means that + the server is trying to use a synchronization file on an NFS filesystem. </P> <P> - This is a feature The Apache Group hopes to add in the next major - release after 1.3. + Because of its parallel-operation model, the Apache Web server needs to + provide some form of synchronization when accessing certain resources. + One of these synchronization methods involves taking out locks on a file, + which means that the filesystem whereon the lockfile resides must support + locking. In many cases this means it <EM>can't</EM> be kept on an + NFS-mounted filesystem. + </P> + <P> + To cause the Web server to work around the NFS locking limitations, include + a line such as the following in your server configuration files: + </P> + <DL> + <DD><CODE>LockFile /var/run/apache-lock</CODE> + </DD> + </DL> + <P> + The directory should not be generally writable (<EM>e.g.</EM>, don't use + <SAMP>/var/tmp</SAMP>). + See the <A HREF="../mod/core.html#lockfile"><SAMP>LockFile</SAMP></A> + documentation for more information. </P> <HR> </LI> - <LI><A NAME="ssi-part-iv"> - <STRONG>SSIs don't work for VirtualHosts and/or - user home directories.</STRONG> - </A> - <P> - This is almost always due to having some setting in your config file that - sets "Options Includes" or some other setting for your DocumentRoot - but not for other directories. If you set it inside a Directory - section, then that setting will only apply to that directory. - </P> + <LI><A NAME="aixccbug"><STRONG>Why am I getting "<SAMP>Expected + </Directory> but saw </Directory></SAMP>" when + I try to start Apache?</STRONG></A> + <P> + This is a known problem with certain versions of the AIX C compiler. + IBM are working on a solution, and the issue is being tracked by + <A HREF="http://bugs.apache.org/index/full/2312">problem report #2312</A>. + </P> + <HR> </LI> - <LI><A NAME="proxy"> - <STRONG>Does or will Apache act as a Proxy server?</STRONG> + <LI><A NAME="redhat"> + <STRONG>I'm using RedHat Linux and I have problems with httpd + dying randomly or not restarting properly</STRONG> </A> + <P> - Apache version 1.1 and above comes with a - <A HREF="../mod/mod_proxy.html">proxy module</A>. - If compiled in, this will make Apache act as a caching-proxy server. + RedHat Linux versions 4.x (and possibly earlier) RPMs contain + various nasty scripts which do not stop or restart Apache properly. + These can affect you even if you're not running the RedHat supplied + RPMs. + </P> + <P> + If you're using the default install then you're probably running + Apache 1.1.3, which is outdated. From RedHat's ftp site you can + pick up a more recent RPM for Apache 1.2.x. This will solve one of + the problems. + </P> + <P> + If you're using a custom built Apache rather than the RedHat RPMs + then you should <CODE>rpm -e apache</CODE>. In particular you want + the mildly broken <CODE>/etc/logrotate.d/apache</CODE> script to be + removed, and you want the broken <CODE>/etc/rc.d/init.d/httpd</CODE> + (or <CODE>httpd.init</CODE>) script to be removed. The latter is + actually fixed by the apache-1.2.5 RPMs but if you're building your + own Apache then you probably don't want the RedHat files. + </P> + <P> + We can't stress enough how important it is for folks, <EM>especially + vendors</EM> to follow the <A HREF="../stopping.html">stopping Apache + directions</A> given in our documentation. In RedHat's defense, + the broken scripts were necessary with Apache 1.1.x because the + Linux support in 1.1.x was very poor, and there were various race + conditions on all platforms. None of this should be necessary with + Apache 1.2 and later. </P> <HR> </LI> - <LI><A NAME="multiviews"> - <STRONG>What are "multiviews"?</STRONG> + <LI><A NAME="stopping"> + <STRONG>I upgraded from an Apache version earlier + than 1.2.0 and suddenly I have problems with Apache dying randomly + or not restarting properly</STRONG> </A> + <P> - "Multiviews" is the general name given to the Apache - server's ability to provide language-specific document variants in - response to a request. This is documented quite thoroughly in the - <A HREF="../content-negotiation.html" REL="Help">content negotiation</A> - description page. In addition, <CITE>Apache Week</CITE> carried an - article on this subject entitled - "<A HREF="http://www.apacheweek.com/features/negotiation" REL="Help" - ><CITE>Content Negotiation Explained</CITE></A>". + You should read <A HREF="#redhat">the previous note</A> about + problems with RedHat installations. It is entirely likely that your + installation has start/stop/restart scripts which were built for + an earlier version of Apache. Versions earlier than 1.2.0 had + various race conditions that made it necessary to use + <CODE>kill -9</CODE> at times to take out all the httpd servers. + But that should not be necessary any longer. You should follow + the <A HREF="../stopping.html">directions on how to stop + and restart Apache</A>. + </P> + <P>As of Apache 1.3 there is a script + <CODE>src/support/apachectl</CODE> which, after a bit of + customization, is suitable for starting, stopping, and restarting + your server. </P> <HR> </LI> +</OL> + + <H3>E. Configuration Questions</H3> +<OL> + <LI><A NAME="fdlim"> <STRONG>Why can't I run more than <<EM>n</EM>> virtual hosts?</STRONG> @@ -949,181 +1228,83 @@ </DD> </DL> <P> - Remember that you'll need to reboot your Windows 95 system in order - for the new value to take effect. - </P> - </LI> - <LI>"Don't do that" - try to run with fewer virtual hosts - </LI> - <LI>Spread your operation across multiple server processes (using - <A HREF="../mod/core.html#listen"><SAMP>Listen</SAMP></A> - for example, but see the first point) and/or ports. - </LI> - </OL> - <P> - Since this is an operating-system limitation, there's not much else - available in the way of solutions. - </P> - <P> - As of 1.2.1 we have made attempts to work around various limitations - involving running with many descriptors. - <A HREF="descriptors.html">More information is available.</A> - </P> - <HR> - </LI> - - <LI><A NAME="freebsd-setsize"> - <STRONG>Can I increase <SAMP>FD_SETSIZE</SAMP> on FreeBSD?</STRONG> - </A> - <P> - On versions of FreeBSD before 3.0, the <SAMP>FD_SETSIZE</SAMP> define - defaults to 256. This means that you will have trouble usefully using - more than 256 file descriptors in Apache. This can be increased, but - doing so can be tricky. - </P> - <P> - If you are using a version prior to 2.2, you need to recompile your - kernel with a larger <SAMP>FD_SETSIZE</SAMP>. This can be done by adding a - line such as: - </P> - <DL> - <DD><CODE>options FD_SETSIZE <EM>nnn</EM></CODE> - </DD> - </DL> - <P> - to your kernel config file. Starting at version 2.2, this is no - longer necessary. - </P> - <P> - If you are using a version of 2.1-stable from after 1997/03/10 or - 2.2 or 3.0-current from before 1997/06/28, there is a limit in - the resolver library that prevents it from using more file descriptors - than what <SAMP>FD_SETSIZE</SAMP> is set to when libc is compiled. To - increase this, you have to recompile libc with a higher - <SAMP>FD_SETSIZE</SAMP>. - </P> - <P> - In FreeBSD 3.0, the default <SAMP>FD_SETSIZE</SAMP> has been increased to - 1024 and the above limitation in the resolver library - has been removed. - </P> - <P> - After you deal with the appropriate changes above, you can increase - the setting of <SAMP>FD_SETSIZE</SAMP> at Apache compilation time - by adding "<SAMP>-DFD_SETSIZE=<EM>nnn</EM></SAMP>" to the - <SAMP>EXTRA_CFLAGS</SAMP> line in your <SAMP>Configuration</SAMP> - file. - </P> - <HR> - </LI> - - <LI><A NAME="POSTnotallowed"> - <STRONG>Why do I keep getting "Method Not Allowed" for - form POST requests?</STRONG> - </A> - <P> - This is almost always due to Apache not being configured to treat the - file you are trying to POST to as a CGI script. You can not POST - to a normal HTML file; the operation has no meaning. See the FAQ - entry on <A HREF="#CGIoutsideScriptAlias">CGIs outside ScriptAliased - directories</A> for details on how to configure Apache to treat the - file in question as a CGI. - </P> - <HR> - </LI> - - <LI><A NAME="passwdauth"> - <STRONG>Can I use my <SAMP>/etc/passwd</SAMP> file - for Web page authentication?</STRONG> - </A> - <P> - Yes, you can - but it's a <STRONG>very bad idea</STRONG>. Here are - some of the reasons: - </P> - <UL> - <LI>The Web technology provides no governors on how often or how - rapidly password (authentication failure) retries can be made. That - means that someone can hammer away at your system's - <SAMP>root</SAMP> password using the Web, using a dictionary or - similar mass attack, just as fast as the wire and your server can - handle the requests. Most operating systems these days include - attack detection (such as <EM>n</EM> failed passwords for the same - account within <EM>m</EM> seconds) and evasion (breaking the - connection, disabling the account under attack, disabling - <EM>all</EM> logins from that source, <EM>et cetera</EM>), but the - Web does not. - </LI> - <LI>An account under attack isn't notified (unless the server is - heavily modified); there's no "You have 19483 login - failures" message when the legitimate owner logs in. - </LI> - <LI>Without an exhaustive and error-prone examination of the server - logs, you can't tell whether an account has been compromised. - Detecting that an attack has occurred, or is in progress, is fairly - obvious, though - <EM>if</EM> you look at the logs. - </LI> - <LI>Web authentication passwords (at least for Basic authentication) - generally fly across the wire, and through intermediate proxy - systems, in what amounts to plain text. "O'er the net we - go/Caching all the way;/O what fun it is to surf/Giving my password - away!" - </LI> - <LI>Since HTTP is stateless, information about the authentication is - transmitted <EM>each and every time</EM> a request is made to the - server. Essentially, the client caches it after the first - successful access, and transmits it without asking for all - subsequent requests to the same server. + Remember that you'll need to reboot your Windows 95 system in order + for the new value to take effect. + </P> </LI> - <LI>It's relatively trivial for someone on your system to put up a - page that will steal the cached password from a client's cache - without them knowing. Can you say "password grabber"? + <LI>"Don't do that" - try to run with fewer virtual hosts </LI> - </UL> + <LI>Spread your operation across multiple server processes (using + <A HREF="../mod/core.html#listen"><SAMP>Listen</SAMP></A> + for example, but see the first point) and/or ports. + </LI> + </OL> <P> - If you still want to do this in light of the above disadvantages, the - method is left as an exercise for the reader. It'll void your Apache - warranty, though, and you'll lose all accumulated UNIX guru points. + Since this is an operating-system limitation, there's not much else + available in the way of solutions. </P> - <HR> - </LI> - - <LI><A NAME="errordoc401"> - <STRONG>Why doesn't my <CODE>ErrorDocument 401</CODE> work?</STRONG> - </A> <P> - You need to use it with a URL in the form - "<SAMP>/foo/bar</SAMP>" and not one with a method and - hostname such as "<SAMP>http://host/foo/bar</SAMP>". See the - <A HREF="../mod/core.html#errordocument"><SAMP>ErrorDocument</SAMP></A> - documentation for details. This was incorrectly documented in the past. + As of 1.2.1 we have made attempts to work around various limitations + involving running with many descriptors. + <A HREF="descriptors.html">More information is available.</A> </P> <HR> </LI> - <LI><A NAME="errordocssi"> - <STRONG>How can I use <CODE>ErrorDocument</CODE> - and SSI to simplify customized error messages?</STRONG> + <LI><A NAME="freebsd-setsize"> + <STRONG>Can I increase <SAMP>FD_SETSIZE</SAMP> on FreeBSD?</STRONG> </A> <P> - Have a look at <A HREF="custom_errordocs.html">this document</A>. - It shows in example form how you can a combination of XSSI and - negotiation to tailor a set of <CODE>ErrorDocument</CODE>s to your - personal taste, and returning different internationalized error - responses based on the client's native language. + On versions of FreeBSD before 3.0, the <SAMP>FD_SETSIZE</SAMP> define + defaults to 256. This means that you will have trouble usefully using + more than 256 file descriptors in Apache. This can be increased, but + doing so can be tricky. + </P> + <P> + If you are using a version prior to 2.2, you need to recompile your + kernel with a larger <SAMP>FD_SETSIZE</SAMP>. This can be done by adding a + line such as: + </P> + <DL> + <DD><CODE>options FD_SETSIZE <EM>nnn</EM></CODE> + </DD> + </DL> + <P> + to your kernel config file. Starting at version 2.2, this is no + longer necessary. + </P> + <P> + If you are using a version of 2.1-stable from after 1997/03/10 or + 2.2 or 3.0-current from before 1997/06/28, there is a limit in + the resolver library that prevents it from using more file descriptors + than what <SAMP>FD_SETSIZE</SAMP> is set to when libc is compiled. To + increase this, you have to recompile libc with a higher + <SAMP>FD_SETSIZE</SAMP>. + </P> + <P> + In FreeBSD 3.0, the default <SAMP>FD_SETSIZE</SAMP> has been increased to + 1024 and the above limitation in the resolver library + has been removed. </P> + <P> + After you deal with the appropriate changes above, you can increase + the setting of <SAMP>FD_SETSIZE</SAMP> at Apache compilation time + by adding "<SAMP>-DFD_SETSIZE=<EM>nnn</EM></SAMP>" to the + <SAMP>EXTRA_CFLAGS</SAMP> line in your <SAMP>Configuration</SAMP> + file. + </P> <HR> </LI> - <LI><A NAME="setgid"> - <STRONG>Why do I get "<SAMP>setgid: Invalid - argument</SAMP>" at startup?</STRONG> + <LI><A NAME="errordoc401"> + <STRONG>Why doesn't my <CODE>ErrorDocument 401</CODE> work?</STRONG> </A> <P> - Your - <A HREF="../mod/core.html#group"><SAMP>Group</SAMP></A> - directive (probably in <SAMP>conf/httpd.conf</SAMP>) needs to name a - group that actually exists in the <SAMP>/etc/group</SAMP> file (or - your system's equivalent). + You need to use it with a URL in the form + "<SAMP>/foo/bar</SAMP>" and not one with a method and + hostname such as "<SAMP>http://host/foo/bar</SAMP>". See the + <A HREF="../mod/core.html#errordocument"><SAMP>ErrorDocument</SAMP></A> + documentation for details. This was incorrectly documented in the past. </P> <HR> </LI> @@ -1132,7 +1313,7 @@ <STRONG>Why does Apache send a cookie on every response?</STRONG> </A> <P> - Apache does <EM>not</EM> send automatically send a cookie on every + Apache does <EM>not</EM> automatically send a cookie on every response, unless you have re-compiled it with the <A HREF="../mod/mod_usertrack.html"><SAMP>mod_usertrack</SAMP></A> module, and specifically enabled it with the @@ -1194,460 +1375,586 @@ Java virtual machine environment, and so even those that are based upon the 1.0.2 version may not have this problem. </P> + <P> + In the meantime, a workaround is to tell + Apache to "fake" an HTTP/1.0 response to requests that come + from the JDK methods; this can be done by including a line such as the + following in your server configuration files: + </P> + <P> + <DL> + <DD><CODE>BrowserMatch Java1.0 force-response-1.0 + <BR> + BrowserMatch JDK/1.0 force-response-1.0</CODE> + </DD> + </DL> + <P></P> + <P> + More information about this issue can be found in the + <A HREF="http://www.apache.org/info/jdk-102.html" + ><CITE>Java and HTTP/1.1</CITE></A> + page at the Apache web site. + </P> + <HR> + </LI> + + <LI><A NAME="midi"> + <STRONG>How do I get Apache to send a MIDI file so the browser can + play it?</STRONG> + </A> + <P> + Even though the registered MIME type for MIDI files is + <SAMP>audio/midi</SAMP>, some browsers are not set up to recognize it + as such; instead, they look for <SAMP>audio/x-midi</SAMP>. There are + two things you can do to address this: + </P> + <OL> + <LI>Configure your browser to treat documents of type + <SAMP>audio/midi</SAMP> correctly. This is the type that Apache + sends by default. This may not be workable, however, if you have + many client installations to change, or if some or many of the + clients are not under your control. + </LI> + <LI>Instruct Apache to send a different <SAMP>Content-type</SAMP> + header for these files by adding the following line to your server's + configuration files: + <P> + <DL> + <DD><CODE>AddType audio/x-midi .mid .midi .kar</CODE> + </DD> + </DL> + <P></P> + <P> + Note that this may break browsers that <EM>do</EM> recognize the + <SAMP>audio/midi</SAMP> MIME type unless they're prepared to also + handle <SAMP>audio/x-midi</SAMP> the same way. + </P> + </LI> + </OL> + <HR> + </LI> + + <LI><A NAME="addlog"> + <STRONG>How do I add browsers and referrers to my logs?</STRONG> + </A> + <P> + Apache provides a couple of different ways of doing this. The + recommended method is to compile the + <A HREF="../mod/mod_log_config.html"><SAMP>mod_log_config</SAMP></A> + module into your configuration and use the + <A HREF="../mod/mod_log_config.html#customlog"><SAMP>CustomLog</SAMP></A> + directive. + </P> + <P> + You can either log the additional information in files other than your + normal transfer log, or you can add them to the records already being + written. For example: + </P> + <P> + <CODE> + CustomLog logs/access_log "%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\"" + </CODE> + </P> + <P> + This will add the values of the <SAMP>User-agent:</SAMP> and + <SAMP>Referer:</SAMP> headers, which indicate the client and the + referring page, respectively, to the end of each line in the access + log. + </P> + <P> + You may want to check out the <CITE>Apache Week</CITE> article + entitled: + "<A HREF="http://www.apacheweek.com/features/logfiles" REL="Help" + ><CITE>Gathering Visitor Information: Customizing Your + Logfiles</CITE></A>". + </P> + <HR> + </LI> + + <LI><A NAME="set-servername"> + <STRONG>Why does accessing directories only work when I include + the trailing "/" + (<EM>e.g.</EM>, <SAMP>http://foo.domain.com/~user/</SAMP>) + but not when I omit it + (<EM>e.g.</EM>, <SAMP>http://foo.domain.com/~user</SAMP>)?</STRONG> + </A> + <P> + When you access a directory without a trailing "/", Apache needs + to send what is called a redirect to the client to tell it to + add the trailing slash. If it did not do so, relative URLs would + not work properly. When it sends the redirect, it needs to know + the name of the server so that it can include it in the redirect. + There are two ways for Apache to find this out; either it can guess, + or you can tell it. If your DNS is configured correctly, it can + normally guess without any problems. If it is not, however, then + you need to tell it. + </P> + <P> + Add a <A HREF="../mod/core.html#servername">ServerName</A> directive + to the config file to tell it what the domain name of the server is. + </P> + <HR> + </LI> + + <LI><A NAME="no-info-directives"> + <STRONG>Why doesn't mod_info list any directives?</STRONG> + </A> + <P> + The <A HREF="../mod/mod_info.html"><SAMP>mod_info</SAMP></A> + module allows you to use a Web browser to see how your server is + configured. Among the information it displays is the list modules and + their configuration directives. The "current" values for + the directives are not necessarily those of the running server; they + are extracted from the configuration files themselves at the time of + the request. If the files have been changed since the server was last + reloaded, the display will will not match the values actively in use. + If the files and the path to the files are not readable by the user as + which the server is running (see the + <A HREF="../mod/core.html#user"><SAMP>User</SAMP></A> + directive), then <SAMP>mod_info</SAMP> cannot read them in order to + list their values. An entry <EM>will</EM> be made in the error log in + this event, however. + </P> + <HR> + </LI> + + <LI><A NAME="namevhost"> + <STRONG>I upgraded to Apache 1.3 and now my virtual hosts don't + work!</STRONG> + </A> + <P> + In versions of Apache prior to 1.3b2, there was a lot of confusion + regarding address-based virtual hosts and (HTTP/1.1) name-based + virtual hosts, and the rules concerning how the server processed + <SAMP><VirtualHost></SAMP> definitions were very complex and not + well documented. + </P> + <P> + Apache 1.3b2 introduced a new directive, + <A HREF="http://www.apache.org/docs/mod/core.html#namevirtualhost" + ><SAMP>NameVirtualHost</SAMP></A>, + which simplifies the rules quite a bit. However, changing the rules + like this means that your existing name-based + <SAMP><VirtualHost></SAMP> containers probably won't work + correctly immediately following the upgrade. + </P> <P> - In the meantime, a workaround is to tell - Apache to "fake" an HTTP/1.0 response to requests that come - from the JDK methods; this can be done by including a line such as the - following in your server configuration files: + To correct this problem, add the following line to the beginning of + your server configuration file, before defining any virtual hosts: </P> - <P> <DL> - <DD><CODE>BrowserMatch Java1.0 force-response-1.0 - <BR> - BrowserMatch JDK/1.0 force-response-1.0</CODE> + <DD><CODE>NameVirtualHost <EM>n.n.n.n</EM></CODE> </DD> </DL> - <P></P> <P> - More information about this issue can be found in the - <A HREF="http://www.apache.org/info/jdk-102.html" - ><CITE>Java and HTTP/1.1</CITE></A> - page at the Apache web site. + Replace the "<SAMP>n.n.n.n</SAMP>" with the IP address to + which the name-based virtual host names resolve; if you have multiple + name-based hosts on multiple addresses, repeat the directive for each + address. </P> - <HR> - </LI> - - <LI><A NAME="putsupport"> - <STRONG>Why can't I publish to my Apache server using PUT on - Netscape Gold and other programs?</STRONG> - </A> <P> - Because you need to install and configure a script to handle - the uploaded files. This script is often called a "PUT" handler. - There are several available, but they may have security problems. - Using FTP uploads may be easier and more secure, at least for now. - For more information, see the <CITE>Apache Week</CITE> article - <A HREF="http://www.apacheweek.com/features/put" - ><CITE>Publishing Pages with PUT</CITE></A>. + Make sure that your name-based <SAMP><VirtualHost></SAMP> blocks + contain <SAMP>ServerName</SAMP> and possibly <SAMP>ServerAlias</SAMP> + directives so Apache can be sure to tell them apart correctly. + </P> + <P> + Please see the + <A HREF="http://www.apache.org/docs/vhosts/">Apache + Virtual Host documentation</A> for further details about configuration. </P> <HR> </LI> - <LI><A NAME="fastcgi"> - <STRONG>Why isn't FastCGI included with Apache any more?</STRONG> + <LI><A NAME="redhat-htm"> + <STRONG>I'm using RedHat Linux and my .htm files are showing + up as HTML source rather than being formatted!</STRONG> </A> + <P> - The simple answer is that it was becoming too difficult to keep the - version being included with Apache synchronized with the master copy - at the - <A HREF="http://www.fastcgi.com/" - >FastCGI web site</A>. When a new version of Apache was released, the - version of the FastCGI module included with it would soon be out of date. + RedHat messed up and forgot to put a content type for <CODE>.htm</CODE> + files into <CODE>/etc/mime.types</CODE>. Edit <CODE>/etc/mime.types</CODE>, + find the line containing <CODE>html</CODE> and add <CODE>htm</CODE> to it. + Then restart your httpd server: </P> + <DL> + <DD><CODE>kill -HUP `cat /var/run/httpd.pid`</CODE> + </DD> + </DL> <P> - You can still obtain the FastCGI module for Apache from the master - FastCGI web site. + Then <STRONG>clear your browsers' caches</STRONG>. (Many browsers won't + re-examine the content type after they've reloaded a page.) </P> <HR> </LI> - <LI><A NAME="nodelay"> - <STRONG>Why am I getting "<SAMP>httpd: could not set socket - option TCP_NODELAY</SAMP>" in my error log?</STRONG> - </A> - <P> - This message almost always indicates that the client disconnected - before Apache reached the point of calling <CODE>setsockopt()</CODE> - for the connection. It shouldn't occur for more than about 1% of the - requests your server handles, and it's advisory only in any case. - </P> - <HR> + <LI><A NAME="htaccess-work"> + <STRONG>My <CODE>.htaccess</CODE> files are being ignored.</STRONG></A> + <P> + This is almost always due to your <A HREF="../mod/core.html#allowoverride"> + AllowOverride</A> directive being set incorrectly for the directory in + question. If it is set to <CODE>None</CODE> then .htaccess files will + not even be looked for. If you do have one that is set, then be certain + it covers the directory you are trying to use the .htaccess file in. + This is normally accomplished by ensuring it is inside the proper + <A HREF="../mod/core.html#directory">Directory</A> container. + </P> + <HR> </LI> +</OL> - <LI><A NAME="peerreset"> - <STRONG>Why am I getting "<SAMP>connection reset by - peer</SAMP>" in my error log?</STRONG> - </A> - <P> - This is a normal message and nothing about which to be alarmed. It simply - means that the client canceled the connection before it had been - completely set up - such as by the end-user pressing the "Stop" - button. People's patience being what it is, sites with response-time - problems or slow network links may experiences this more than - high-capacity ones or those with large pipes to the network. - </P> - <HR> - </LI> + <H3>F. Dynamic Content (CGI and SSI)</H3> +<OL> - <LI><A NAME="nph-scripts"> - <STRONG>How can I get my script's output without Apache buffering - it? Why doesn't my server push work?</STRONG> + <LI><A NAME="CGIoutsideScriptAlias"> + <STRONG>How do I enable CGI execution in directories other than + the ScriptAlias?</STRONG> </A> <P> - As of Apache 1.3, CGI scripts are essentially not buffered. Every time - your script does a "flush" to output data, that data gets relayed on to - the client. Some scripting languages, for example Perl, have their own - buffering for output - this can be disabled by setting the <CODE>$|</CODE> - special variable to 1. Of course this does increase the overall number - of packets being transmitted, which can result in a sense of slowness for - the end user. + Apache recognizes all files in a directory named as a + <A HREF="../mod/mod_alias.html#scriptalias"><SAMP>ScriptAlias</SAMP></A> + as being eligible for execution rather than processing as normal + documents. This applies regardless of the file name, so scripts in a + ScriptAlias directory don't need to be named + "<SAMP>*.cgi</SAMP>" or "<SAMP>*.pl</SAMP>" or + whatever. In other words, <EM>all</EM> files in a ScriptAlias + directory are scripts, as far as Apache is concerned. </P> - <P>Prior to 1.3, you needed to use "nph-" scripts to accomplish non-buffering. - Today, the only difference between nph scripts and normal scripts is - that nph scripts require the full HTTP headers to be sent. + <P> + To persuade Apache to execute scripts in other locations, such as in + directories where normal documents may also live, you must tell it how + to recognize them - and also that it's okay to execute them. For + this, you need to use something like the + <A HREF="../mod/mod_mime.html#addhandler"><SAMP>AddHandler</SAMP></A> + directive. </P> - <HR> - </LI> - - <LI><A NAME="linuxiovec"> - <STRONG>Why do I get complaints about redefinition - of "<CODE>struct iovec</CODE>" when - compiling under Linux?</STRONG> - </A> <P> - This is a conflict between your C library includes and your kernel - includes. You need to make sure that the versions of both are matched - properly. There are two workarounds, either one will solve the problem: + <OL> + <LI>In an appropriate section of your server configuration files, add + a line such as + <P> + <DL> + <DD><CODE>AddHandler cgi-script .cgi</CODE> + </DD> + </DL> + <P></P> + <P> + The server will then recognize that all files in that location (and + its logical descendants) that end in "<SAMP>.cgi</SAMP>" + are script files, not documents. + </P> + </LI> + <LI>Make sure that the directory location is covered by an + <A HREF="../mod/core.html#options"><SAMP>Options</SAMP></A> + declaration that includes the <SAMP>ExecCGI</SAMP> option. + </LI> + </OL> + <P></P> + <P> + In some situations, you might not want to actually + allow all files named "<SAMP>*.cgi</SAMP>" to be executable. + Perhaps all you want is to enable a particular file in a normal directory to + be executable. This can be alternatively accomplished + <EM>via</EM> <A HREF="../mod/mod_rewrite.html"><SAMP>mod_rewrite</SAMP></A> + and the following steps: </P> <P> - <UL> - <LI>Remove the definition of <CODE>struct iovec</CODE> from your C - library includes. It is located in <CODE>/usr/include/sys/uio.h</CODE>. - <STRONG>Or,</STRONG> + <OL> + <LI>Locally add to the corresponding <SAMP>.htaccess</SAMP> file a ruleset + similar to this one: + <P> + <DL> + <DD><CODE>RewriteEngine on + <BR> + RewriteBase /~foo/bar/ + <BR> + RewriteRule ^quux\.cgi$ - [T=application/x-httpd-cgi]</CODE> + </DD> + </DL> + <P></P> </LI> - <LI>Add <CODE>-DNO_WRITEV</CODE> to the <CODE>EXTRA_CFLAGS</CODE> - line in your <SAMP>Configuration</SAMP> and reconfigure/rebuild. - This hurts performance and should only be used as a last resort. + <LI>Make sure that the directory location is covered by an + <A HREF="../mod/core.html#options"><SAMP>Options</SAMP></A> + declaration that includes the <SAMP>ExecCGI</SAMP> and + <SAMP>FollowSymLinks</SAMP> option. </LI> - </UL> + </OL> <P></P> <HR> </LI> - <LI><A NAME="wheres-the-dump"> - <STRONG>The errorlog says Apache dumped core, but where's the dump - file?</STRONG> + <LI><A NAME="premature-script-headers"> + <STRONG>What does it mean when my CGIs fail with + "<SAMP>Premature end of script headers</SAMP>"?</STRONG> </A> <P> - In Apache version 1.2, the error log message - about dumped core includes the directory where the dump file should be - located. However, many Unixes do not allow a process that has - called <CODE>setuid()</CODE> to dump core for security reasons; - the typical Apache setup has the server started as root to bind to - port 80, after which it changes UIDs to a non-privileged user to - serve requests. + It means just what it says: the server was expecting a complete set of + HTTP headers (one or more followed by a blank line), and didn't get + them. </P> <P> - Dealing with this is extremely operating system-specific, and may - require rebuilding your system kernel. Consult your operating system - documentation or vendor for more information about whether your system - does this and how to bypass it. If there <EM>is</EM> a documented way - of bypassing it, it is recommended that you bypass it only for the - <SAMP>httpd</SAMP> server process if possible. + The most common cause of this problem is the script dying before + sending the complete set of headers, or possibly any at all, to the + server. To see if this is the case, try running the script standalone + from an interactive session, rather than as a script under the server. + If you get error messages, this is almost certainly the cause of the + "premature end of script headers" message. + </P> + <P> + The second most common cause of this (aside from people not + outputting the required headers at all) is a result of an interaction + with Perl's output buffering. To make Perl flush its buffers + after each output statement, insert the following statements around + the <CODE>print</CODE> or <CODE>write</CODE> statements that send your + HTTP headers: + </P> + <P> + <DL> + <DD><CODE>{<BR> + local ($oldbar) = $|;<BR> + $cfh = select (STDOUT);<BR> + $| = 1;<BR> + #<BR> + # print your HTTP headers here<BR> + #<BR> + $| = $oldbar;<BR> + select ($cfh);<BR> + }</CODE> + </DD> + </DL> + <P></P> + <P> + This is generally only necessary when you are calling external + programs from your script that send output to stdout, or if there will + be a long delay between the time the headers are sent and the actual + content starts being emitted. To maximize performance, you should + turn buffer-flushing back <EM>off</EM> (with <CODE>$| = 0</CODE> or the + equivalent) after the statements that send the headers, as displayed + above. </P> <P> - The canonical location for Apache's core-dump files is the - <A HREF="../mod/core.html#serverroot">ServerRoot</A> - directory. As of Apache version 1.3, the location can be set <EM>via</EM> - the - <A HREF="../mod/core.html#coredumpdirectory" - ><SAMP>CoreDumpDirectory</SAMP></A> - directive to a different directory. Make sure that this directory is - writable by the user the server runs as (as opposed to the user the server - is <EM>started</EM> as). + If your script isn't written in Perl, do the equivalent thing for + whatever language you <EM>are</EM> using (<EM>e.g.</EM>, for C, call + <CODE>fflush()</CODE> after writing the headers). + </P> + <P> + Another cause for the "premature end of script headers" + message are the RLimitCPU and RLimitMEM directives. You may + get the message if the CGI script was killed due to a + resource limit. </P> <HR> </LI> - <LI><A NAME="dnsauth"> - <STRONG>Why isn't restricting access by host or domain name - working correctly?</STRONG> + <LI><A NAME="POSTnotallowed"> + <STRONG>Why do I keep getting "Method Not Allowed" for + form POST requests?</STRONG> </A> <P> - Two of the most common causes of this are: + This is almost always due to Apache not being configured to treat the + file you are trying to POST to as a CGI script. You can not POST + to a normal HTML file; the operation has no meaning. See the FAQ + entry on <A HREF="#CGIoutsideScriptAlias">CGIs outside ScriptAliased + directories</A> for details on how to configure Apache to treat the + file in question as a CGI. </P> - <OL> - <LI><STRONG>An error, inconsistency, or unexpected mapping in the DNS - registration</STRONG> - <BR> - This happens frequently: your configuration restricts access to - <SAMP>Host.FooBar.Com</SAMP>, but you can't get in from that host. - The usual reason for this is that <SAMP>Host.FooBar.Com</SAMP> is - actually an alias for another name, and when Apache performs the - address-to-name lookup it's getting the <EM>real</EM> name, not - <SAMP>Host.FooBar.Com</SAMP>. You can verify this by checking the - reverse lookup yourself. The easiest way to work around it is to - specify the correct host name in your configuration. - </LI> - <LI><STRONG>Inadequate checking and verification in your - configuration of Apache</STRONG> - <BR> - If you intend to perform access checking and restriction based upon - the client's host or domain name, you really need to configure - Apache to double-check the origin information it's supplied. You do - this by adding the <SAMP>-DMAXIMUM_DNS</SAMP> clause to the - <SAMP>EXTRA_CFLAGS</SAMP> definition in your - <SAMP>Configuration</SAMP> file. For example: - <P> - <DL> - <DD><CODE>EXTRA_CFLAGS=-DMAXIMUM_DNS</CODE> - </DD> - </DL> - <P></P> - <P> - This will cause Apache to be very paranoid about making sure a - particular host address is <EM>really</EM> assigned to the name it - claims to be. Note that this <EM>can</EM> incur a significant - performance penalty, however, because of all the name resolution - requests being sent to a nameserver. - </P> - </LI> - </OL> <HR> </LI> - <LI><A NAME="SSL-i"> - <STRONG>Why doesn't Apache include SSL?</STRONG> + <LI><A NAME="nph-scripts"> + <STRONG>How can I get my script's output without Apache buffering + it? Why doesn't my server push work?</STRONG> </A> - <P> - SSL (Secure Socket Layer) data transport requires encryption, and many - governments have restrictions upon the import, export, and use of - encryption technology. If Apache included SSL in the base package, - its distribution would involve all sorts of legal and bureaucratic - issues, and it would no longer be freely available. Also, some of - the technology required to talk to current clients using SSL is - patented by <A HREF="http://www.rsa.com/">RSA Data Security</A>, - who restricts its use without a license. - </P> <P> - Some SSL implementations of Apache are available, however; see the - "<A HREF="http://www.apache.org/related_projects.html" - >related projects</A>" - page at the main Apache web site. + As of Apache 1.3, CGI scripts are essentially not buffered. Every time + your script does a "flush" to output data, that data gets relayed on to + the client. Some scripting languages, for example Perl, have their own + buffering for output - this can be disabled by setting the <CODE>$|</CODE> + special variable to 1. Of course this does increase the overall number + of packets being transmitted, which can result in a sense of slowness for + the end user. </P> - <P> - You can find out more about this topic in the <CITE>Apache Week</CITE> - article about - <A HREF="http://www.apacheweek.com/features/ssl" REL="Help" - ><CITE>Apache and Secure Transactions</CITE></A>. + <P>Prior to 1.3, you needed to use "nph-" scripts to accomplish + non-buffering. Today, the only difference between nph scripts and + normal scripts is that nph scripts require the full HTTP headers to + be sent. </P> <HR> </LI> - <LI><A NAME="midi"> - <STRONG>How do I get Apache to send a MIDI file so the browser can - play it?</STRONG> + <LI><A NAME="cgi-spec"> + <STRONG>Where can I find the "CGI specification"?</STRONG> </A> <P> - Even though the registered MIME type for MIDI files is - <SAMP>audio/midi</SAMP>, some browsers are not set up to recognize it - as such; instead, they look for <SAMP>audio/x-midi</SAMP>. There are - two things you can do to address this: + The Common Gateway Interface (CGI) specification can be found at + the original NCSA site + <<A HREF="http://hoohoo.ncsa.uiuc.edu/cgi/interface.html"> + <SAMP>http://hoohoo.ncsa.uiuc.edu/cgi/interface.html</SAMP></A>>. + This version hasn't been updated since 1995, and there have been + some efforts to update it. </P> - <OL> - <LI>Configure your browser to treat documents of type - <SAMP>audio/midi</SAMP> correctly. This is the type that Apache - sends by default. This may not be workable, however, if you have - many client installations to change, or if some or many of the - clients are not under your control. - </LI> - <LI>Instruct Apache to send a different <SAMP>Content-type</SAMP> - header for these files by adding the following line to your server's - configuration files: - <P> - <DL> - <DD><CODE>AddType audio/x-midi .mid .midi .kar</CODE> - </DD> - </DL> - <P></P> - <P> - Note that this may break browsers that <EM>do</EM> recognize the - <SAMP>audio/midi</SAMP> MIME type unless they're prepared to also - handle <SAMP>audio/x-midi</SAMP> the same way. - </P> - </LI> - </OL> + <P> + A new draft is being worked on with the intent of making it an informational + RFC; you can find out more about this project at + <<A HREF="http://web.golux.com/coar/cgi/" + ><SAMP>http://web.golux.com/coar/cgi/</SAMP></A>>. + </P> <HR> </LI> - <LI><A NAME="cantbuild"> - <STRONG>Why won't Apache compile with my system's - <SAMP>cc</SAMP>?</STRONG> + <LI><A NAME="fastcgi"> + <STRONG>Why isn't FastCGI included with Apache any more?</STRONG> </A> <P> - If the server won't compile on your system, it is probably due to one - of the following causes: + The simple answer is that it was becoming too difficult to keep the + version being included with Apache synchronized with the master copy + at the + <A HREF="http://www.fastcgi.com/" + >FastCGI web site</A>. When a new version of Apache was released, the + version of the FastCGI module included with it would soon be out of date. </P> - <UL> - <LI><STRONG>The <SAMP>Configure</SAMP> script doesn't recognize your system - environment.</STRONG> - <BR> - This might be either because it's completely unknown or because - the specific environment (include files, OS version, <EM>et - cetera</EM>) isn't explicitly handled. If this happens, you may - need to port the server to your OS yourself. - </LI> - <LI><STRONG>Your system's C compiler is garbage.</STRONG> - <BR> - Some operating systems include a default C compiler that is either - not ANSI C-compliant or suffers from other deficiencies. The usual - recommendation in cases like this is to acquire, install, and use - <SAMP>gcc</SAMP>. - </LI> - <LI><STRONG>Your <SAMP>include</SAMP> files may be confused.</STRONG> - <BR> - In some cases, we have found that a compiler installation or system - upgrade has left the C header files in an inconsistent state. Make - sure that your include directory tree is in sync with the compiler and - the operating system. - </LI> - <LI><STRONG>Your operating system or compiler may be out of - revision.</STRONG> - <BR> - Software vendors (including those that develop operating systems) - issue new releases for a reason; sometimes to add functionality, but - more often to fix bugs that have been discovered. Try upgrading - your compiler and/or your operating system. - </LI> - </UL> <P> - The Apache Group tests the ability to build the server on many - different platforms. Unfortunately, we can't test all of the OS - platforms there are. If you have verified that none of the above - issues is the cause of your problem, and it hasn't been reported - before, please submit a - <A HREF="http://www.apache.org/bug_report.html">problem report</A>. - Be sure to include <EM>complete</EM> details, such as the compiler - & OS versions and exact error messages. + You can still obtain the FastCGI module for Apache from the master + FastCGI web site. </P> <HR> </LI> - <LI><A NAME="addlog"> - <STRONG>How do I add browsers and referrers to my logs?</STRONG> + <LI><A NAME="ssi-part-i"> + <STRONG>How do I enable SSI (parsed HTML)?</STRONG> </A> - <P> - Apache provides a couple of different ways of doing this. The - recommended method is to compile the - <A HREF="../mod/mod_log_config.html"><SAMP>mod_log_config</SAMP></A> - module into your configuration and use the - <A HREF="../mod/mod_log_config.html#customlog"><SAMP>CustomLog</SAMP></A> - directive. - </P> <P> - You can either log the additional information in files other than your - normal transfer log, or you can add them to the records already being - written. For example: + SSI (an acronym for Server-Side Include) directives allow static HTML + documents to be enhanced at run-time (<EM>e.g.</EM>, when delivered to + a client by Apache). The format of SSI directives is covered + in the <A HREF="../mod/mod_include.html">mod_include manual</A>; + suffice it to say that Apache supports not only SSI but + xSSI (eXtended SSI) directives. </P> <P> - <CODE> - CustomLog logs/access_log "%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\"" - </CODE> + Processing a document at run-time is called <EM>parsing</EM> it; hence + the term "parsed HTML" sometimes used for documents that + contain SSI instructions. Parsing tends to be <EM>extremely</EM> + resource-consumptive, and is not enabled by default. It can also + interfere with the cachability of your documents, which can put a + further load on your server. (see the + <A HREF="#ssi-part-ii">next question</A> for more information about this.) </P> <P> - This will add the values of the <SAMP>User-agent:</SAMP> and - <SAMP>Referer:</SAMP> headers, which indicate the client and the - referring page, respectively, to the end of each line in the access - log. + To enable SSI processing, you need to </P> + <UL> + <LI>Build your server with the + <A HREF="../mod/mod_include.html"><SAMP>mod_include</SAMP></A> + module. This is normally compiled in by default. + </LI> + <LI>Make sure your server configuration files have an + <A HREF="../mod/core.html#options"><SAMP>Options</SAMP></A> + directive which permits <SAMP>Includes</SAMP>. + </LI> + <LI>Make sure that the directory where you want the SSI documents to + live is covered by the "server-parsed" content handler, + either explicitly or in some ancestral location. That can be done + with the following + <A HREF="../mod/mod_mime.html#addhandler"><SAMP>AddHandler</SAMP></A> + directive: + <P> + <DL> + <DD><CODE>AddHandler server-parsed .shtml</CODE> + </DD> + </DL> + <P></P> + <P> + This indicates that all files ending in ".shtml" in that + location (or its descendants) should be parsed. Note that using + ".html" will cause all normal HTML files to be parsed, + which may put an inordinate load on your server. + </P> + </LI> + </UL> <P> - You may want to check out the <CITE>Apache Week</CITE> article - entitled: - "<A HREF="http://www.apacheweek.com/features/logfiles" REL="Help" - ><CITE>Gathering Visitor Information: Customising Your - Logfiles</CITE></A>". + For additional information, see the <CITE>Apache Week</CITE> article on + <A HREF="http://www.apacheweek.com/features/ssi" REL="Help" + ><CITE>Using Server Side Includes</CITE></A>. </P> <HR> </LI> - <LI><A NAME="bind8.1"> - <STRONG>Why do I get an error about an undefined reference to - "<SAMP>__inet_ntoa</SAMP>" or other - <SAMP>__inet_*</SAMP> symbols?</STRONG> + <LI><A NAME="ssi-part-ii"> + <STRONG>Why don't my parsed files get cached?</STRONG> </A> - <P> - If you have installed <A HREF="http://www.isc.org/bind.html">BIND-8</A> - then this is normally due to a conflict between your include files - and your libraries. BIND-8 installs its include files and libraries - <CODE>/usr/local/include/</CODE> and <CODE>/usr/local/lib/</CODE>, while - the resolver that comes with your system is probably installed in - <CODE>/usr/include/</CODE> and <CODE>/usr/lib/</CODE>. If - your system uses the header files in <CODE>/usr/local/include/</CODE> - before those in <CODE>/usr/include/</CODE> but you do not use the new - resolver library, then the two versions will conflict. - </P> <P> - To resolve this, you can either make sure you use the include files - and libraries that came with your system or make sure to use the - new include files and libraries. Adding <CODE>-lbind</CODE> to the - <CODE>EXTRA_LDFLAGS</CODE> line in your <SAMP>Configuration</SAMP> - file, then re-running <SAMP>Configure</SAMP>, should resolve the - problem. (Apache versions 1.2.* and earlier use - <CODE>EXTRA_LFLAGS</CODE> instead.) + Since the server is performing run-time processing of your SSI + directives, which may change the content shipped to the client, it + can't know at the time it starts parsing what the final size of the + result will be, or whether the parsed result will always be the same. + This means that it can't generate <SAMP>Content-Length</SAMP> or + <SAMP>Last-Modified</SAMP> headers. Caches commonly work by comparing + the <SAMP>Last-Modified</SAMP> of what's in the cache with that being + delivered by the server. Since the server isn't sending that header + for a parsed document, whatever's doing the caching can't tell whether + the document has changed or not - and so fetches it again to be on the + safe side. </P> <P> - <STRONG>Note:</STRONG>As of BIND 8.1.1, the bind libraries and files are - installed under <SAMP>/usr/local/bind</SAMP> by default, so you - should not run into this problem. Should you want to use the bind - resolvers you'll have to add the following to the respective lines: + You can work around this in some cases by causing an + <SAMP>Expires</SAMP> header to be generated. (See the + <A HREF="../mod/mod_expires.html" REL="Help"><SAMP>mod_expires</SAMP></A> + documentation for more details.) Another possibility is to use the + <A HREF="../mod/mod_include.html#xbithack" REL="Help" + ><SAMP>XBitHack Full</SAMP></A> + mechanism, which tells Apache to send (under certain circumstances + detailed in the XBitHack directive description) a + <SAMP>Last-Modified</SAMP> header based upon the last modification + time of the file being parsed. Note that this may actually be lying + to the client if the parsed file doesn't change but the SSI-inserted + content does; if the included content changes often, this can result + in stale copies being cached. </P> - <P> - <DL> - <DD><CODE>EXTRA_CFLAGS=-I/usr/local/bind/include - <BR> - EXTRA_LDFLAGS=-L/usr/local/bind/lib - <BR> - EXTRA_LIBS=-lbind</CODE> - </DD> - </DL> - <P></P> <HR> </LI> - <LI><A NAME="set-servername"> - <STRONG>Why does accessing directories only work when I include - the trailing "/" - (<EM>e.g.</EM>, <SAMP>http://foo.domain.com/~user/</SAMP>) - but not when I omit it - (<EM>e.g.</EM>, <SAMP>http://foo.domain.com/~user</SAMP>)?</STRONG> + <LI><A NAME="ssi-part-iii"> + <STRONG>How can I have my script output parsed?</STRONG> </A> <P> - When you access a directory without a trailing "/", Apache needs - to send what is called a redirect to the client to tell it to - add the trailing slash. If it did not do so, relative URLs would - not work properly. When it sends the redirect, it needs to know - the name of the server so that it can include it in the redirect. - There are two ways for Apache to find this out; either it can guess, - or you can tell it. If your DNS is configured correctly, it can - normally guess without any problems. If it is not, however, then - you need to tell it. + So you want to include SSI directives in the output from your CGI + script, but can't figure out how to do it? + The short answer is "you can't." This is potentially + a security liability and, more importantly, it can not be cleanly + implemented under the current server API. The best workaround + is for your script itself to do what the SSIs would be doing. + After all, it's generating the rest of the content. </P> <P> - Add a <A HREF="../mod/core.html#servername">ServerName</A> directive - to the config file to tell it what the domain name of the server is. + This is a feature The Apache Group hopes to add in the next major + release after 1.3. </P> <HR> </LI> - <LI><A NAME="user-authentication"> - <STRONG>How do I set up Apache to require a username and - password to access certain documents?</STRONG> + <LI><A NAME="ssi-part-iv"> + <STRONG>SSIs don't work for VirtualHosts and/or + user home directories.</STRONG> </A> <P> - There are several ways to do this; some of the more popular - ones are to use the <A HREF="../mod/mod_auth.html">mod_auth</A>, - <A HREF="../mod/mod_auth_db.html">mod_auth_db</A>, or - <A HREF="../mod/mod_auth_dbm.html">mod_auth_dbm</A> modules. + This is almost always due to having some setting in your config file that + sets "Options Includes" or some other setting for your DocumentRoot + but not for other directories. If you set it inside a Directory + section, then that setting will only apply to that directory. </P> + <HR> + </LI> + + <LI><A NAME="errordocssi"> + <STRONG>How can I use <CODE>ErrorDocument</CODE> + and SSI to simplify customized error messages?</STRONG> + </A> <P> - For an explanation on how to implement these restrictions, see - <A HREF="http://www.apacheweek.com/"><CITE>Apache Week</CITE></A>'s - articles on - <A HREF="http://www.apacheweek.com/features/userauth" - ><CITE>Using User Authentication</CITE></A> - or - <A HREF="http://www.apacheweek.com/features/dbmauth" - ><CITE>DBM User Authentication</CITE></A>. + Have a look at <A HREF="custom_errordocs.html">this document</A>. + It shows in example form how you can a combination of XSSI and + negotiation to tailor a set of <CODE>ErrorDocument</CODE>s to your + personal taste, and returning different internationalized error + responses based on the client's native language. </P> <HR> </LI> @@ -1679,6 +1986,81 @@ <HR> </LI> +</OL> + + <H3>G. Authentication and Access Restrictions</H3> +<OL> + + <LI><A NAME="dnsauth"> + <STRONG>Why isn't restricting access by host or domain name + working correctly?</STRONG> + </A> + <P> + Two of the most common causes of this are: + </P> + <OL> + <LI><STRONG>An error, inconsistency, or unexpected mapping in the DNS + registration</STRONG> + <BR> + This happens frequently: your configuration restricts access to + <SAMP>Host.FooBar.Com</SAMP>, but you can't get in from that host. + The usual reason for this is that <SAMP>Host.FooBar.Com</SAMP> is + actually an alias for another name, and when Apache performs the + address-to-name lookup it's getting the <EM>real</EM> name, not + <SAMP>Host.FooBar.Com</SAMP>. You can verify this by checking the + reverse lookup yourself. The easiest way to work around it is to + specify the correct host name in your configuration. + </LI> + <LI><STRONG>Inadequate checking and verification in your + configuration of Apache</STRONG> + <BR> + If you intend to perform access checking and restriction based upon + the client's host or domain name, you really need to configure + Apache to double-check the origin information it's supplied. You do + this by adding the <SAMP>-DMAXIMUM_DNS</SAMP> clause to the + <SAMP>EXTRA_CFLAGS</SAMP> definition in your + <SAMP>Configuration</SAMP> file. For example: + <P> + <DL> + <DD><CODE>EXTRA_CFLAGS=-DMAXIMUM_DNS</CODE> + </DD> + </DL> + <P></P> + <P> + This will cause Apache to be very paranoid about making sure a + particular host address is <EM>really</EM> assigned to the name it + claims to be. Note that this <EM>can</EM> incur a significant + performance penalty, however, because of all the name resolution + requests being sent to a nameserver. + </P> + </LI> + </OL> + <HR> + </LI> + + <LI><A NAME="user-authentication"> + <STRONG>How do I set up Apache to require a username and + password to access certain documents?</STRONG> + </A> + <P> + There are several ways to do this; some of the more popular + ones are to use the <A HREF="../mod/mod_auth.html">mod_auth</A>, + <A HREF="../mod/mod_auth_db.html">mod_auth_db</A>, or + <A HREF="../mod/mod_auth_dbm.html">mod_auth_dbm</A> modules. + </P> + <P> + For an explanation on how to implement these restrictions, see + <A HREF="http://www.apacheweek.com/"><CITE>Apache Week</CITE></A>'s + articles on + <A HREF="http://www.apacheweek.com/features/userauth" + ><CITE>Using User Authentication</CITE></A> + or + <A HREF="http://www.apacheweek.com/features/dbmauth" + ><CITE>DBM User Authentication</CITE></A>. + </P> + <HR> + </LI> + <LI><A NAME="remote-auth-only"> <STRONG>How do I set up Apache to allow access to certain documents only if a site is either a local site <EM>or</EM> @@ -1700,69 +2082,21 @@ allow from .domain.com <BR> AuthType Basic - <BR> - AuthUserFile /usr/local/apache/conf/htpasswd.users - <BR> - AuthName "special directory" - <BR> - require valid-user - <BR> - satisfy any</CODE> - </DD> - </DL> - <P></P> - <P> - See the <A HREF="#user-authentication">user authentication</A> - question and the <A HREF="../mod/mod_access.html">mod_access</A> - module for details on how the above directives work. - </P> - <HR> - </LI> - - <LI><A NAME="no-info-directives"> - <STRONG>Why doesn't mod_info list any directives?</STRONG> - </A> - <P> - The <A HREF="../mod/mod_info.html"><SAMP>mod_info</SAMP></A> - module allows you to use a Web browser to see how your server is - configured. Among the information it displays is the list modules and - their configuration directives. The "current" values for - the directives are not necessarily those of the running server; they - are extracted from the configuration files themselves at the time of - the request. If the files have been changed since the server was last - reloaded, the display will will not match the values actively in use. - If the files and the path to the files are not readable by the user as - which the server is running (see the - <A HREF="../mod/core.html#user"><SAMP>User</SAMP></A> - directive), then <SAMP>mod_info</SAMP> cannot read them in order to - list their values. An entry <EM>will</EM> be made in the error log in - this event, however. - </P> - <HR> - </LI> - - <LI><A NAME="linux-shmget"> - <STRONG>When I run it under Linux I get "shmget: - function not found", what should I do?</STRONG> - </A> + <BR> + AuthUserFile /usr/local/apache/conf/htpasswd.users + <BR> + AuthName "special directory" + <BR> + require valid-user + <BR> + satisfy any</CODE> + </DD> + </DL> + <P></P> <P> - Your kernel has been built without SysV IPC support. You will have to - rebuild the kernel with that support enabled (it's under the - "General Setup" submenu). Documentation for - kernel building is beyond the scope of this FAQ; you should consult - the - <A HREF="http://www.linuxhq.com/HOWTO/Kernel-HOWTO.html" - >Kernel HOWTO</A>, - or the documentation provided with your distribution, or a - <A HREF="http://www.linuxhq.com/HOWTO/META-FAQ.html" - >Linux newsgroup/mailing list</A>. - As a last-resort workaround, you can - comment out the <CODE>#define USE_SHMGET_SCOREBOARD</CODE> - definition in the - <SAMP>LINUX</SAMP> section of - <SAMP>src/conf.h</SAMP> and rebuild the server (prior to 1.3b4, simply - removing <CODE>#define HAVE_SHMGET</CODE> would have sufficed). - This will produce a server which is slower and less reliable. + See the <A HREF="#user-authentication">user authentication</A> + question and the <A HREF="../mod/mod_access.html">mod_access</A> + module for details on how the above directives work. </P> <HR> </LI> @@ -1860,6 +2194,65 @@ <HR> </LI> + <LI><A NAME="passwdauth"> + <STRONG>Can I use my <SAMP>/etc/passwd</SAMP> file + for Web page authentication?</STRONG> + </A> + <P> + Yes, you can - but it's a <STRONG>very bad idea</STRONG>. Here are + some of the reasons: + </P> + <UL> + <LI>The Web technology provides no governors on how often or how + rapidly password (authentication failure) retries can be made. That + means that someone can hammer away at your system's + <SAMP>root</SAMP> password using the Web, using a dictionary or + similar mass attack, just as fast as the wire and your server can + handle the requests. Most operating systems these days include + attack detection (such as <EM>n</EM> failed passwords for the same + account within <EM>m</EM> seconds) and evasion (breaking the + connection, disabling the account under attack, disabling + <EM>all</EM> logins from that source, <EM>et cetera</EM>), but the + Web does not. + </LI> + <LI>An account under attack isn't notified (unless the server is + heavily modified); there's no "You have 19483 login + failures" message when the legitimate owner logs in. + </LI> + <LI>Without an exhaustive and error-prone examination of the server + logs, you can't tell whether an account has been compromised. + Detecting that an attack has occurred, or is in progress, is fairly + obvious, though - <EM>if</EM> you look at the logs. + </LI> + <LI>Web authentication passwords (at least for Basic authentication) + generally fly across the wire, and through intermediate proxy + systems, in what amounts to plain text. "O'er the net we + go/Caching all the way;/O what fun it is to surf/Giving my password + away!" + </LI> + <LI>Since HTTP is stateless, information about the authentication is + transmitted <EM>each and every time</EM> a request is made to the + server. Essentially, the client caches it after the first + successful access, and transmits it without asking for all + subsequent requests to the same server. + </LI> + <LI>It's relatively trivial for someone on your system to put up a + page that will steal the cached password from a client's cache + without them knowing. Can you say "password grabber"? + </LI> + </UL> + <P> + If you still want to do this in light of the above disadvantages, the + method is left as an exercise for the reader. It'll void your Apache + warranty, though, and you'll lose all accumulated UNIX guru points. + </P> + <HR> + </LI> +</OL> + + <H3>H. URL Rewriting</H3> +<OL> + <LI><A NAME="rewrite-more-config"> <STRONG>Where can I find mod_rewrite rulesets which already solve particular URL-related problems?</STRONG> @@ -1935,472 +2328,155 @@ <STRONG>What can I do if my RewriteRules don't work as expected? </STRONG> </A> - <P> - Use "<SAMP>RewriteLog somefile</SAMP>" and - "<SAMP>RewriteLogLevel 9</SAMP>" and have a precise look at the - steps the rewriting engine performs. This is really the only one and best - way to debug your rewriting configuration. - </P> - <HR> - </LI> - - <LI><A NAME="rewrite-prefixdocroot"><STRONG>Why don't some of my URLs - get prefixed with DocumentRoot when using mod_rewrite?</STRONG> - </A> - <P> - If the rule starts with <SAMP>/somedir/...</SAMP> make sure that really no - <SAMP>/somedir</SAMP> exists on the filesystem if you don't want to lead the - URL to match this directory, <EM>i.e.</EM>, there must be no root directory named - <SAMP>somedir</SAMP> on the filesystem. Because if there is such a - directory, the URL will not get prefixed with DocumentRoot. This behaviour - looks ugly, but is really important for some other aspects of URL - rewriting. - </P> - <HR> - </LI> - - <LI><A NAME="rewrite-nocase"> - <STRONG>How can I make all my URLs case-insensitive with mod_rewrite? - </STRONG> - </A> - <P> - You can't! The reason is: First, case translations for arbitrary length URLs - cannot be done <EM>via</EM> regex patterns and corresponding substitutions. - One need - a per-character pattern like sed/Perl <SAMP>tr|..|..|</SAMP> feature. - Second, just - making URLs always upper or lower case will not resolve the complete problem - of case-INSENSITIVE URLs, because actually the URLs had to be rewritten to - the correct case-variant residing on the filesystem because in later - processing Apache needs to access the file. And Unix filesystem is always - case-SENSITIVE. - </P> - <P> - But there is a module named <CODE>mod_speling.c</CODE> (yes, it is named - this way!) out there on the net. Try this one. - </P> - <HR> - </LI> - - <LI><A NAME="rewrite-virthost"> - <STRONG> Why are RewriteRules in my VirtualHost parts ignored?</STRONG> - </A> - <P> - Because you have to enable the engine for every virtual host explicitly due - to security concerns. Just add a "RewriteEngine on" to your - virtual host configuration parts. - </P> - <HR> - </LI> - - <LI><A NAME="rewrite-envwhitespace"> - <STRONG> How can I use strings with whitespaces in RewriteRule's ENV - flag?</STRONG> - </A> - <P> - There is only one ugly solution: You have to surround the complete flag - argument by quotation marks (<SAMP>"[E=...]"</SAMP>). Notice: The argument - to quote here is not the argument to the E-flag, it is the argument of the - Apache config file parser, <EM>i.e.</EM>, the third argument of the RewriteRule here. - So you have to write <SAMP>"[E=any text with whitespaces]"</SAMP>. - </P> - <HR> - </LI> - - <LI><A NAME="cgi-spec"> - <STRONG>Where can I find the "CGI specification"?</STRONG> - </A> - <P> - The Common Gateway Interface (CGI) specification can be found at - the original NCSA site - <<A HREF="http://hoohoo.ncsa.uiuc.edu/cgi/interface.html"> - <SAMP>http://hoohoo.ncsa.uiuc.edu/cgi/interface.html</SAMP></A>>. - This version hasn't been updated since 1995, and there have been - some efforts to update it. - </P> - <P> - A new draft is being worked on with the intent of making it an informational - RFC; you can find out more about this project at - <<A HREF="http://web.golux.com/coar/cgi/" - ><SAMP>http://web.golux.com/coar/cgi/</SAMP></A>>. - </P> - <HR> - </LI> - - <LI><A NAME="year2000"> - <STRONG>Is Apache Year 2000 compliant?</STRONG> - </A> - <P> - Yes, Apache is Year 2000 compliant. - </P> - <P> - Apache internally never stores years as two digits. - On the HTTP protocol level RFC1123-style addresses are generated - which is the only format a HTTP/1.1-compliant server should - generate. To be compatible with older applications Apache - recognizes ANSI C's <CODE>asctime()</CODE> and - RFC850-/RFC1036-style date formats, too. - The <CODE>asctime()</CODE> format uses four-digit years, - but the RFC850 and RFC1036 date formats only define a two-digit year. - If Apache sees such a date with a value less than 70 it assumes that - the century is <SAMP>20</SAMP> rather than <SAMP>19</SAMP>. - </P> - <P> - Some aspects of Apache's output may use two-digit years, such as the - automatic listing of directory contents provided by - <A HREF="../mod/mod_autoindex.html"><SAMP>mod_autoindex</SAMP></A> - with the - <A HREF="../mod/mod_autoindex.html#indexoptions" - ><SAMP>FancyIndexing</SAMP></A> - option enabled, but it is improper to depend upon such displays for - specific syntax. And even that issue is being addressed by the - developers; a future version of Apache should allow you to format that - display as you like. - </P> - <P> - Although Apache is Year 2000 compliant, you may still get problems - if the underlying OS has problems with dates past year 2000 - (<EM>e.g.</EM>, OS calls which accept or return year numbers). - Most (UNIX) systems store dates internally as signed 32-bit integers - which contain the number of seconds since 1<SUP>st</SUP> January 1970, so - the magic boundary to worry about is the year 2038 and not 2000. - But modern operating systems shouldn't cause any trouble - at all. - </P> - <HR> - </LI> - - <LI><A NAME="namevhost"> - <STRONG>I upgraded to Apache 1.3 and now my virtual hosts don't - work!</STRONG> - </A> - <P> - In versions of Apache prior to 1.3b2, there was a lot of confusion - regarding address-based virtual hosts and (HTTP/1.1) name-based - virtual hosts, and the rules concerning how the server processed - <SAMP><VirtualHost></SAMP> definitions were very complex and not - well documented. - </P> - <P> - Apache 1.3b2 introduced a new directive, - <A HREF="http://www.apache.org/docs/mod/core.html#namevirtualhost" - ><SAMP>NameVirtualHost</SAMP></A>, - which simplifies the rules quite a bit. However, changing the rules - like this means that your existing name-based - <SAMP><VirtualHost></SAMP> containers probably won't work - correctly immediately following the upgrade. - </P> - <P> - To correct this problem, add the following line to the beginning of - your server configuration file, before defining any virtual hosts: - </P> - <DL> - <DD><CODE>NameVirtualHost <EM>n.n.n.n</EM></CODE> - </DD> - </DL> - <P> - Replace the "<SAMP>n.n.n.n</SAMP>" with the IP address to - which the name-based virtual host names resolve; if you have multiple - name-based hosts on multiple addresses, repeat the directive for each - address. - </P> - <P> - Make sure that your name-based <SAMP><VirtualHost></SAMP> blocks - contain <SAMP>ServerName</SAMP> and possibly <SAMP>ServerAlias</SAMP> - directives so Apache can be sure to tell them apart correctly. - </P> - <P> - Please see the - <A HREF="http://www.apache.org/docs/vhosts/">Apache - Virtual Host documentation</A> for further details about configuration. - </P> - <HR> - </LI> - - <LI><A NAME="redhat"> - <STRONG>I'm using RedHat Linux and I have problems with httpd - dying randomly or not restarting properly</STRONG> - </A> - - <P> - RedHat Linux versions 4.x (and possibly earlier) RPMs contain - various nasty scripts which do not stop or restart Apache properly. - These can affect you even if you're not running the RedHat supplied - RPMs. - </P> - <P> - If you're using the default install then you're probably running - Apache 1.1.3, which is outdated. From RedHat's ftp site you can - pick up a more recent RPM for Apache 1.2.x. This will solve one of - the problems. - </P> <P> - If you're using a custom built Apache rather than the RedHat RPMs - then you should <CODE>rpm -e apache</CODE>. In particular you want - the mildly broken <CODE>/etc/logrotate.d/apache</CODE> script to be - removed, and you want the broken <CODE>/etc/rc.d/init.d/httpd</CODE> - (or <CODE>httpd.init</CODE>) script to be removed. The latter is - actually fixed by the apache-1.2.5 RPMs but if you're building your - own Apache then you probably don't want the RedHat files. - </P> - <P> - We can't stress enough how important it is for folks, <EM>especially - vendors</EM> to follow the <A HREF="../stopping.html">stopping Apache - directions</A> given in our documentation. In RedHat's defense, - the broken scripts were necessary with Apache 1.1.x because the - Linux support in 1.1.x was very poor, and there were various race - conditions on all platforms. None of this should be necessary with - Apache 1.2 and later. + Use "<SAMP>RewriteLog somefile</SAMP>" and + "<SAMP>RewriteLogLevel 9</SAMP>" and have a precise look at the + steps the rewriting engine performs. This is really the only one and best + way to debug your rewriting configuration. </P> <HR> </LI> - <LI><A NAME="stopping"> - <STRONG>I upgraded from an Apache version earlier - than 1.2.0 and suddenly I have problems with Apache dying randomly - or not restarting properly</STRONG> + <LI><A NAME="rewrite-prefixdocroot"><STRONG>Why don't some of my URLs + get prefixed with DocumentRoot when using mod_rewrite?</STRONG> </A> - <P> - You should read <A HREF="#redhat">the previous note</A> about - problems with RedHat installations. It is entirely likely that your - installation has start/stop/restart scripts which were built for - an earlier version of Apache. Versions earlier than 1.2.0 had - various race conditions that made it necessary to use - <CODE>kill -9</CODE> at times to take out all the httpd servers. - But that should not be necessary any longer. You should follow - the <A HREF="../stopping.html">directions on how to stop - and restart Apache</A>. - </P> - <P>As of Apache 1.3 there is a script - <CODE>src/support/apachectl</CODE> which, after a bit of - customization, is suitable for starting, stopping, and restarting - your server. + If the rule starts with <SAMP>/somedir/...</SAMP> make sure that + really no <SAMP>/somedir</SAMP> exists on the filesystem if you + don't want to lead the URL to match this directory, <EM>i.e.</EM>, + there must be no root directory named <SAMP>somedir</SAMP> on the + filesystem. Because if there is such a directory, the URL will not + get prefixed with DocumentRoot. This behaviour looks ugly, but is + really important for some other aspects of URL rewriting. </P> <HR> </LI> - <LI><A NAME="redhat-htm"> - <STRONG>I'm using RedHat Linux and my .htm files are showing - up as HTML source rather than being formatted!</STRONG> + <LI><A NAME="rewrite-nocase"> + <STRONG>How can I make all my URLs case-insensitive with mod_rewrite? + </STRONG> </A> - <P> - RedHat messed up and forgot to put a content type for <CODE>.htm</CODE> - files into <CODE>/etc/mime.types</CODE>. Edit <CODE>/etc/mime.types</CODE>, - find the line containing <CODE>html</CODE> and add <CODE>htm</CODE> to it. - Then restart your httpd server: + You can't! The reason is: First, case translations for arbitrary + length URLs cannot be done <EM>via</EM> regex patterns and + corresponding substitutions. One need a per-character pattern like + sed/Perl <SAMP>tr|..|..|</SAMP> feature. Second, just making URLs + always upper or lower case will not resolve the complete problem of + case-INSENSITIVE URLs, because actually the URLs had to be rewritten + to the correct case-variant residing on the filesystem because in + later processing Apache needs to access the file. And Unix + filesystem is always case-SENSITIVE. </P> - <DL> - <DD><CODE>kill -HUP `cat /var/run/httpd.pid`</CODE> - </DD> - </DL> <P> - Then <STRONG>clear your browsers' caches</STRONG>. (Many browsers won't - re-examine the content type after they've reloaded a page.) + But there is a module named <CODE>mod_speling.c</CODE> (yes, it is named + this way!) out there on the net. Try this one. </P> <HR> </LI> - <LI><A NAME="glibc-crypt"> - <STRONG>I'm using RedHat Linux 5.0, or some other - <SAMP>glibc</SAMP>-based Linux system, and I get errors with the - <CODE>crypt</CODE> function when I attempt to build Apache 1.2.</STRONG> + <LI><A NAME="rewrite-virthost"> + <STRONG> Why are RewriteRules in my VirtualHost parts ignored?</STRONG> </A> - - <P> - <SAMP>glibc</SAMP> puts the <CODE>crypt</CODE> function into a separate - library. Edit your <CODE>src/Configuration</CODE> file and set this: - </P> - <DL> - <DD><CODE>EXTRA_LIBS=-lcrypt</CODE> - </DD> - </DL> <P> - Then re-run <SAMP>src/Configure</SAMP> and re-execute the make. + Because you have to enable the engine for every virtual host explicitly due + to security concerns. Just add a "RewriteEngine on" to your + virtual host configuration parts. </P> <HR> </LI> - <LI><A NAME="nfslocking"> - <STRONG>Server hangs, or fails to start, and/or error log - fills with "<SAMP>fcntl: F_SETLKW: No record locks - available</SAMP>" or similar messages</STRONG> + <LI><A NAME="rewrite-envwhitespace"> + <STRONG> How can I use strings with whitespaces in RewriteRule's ENV + flag?</STRONG> </A> - - <P> - These are symptoms of a fine locking problem, which usually means that - the server is trying to use a synchronization file on an NFS filesystem. - </P> <P> - Because of its parallel-operation model, the Apache Web server needs to - provide some form of synchronization when accessing certain resources. - One of these synchronization methods involves taking out locks on a file, - which means that the filesystem whereon the lockfile resides must support - locking. In many cases this means it <EM>can't</EM> be kept on an - NFS-mounted filesystem. + There is only one ugly solution: You have to surround the complete + flag argument by quotation marks (<SAMP>"[E=...]"</SAMP>). Notice: + The argument to quote here is not the argument to the E-flag, it is + the argument of the Apache config file parser, <EM>i.e.</EM>, the + third argument of the RewriteRule here. So you have to write + <SAMP>"[E=any text with whitespaces]"</SAMP>. </P> + <HR> + </LI> +</OL> + + <H3>I. Features</H3> +<OL> + + <LI><A NAME="proxy"> + <STRONG>Does or will Apache act as a Proxy server?</STRONG> + </A> <P> - To cause the Web server to work around the NFS locking limitations, include - a line such as the following in your server configuration files: + Apache version 1.1 and above comes with a + <A HREF="../mod/mod_proxy.html">proxy module</A>. + If compiled in, this will make Apache act as a caching-proxy server. </P> - <DL> - <DD><CODE>LockFile /var/run/apache-lock</CODE> - </DD> - </DL> + <HR> + </LI> + + <LI><A NAME="multiviews"> + <STRONG>What are "multiviews"?</STRONG> + </A> <P> - The directory should not be generally writable (<EM>e.g.</EM>, don't use - <SAMP>/var/tmp</SAMP>). - See the <A HREF="../mod/core.html#lockfile"><SAMP>LockFile</SAMP></A> - documentation for more information. + "Multiviews" is the general name given to the Apache + server's ability to provide language-specific document variants in + response to a request. This is documented quite thoroughly in the + <A HREF="../content-negotiation.html" REL="Help">content negotiation</A> + description page. In addition, <CITE>Apache Week</CITE> carried an + article on this subject entitled + "<A HREF="http://www.apacheweek.com/features/negotiation" REL="Help" + ><CITE>Content Negotiation Explained</CITE></A>". </P> <HR> </LI> - <LI><A NAME="zoom"> - <STRONG>What's the best hardware/operating system/... How do - I get the most out of my Apache Web server?</STRONG> + + <LI><A NAME="putsupport"> + <STRONG>Why can't I publish to my Apache server using PUT on + Netscape Gold and other programs?</STRONG> </A> <P> - Check out Dean Gaudet's - <A HREF="http://www.apache.org/docs/misc/perf-tuning.html" - >performance tuning page</A>. + Because you need to install and configure a script to handle + the uploaded files. This script is often called a "PUT" handler. + There are several available, but they may have security problems. + Using FTP uploads may be easier and more secure, at least for now. + For more information, see the <CITE>Apache Week</CITE> article + <A HREF="http://www.apacheweek.com/features/put" + ><CITE>Publishing Pages with PUT</CITE></A>. </P> <HR> </LI> - <LI><A NAME="regex"> - <STRONG>What are "regular expressions"?</STRONG></A> - <P> - Regular expressions are a way of describing a pattern - for example, "all - the words that begin with the letter A" or "every 10-digit phone number" - or even "Every sentence with two commas in it, and no capital letter Q". - Regular expressions (aka "regexp"s) are useful in Apache because they - let you apply certain attributes against collections of files or resources - in very flexible ways - for example, all .gif and .jpg files under - any "images" directory could be written as /.*\/images\/.*[jpg|gif]/. - </P> - <P> - The best overview around is probably the one which comes with - Perl. We implement a simple subset of Perl's regexp support, but - it's still a good way to learn what they mean. You can start by - going to the - <A - HREF="http://www.perl.com/CPAN-local/doc/manual/html/pod/perlre.html#Version_8_Regular_Expresions" - >CPAN page on regular expressions</A>, and branching out from there. - </P> + + <LI><A NAME="SSL-i"> + <STRONG>Why doesn't Apache include SSL?</STRONG> + </A> + <P> + SSL (Secure Socket Layer) data transport requires encryption, and many + governments have restrictions upon the import, export, and use of + encryption technology. If Apache included SSL in the base package, + its distribution would involve all sorts of legal and bureaucratic + issues, and it would no longer be freely available. Also, some of + the technology required to talk to current clients using SSL is + patented by <A HREF="http://www.rsa.com/">RSA Data Security</A>, + who restricts its use without a license. + </P> + <P> + Some SSL implementations of Apache are available, however; see the + "<A HREF="http://www.apache.org/related_projects.html" + >related projects</A>" + page at the main Apache web site. + </P> + <P> + You can find out more about this topic in the <CITE>Apache Week</CITE> + article about + <A HREF="http://www.apacheweek.com/features/ssl" REL="Help" + ><CITE>Apache and Secure Transactions</CITE></A>. + </P> <HR> </LI> - <LI><A NAME="broken-gcc"><STRONG>I'm using gcc and I get some - compilation errors, what is wrong?</STRONG></A> - <P> - GCC parses your system header files and produces a modified subset which - it uses for compiling. This behaviour ties GCC tightly to the version - of your operating system. So, for example, if you were running IRIX 5.3 - when you built GCC and then upgrade to IRIX 6.2 later, you will have to - rebuild GCC. Similarly for Solaris 2.4, 2.5, or 2.5.1 when you upgrade - to 2.6. Sometimes you can type "gcc -v" and it will tell you the version - of the operating system it was built against. - </P> - <P> - If you fail to do this, then it is very likely that Apache will fail - to build. One of the most common errors is with <CODE>readv</CODE>, - <CODE>writev</CODE>, or <CODE>uio.h</CODE>. This is <STRONG>not</STRONG> a - bug with Apache. You will need to re-install GCC. - </P> - <HR> - </LI> - <LI><A NAME="htaccess-work"> - <STRONG>My <CODE>.htaccess</CODE> files are being ignored.</STRONG></A> - <P> - This is almost always due to your <A HREF="../mod/core.html#allowoverride"> - AllowOverride</A> directive being set incorrectly for the directory in - question. If it is set to <CODE>None</CODE> then .htaccess files will - not even be looked for. If you do have one that is set, then be certain - it covers the directory you are trying to use the .htaccess file in. - This is normally accomplished by ensuring it is inside the proper - <A HREF="../mod/core.html#directory">Directory</A> container. - </P> - <HR> - </LI> - <LI><A NAME="submit_patch"> - <STRONG>How do I submit a patch to the Apache Group?</STRONG></A> - <P> - The Apache Group encourages patches from outside developers. There are 2 - main "types" - of patches: small bugfixes and general improvements. Bugfixes should be - submitting using the - Apache <A HREF="http://www.apache.org/bug_report.html">bug report page</A>. - Improvements, modifications, and additions should follow the instructions - below. - </P> - <P> - In general, the first course of action is to be a member of the - <SAMP>new-httpd@apache.org</SAMP> mailing list. This indicates to the Group - that - you are closely following the latest Apache developments. Your patch file - should be - generated using either '<CODE>diff -c</CODE>' or - '<CODE>diff -u</CODE>' against the - latest CVS tree. To submit your patch, send email to - <SAMP>new-httpd@apache.org</SAMP> - with a <SAMP>Subject:</SAMP> line that starts with <SAMP>[PATCH]</SAMP> and - includes a general description of the patch. In the body of the message, the - patch should be clearly described and then included at the end of the - message. - If the patch-file is long, you can note a URL to the file instead of the - file itself. Use of MIME enclosures/attachments should be avoided. - </P> - <P> - Be prepared to respond to any questions about your patches and possibly - defend - your code. If your patch results in a lot of discussion, you may be asked to - submit an updated patch that incorporate all changes and suggestions. - </P> - <HR> - </LI> - <LI><A NAME="aixccbug"><STRONG>Why am I getting "<SAMP>Expected - </Directory> but saw </Directory></SAMP>" when - I try to start Apache?</STRONG></A> - <P> - This is a known problem with certain versions of the AIX C compiler. - IBM are working on a solution, and the issue is being tracked by - <A HREF="http://bugs.apache.org/index/full/2312">problem report #2312</A>. - </P> - <HR> - </LI> - <LI><A NAME="domination"><STRONG>Why has Apache stolen my favourite site's - Internet address?</STRONG></A> - <P> - The simple answer is: "It hasn't." This misconception is usually - caused by the site in question having migrated to the Apache Web - server software, but not having migrated the site's content yet. When - Apache is installed, the default page that gets installed tells the - Webmaster the installation was successful. The expectation is that - this default page will be replaced with the site's real content. - If it doesn't, complain to the Webmaster, not to the Apache project -- - we just make the software and aren't responsible for what people - do (or don't do) with it. - </P> - <HR> - </LI> - <LI><A NAME="apspam"><STRONG>Why am I getting spam mail from the - Apache site?</STRONG></A> - <P> - The short answer is: "You aren't." Usually when someone thinks the - Apache site is originating spam, it's because they've traced the - spam to a Web site, and the Web site says it's using Apache. See the - <A HREF="#domination">previous FAQ entry</A> for more details on this - phenomenon. - </P> - <P> - No marketing spam originates from the Apache site. The only mail - that comes from the site goes only to addresses that have been - <EM>requested</EM> to receive the mail. - </P> - <HR> - </LI> +</OL> <!-- Don't forget to add HR tags at the end of each list item.. --> -</OL> <!--#include virtual="footer.html" --> </BODY> </HTML> 1.143 +59 -1 apache-apr/pthreads/htdocs/manual/mod/core.html Index: core.html =================================================================== RCS file: /home/cvs/apache-apr/pthreads/htdocs/manual/mod/core.html,v retrieving revision 1.142 retrieving revision 1.143 diff -u -u -r1.142 -r1.143 --- core.html 1999/01/01 17:03:12 1.142 +++ core.html 1999/03/17 17:00:00 1.143 @@ -49,6 +49,7 @@ <LI><A HREF="#keepalive">KeepAlive</A> <LI><A HREF="#keepalivetimeout">KeepAliveTimeout</A> <LI><A HREF="#limit"><Limit></A> +<LI><A HREF="#limitexcept"><LimitExcept></A> <LI><A HREF="#limitrequestbody">LimitRequestBody</A> <LI><A HREF="#limitrequestfields">LimitRequestFields</A> <LI><A HREF="#limitrequestfieldsize">LimitRequestFieldsize</A> @@ -75,6 +76,7 @@ <LI><A HREF="#rlimitnproc">RLimitNPROC</A> <LI><A HREF="#satisfy">Satisfy</A> <LI><A HREF="#scoreboardfile">ScoreBoardFile</A> +<LI><A HREF="#scriptinterpretersource">ScriptInterpreterSource</A> <LI><A HREF="#sendbuffersize">SendBufferSize</A> <LI><A HREF="#serveradmin">ServerAdmin</A> <LI><A HREF="#serveralias">ServerAlias</A> @@ -658,7 +660,8 @@ The directory sections typically occur in the access.conf file, but they may appear in any configuration file. <Directory> directives cannot -nest, and cannot appear in a <A HREF="#limit"><Limit></A> section. +nest, and cannot appear in a <A HREF="#limit"><Limit></A> or +<A HREF="#limitexcept"><LimitExcept></A> section. <P> <STRONG>See also</STRONG>: <A HREF="../sections.html">How Directory, @@ -1334,6 +1337,35 @@ <P><HR> +<H2><A NAME="limitexcept"><LimitExcept> directive</A></H2> +<!--%plaintext <?INDEX {\tt LimitExcept} section directive> --> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> + <LimitExcept <EM>method method</EM> ... > ... </LimitExcept><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> any<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> core<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> Available in Apache 1.3.5 and later<P> + +<LimitExcept> and </LimitExcept> are used to enclose a group of +access control directives which will then apply to any HTTP access method +<STRONG>not</STRONG> listed in the arguments; i.e., it is the opposite of a +<A HREF="#limit"><Limit></A> section and can be used to control both +standard and nonstandard/unrecognized methods. See the documentation for +<A HREF="#limit"><Limit></A> for more details. + +<P><HR> + <H2><A NAME="limitrequestbody">LimitRequestBody directive</A></H2> <!--%plaintext <?INDEX {\tt LimitRequestBody} directive> --> <A @@ -2591,6 +2623,32 @@ <STRONG>See Also</STRONG>: <A HREF="../stopping.html">Stopping and Restarting Apache</A></P> +<P><HR> + +<H2><A NAME="scriptinterpretersource">ScriptInterpreterSource directive</A></H2> +<!--%plaintext <?INDEX {\tt ScriptInterpreterSource} directive> --> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> ScriptInterpreterSource <EM>'registry' or 'script'</EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>ScriptInterpreterSource script</CODE> +<BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> directory, .htaccess<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> core (Windows only)<P> + +This directive is used to control how Apache 1.3.5 and later finds the interpreter +used to run CGI scripts. The default technique is to use the interpreter pointed to by +the #! line in the script. Setting ScriptInterpreterSource registry will cause the +Windows Registry to be searched using the script file extension (e.g., .pl) as a search key. <P><HR> <H2><A NAME="sendbuffersize">SendBufferSize directive</A></H2> 1.54 +2 -0 apache-apr/pthreads/htdocs/manual/mod/directives.html Index: directives.html =================================================================== RCS file: /home/cvs/apache-apr/pthreads/htdocs/manual/mod/directives.html,v retrieving revision 1.53 retrieving revision 1.54 diff -u -u -r1.53 -r1.54 --- directives.html 1998/12/27 02:38:14 1.53 +++ directives.html 1999/03/17 17:00:02 1.54 @@ -123,6 +123,7 @@ <LI><A HREF="core.html#keepalivetimeout">KeepAliveTimeout</A> <LI><A HREF="mod_negotiation.html#languagepriority">LanguagePriority</A> <LI><A HREF="core.html#limit"><Limit></A> +<LI><A HREF="core.html#limitexcept"><LimitExcept></A> <LI><A HREF="core.html#limitrequestbody">LimitRequestBody</A> <LI><A HREF="core.html#limitrequestfields">LimitRequestFields</A> <LI><A HREF="core.html#limitrequestfieldsize">LimitRequestFieldsize</A> @@ -186,6 +187,7 @@ <LI><A HREF="mod_actions.html#script">Script</A> <LI><A HREF="mod_alias.html#scriptalias">ScriptAlias</A> <LI><A HREF="mod_alias.html#scriptaliasmatch">ScriptAliasMatch</A> +<LI><A HREF="core.html#scriptinterpretersource">ScriptInterpreterSource</A> <LI><A HREF="mod_cgi.html#scriptlog">ScriptLog</A> <LI><A HREF="mod_cgi.html#scriptlogbuffer">ScriptLogBuffer</A> <LI><A HREF="mod_cgi.html#scriptloglength">ScriptLogLength</A> 1.23 +1 -1 apache-apr/pthreads/htdocs/manual/mod/mod_alias.html Index: mod_alias.html =================================================================== RCS file: /home/cvs/apache-apr/pthreads/htdocs/manual/mod/mod_alias.html,v retrieving revision 1.22 retrieving revision 1.23 diff -u -u -r1.22 -r1.23 --- mod_alias.html 1998/11/20 17:07:38 1.22 +++ mod_alias.html 1999/03/17 17:00:05 1.23 @@ -286,7 +286,7 @@ <P> This directive makes the client know that the Redirect is only temporary (status 302). Exactly equivalent to <CODE>Redirect -temporary</CODE>. +temp</CODE>. </P> <HR> 1.14 +27 -10 apache-apr/pthreads/htdocs/manual/mod/mod_negotiation.html Index: mod_negotiation.html =================================================================== RCS file: /home/cvs/apache-apr/pthreads/htdocs/manual/mod/mod_negotiation.html,v retrieving revision 1.13 retrieving revision 1.14 diff -u -u -r1.13 -r1.14 --- mod_negotiation.html 1998/12/27 02:38:15 1.13 +++ mod_negotiation.html 1999/03/17 17:00:06 1.14 @@ -46,26 +46,35 @@ <DL> <DT>Content-Encoding: -<DD>The encoding of the file. Currently only two encodings are recognized -by http; <CODE>x-compress</CODE> for compressed files, and <CODE>x-gzip</CODE> -for gzipped files. +<DD>The encoding of the file. Apache only recognizes encodings that are +defined by an <A HREF="mod_mime.html#addencoding">AddEncoding</A> directive. +This normally includes the encodings <CODE>x-compress</CODE> for compress'd +files, and <CODE>x-gzip</CODE> for gzip'd files. The <CODE>x-</CODE> prefix +is ignored for encoding comparisons. <DT>Content-Language: -<DD>The language of the variant, as an Internet standard language code, such -as <CODE>en</CODE>. +<DD>The language of the variant, as an Internet standard language tag +(RFC 1766). An example is <CODE>en</CODE>, meaning English. <DT>Content-Length: <DD>The length of the file, in bytes. If this header is not present, then the actual length of the file is used. <DT>Content-Type: <DD>The MIME media type of the document, with optional parameters. -parameters are separated from the media type and from one another by -semi-colons. Parameter syntax is name=value; allowed parameters are: +Parameters are separated from the media type and from one another by a +semi-colon, with a syntax of <CODE>name=value</CODE>. Common parameters +include: <DL> <DT>level -<DD>the value is an integer, which specifies the version of the media type. +<DD>an integer specifying the version of the media type. For <CODE>text/html</CODE> this defaults to 2, otherwise 0. <DT>qs -<DD>the value is a floating-point number with value between 0. and 1. -It indications the 'quality' of this variant. +<DD>a floating-point number with a value in the range 0.0 to 1.0, + indicating the relative 'quality' of this variant + compared to the other available variants, independent of the client's + capabilities. For example, a jpeg file is usually of higher source + quality than an ascii file if it is attempting to represent a + photograph. However, if the resource being represented is ascii art, + then an ascii file would have a higher source quality than a jpeg file. + All qs values are therefore specific to a given resource. </DL> Example: <BLOCKQUOTE><CODE>Content-Type: image/jpeg; qs=0.8</CODE></BLOCKQUOTE> @@ -91,6 +100,14 @@ <LI><A HREF="#cachenegotiateddocs">CacheNegotiatedDocs</A> <LI><A HREF="#languagepriority">LanguagePriority</A> </UL> + +<STRONG>See also</STRONG>: +<A HREF="./mod_mime.html#defaultlanguage">DefaultLanguage</A>, +<A HREF="./mod_mime.html#addencoding">AddEncoding</A>, +<A HREF="./mod_mime.html#addlanguage">AddLanguage</A>, +<A HREF="./mod_mime.html#addtype">AddType</A>, and +<A HREF="core.html#options">Option</A>. + <HR> 1.6 +2 -2 apache-apr/pthreads/htdocs/manual/mod/mod_so.html Index: mod_so.html =================================================================== RCS file: /home/cvs/apache-apr/pthreads/htdocs/manual/mod/mod_so.html,v retrieving revision 1.5 retrieving revision 1.6 diff -u -u -r1.5 -r1.6 --- mod_so.html 1998/05/20 14:12:59 1.5 +++ mod_so.html 1999/03/17 17:00:08 1.6 @@ -57,7 +57,7 @@ <A HREF="directive-dict.html#Status" REL="Help" -><STRONG>Status:</STRONG></A> Experimental<BR> +><STRONG>Status:</STRONG></A> Base<BR> <A HREF="directive-dict.html#Module" REL="Help" @@ -82,7 +82,7 @@ <A HREF="directive-dict.html#Status" REL="Help" -><STRONG>Status:</STRONG></A> Experimental<BR> +><STRONG>Status:</STRONG></A> Base<BR> <A HREF="directive-dict.html#Module" REL="Help" 1.10 +1 -1 apache-apr/pthreads/htdocs/manual/vhosts/details.html Index: details.html =================================================================== RCS file: /home/cvs/apache-apr/pthreads/htdocs/manual/vhosts/details.html,v retrieving revision 1.9 retrieving revision 1.10 diff -u -u -r1.9 -r1.10 --- details.html 1998/09/17 14:52:03 1.9 +++ details.html 1999/03/17 17:00:22 1.10 @@ -126,7 +126,7 @@ affect the ports assigned in the address set. <P>During initialization a list for each IP address -is generated an inserted into an hash table. If the IP address is +is generated and inserted into an hash table. If the IP address is used in a <CODE>NameVirtualHost</CODE> directive the list contains all name-based vhosts for the given IP address. If there are no vhosts defined for that address the <CODE>NameVirtualHost</CODE> directive 1.10 +6 -3 apache-apr/pthreads/htdocs/manual/vhosts/name-based.html Index: name-based.html =================================================================== RCS file: /home/cvs/apache-apr/pthreads/htdocs/manual/vhosts/name-based.html,v retrieving revision 1.9 retrieving revision 1.10 diff -u -u -r1.9 -r1.10 --- name-based.html 1998/12/18 23:49:44 1.9 +++ name-based.html 1999/03/17 17:00:26 1.10 @@ -107,15 +107,18 @@ familiar with typing "www" or "www.foobar" then you will need to add <CODE>ServerAlias www www.foobar</CODE>. It isn't possible for the server to know what domain the client uses for their name resolution -because the client doesn't provide that information in the request.</P> +because the client doesn't provide that information in the request. +The <CODE>ServerAlias</CODE> directive is generally a way to have different +hostnames pointing to the same virtual host. +</P> <H2>Compatibility with Older Browsers</H2> <P>As mentioned earlier, there are still some clients in use who do not send the required data for the name-based virtual hosts to work properly. These clients will always be sent the pages from the -<CITE>primary</CITE> name-based virtual host (the first virtual host -appearing in the configuration file for a specific IP address).</P> +first virtual host listed for that IP address (the +<CITE>primary</CITE> name-based virtual host).</P> <P>There is a possible workaround with the <A HREF="../mod/core.html#serverpath"><CODE>ServerPath</CODE></A> 1.3 +18 -2 apache-apr/pthreads/src/ApacheCore.def Index: ApacheCore.def =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/ApacheCore.def,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- ApacheCore.def 1999/02/07 06:29:08 1.2 +++ ApacheCore.def 1999/03/17 17:00:32 1.3 @@ -320,11 +320,27 @@ ap_method_number_of @313 ap_exists_config_define @314 ap_single_module_configure @315 - ap_single_module_init @316 ap_make_etag @317 ap_array_pstrcat @318 ap_os_is_filename_valid @319 - ap_find_opaque_token @320 + ap_find_list_item @320 ap_MD5Encode @321 ap_validate_password @322 + ap_size_list_item @323 + ap_get_list_item @324 + ap_scoreboard_fname @325 + ap_pid_fname @326 + ap_excess_requests_per_child @327 + ap_threads_per_child @328 + ap_max_requests_per_child @329 + ap_daemons_to_start @330 + ap_daemons_min_free @331 + ap_daemons_max_free @332 + ap_daemons_limit @333 + ap_user_name @334 + ap_user_id @335 + ap_group_id @336 + ap_standalone @337 + ap_server_confname @338 + ap_sub_req_method_uri @339 1.3 +183 -5 apache-apr/pthreads/src/CHANGES Index: CHANGES =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/CHANGES,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- CHANGES 1999/02/07 06:29:08 1.2 +++ CHANGES 1999/03/17 17:00:33 1.3 @@ -1,9 +1,190 @@ Changes with Apache 1.3.5 + *) PORT: Switch back to using fcntl() locking on Linux -- instabilities + have been reported with flock() locking (probably related to kernel + version). [Dean Gaudet] PR#2723, 3531 + + *) Using APACI, the main config file (usually httpd.conf) was + not being adjusted as $(TARGET).conf. [Wilfredo Sanchez + <[EMAIL PROTECTED]>] + + *) PORT: AIX does not require the SHARED_CODE "hack" + [Ryan Bloom <[EMAIL PROTECTED]>] + + *) Set-Cookie headers were being doubled up for some CGIs by the O(n^2) + avoidance code added in 1.3.3. + [Dean Gaudet, Jeff Lewis <[EMAIL PROTECTED]>] PR#3872 + + *) ap_isxdigit was somehow neglected when adding the ap_isfoo() macros + for 8-bit safeness. [Dean Gaudet] + + *) Use -fPIC instead of -fpic on Solaris and SunOS for compiling DSOs + because SPARCs have a small machine-specific maximum size for the Global + Offset Table which is often exceeded when compiling one of the larger + third-party modules with Apache. [Peter Urban <[EMAIL PROTECTED]>] PR#3977 + + *) Move the directive `ExtendedStatus' in httpd.conf-dist-win _after_ the + DSO/DLL section because it's a directive from mod_status and isn't + available before the DLL of mod_status is loaded. + [Martin POESCHL <[EMAIL PROTECTED]>] PR#3936 + + *) SECURITY: Fix a bug in the calculation of the buffer size for the line + continuation facility in Apache's configuration files which could + lead to a buffer overflow situation. + [Thomas Devanneaux <[EMAIL PROTECTED]>] PR#3617 + + *) Make documentation and error messages of APACI's --activate-module=FILE + option more clear. [Jan Wolter <[EMAIL PROTECTED]>] PR#3995 + + *) Fix the gcc version check (for enabling the `inline' facility) to + really support all future gcc versions >= 2.7 until we know more. + [John Tobey <[EMAIL PROTECTED]>] PR#3983 + + *) Let APACI's configure script correctly complain for unknown --enable-XXX + and --disable-XXX options. [Ralf S. Engelschall] PR#3958 + + *) Link the shared core bootstrap program (``Rule SHARED_CORE=yes'') also + against libap.a and use its ap_snprintf() instead of sprintf() to avoid + possible buffer overflows. [Ralf S. Engelschall] + + *) Remove no longer used non-API function ap_single_module_init(). + [Ralf S. Engelschall] + + *) Add Apple's Mac OS X Server Layout "Rhapsody" to config.layout. + [Wilfredo Sanchez] + + *) Add cgidir, htdocsdir, iconsdir variables to Makefile.tmpl in order + to make platform installations easier. [Wilfredo Sanchez] + + *) In configure, do not append the target name to the directory path if + the path already contains "apache". [Ralf S. Engelschall] + + *) SIGPIPE is now ignored by the server core. The request write routines + (ap_rputc, ap_rputs, ap_rvputs, ap_rwrite, ap_rprintf, ap_rflush) now + correctly check for output errors and mark the connection as aborted. + Replaced many direct (unchecked) calls to ap_b* routines with the + analogous ap_r* calls. [Roy Fielding] + + *) Enhanced mod_rewrite's mapfile handling: The in-core cache for text and + DBM format mapfiles now uses a 4-way hash table with LRU functionality. + Furthermore map lookups for non-existent keys are now cached as well. + Additionally "txt" maps are now parsed with simple string functions + instead of using ap_pregcomp(). As a side effect a bug that prevented + the usage of keys containing the "," character was fixed. + The changes drastically improve the performance when large rewrite maps + are in use. + [Michael van Elst <[EMAIL PROTECTED]>, Lars Eilebrecht] PR#3160 + + *) Added ap_sub_req_method_uri() for doing a subrequest with a method + other than GET, and const'd the definition of method in request_rec. + [Greg Stein] + + *) Use proper pid_t type for saving PIDs in alloc.c. [John Bley] + + *) Replaced use of WIN32 define with HAVE_DRIVE_LETTERS to indicate + when the OS allows a DOS drive letter within pathnames. [Brian Havard] + + *) Add %V to mod_log_config, this logs the hostname according to the + UseCanonicalName setting (this is the pre-1.3.4 behaviour of + %v). Useful for mass vhosting. [Tony Finch <[EMAIL PROTECTED]>] + + *) Add support for \n and \t to mod_log_config, can be used to produce + more reliable logs with multiline entries. [Tony Finch <[EMAIL PROTECTED]>] + + *) Fixed a few compiler nits. [John Bley <[EMAIL PROTECTED]>] + + *) Added informative error messages for failed munmap() and fseek() calls + in http_core.c. [John Bley, Roy Fielding] + + *) Added some informative error messages for some failed malloc() + calls. [John Bley <[EMAIL PROTECTED]>, Jim Jagielski] + + *) OS/2 ap_os_canonical_filename()'s behaviour is improved: ap_assert() + is removed. This allows <Directory proxy:*> directives to work and + prevents invalid requests from killing the process. + [Brian Havard <[EMAIL PROTECTED]>] + + *) Reorganised FAQ document. + [Joshua Slive <[EMAIL PROTECTED]>] PR#2497 + + *) src/support/: The ApacheBench benchmark program was overhauled by + David N. Welton: you can now have it generate an HTML TABLE, presumably + for integration into other HTML sources. David updated the ab man page + as well and added some missing descriptions. Thanks! + [David N. Welton <[EMAIL PROTECTED]>] + + *) Win32: The filename validity checker now allows filenames containing + characters in the range 0x80 to 0xff (for example accented characters). + [Paul Sutton] PR#3890 + + *) Added conditional logging based upon environment variables to + mod_log_config. mod_log_referer and mod_log_agent + are now deprecated. [Ken Coar] + + *) Allow apache acting as a proxy server to relay the real + reason of a failure to a client rather than the "internal + server error" it does currently. The general exposure mechanism + can be triggered by any module by setting the "verbose-error-to" + note to "*"; this allows more than just proxy errors to be exposed. + [Cliff Skolnick, Roy Fielding, Martin Kraemer] Related to PR#3455 + + *) Moved man pages for ab and apachectrl to section 8. + [Wilfredo Sanchez, Roy Fielding] + + *) Added -S option to install.sh so that options can be passed to + strip on some platforms. [Ralf S. Engelschall, Wilfredo Sanchez] + + *) Tweak modules Makefile generated by Configure so that it handles + the test case of no modules being selected. [EMAIL PROTECTED] + + *) Added a <LimitExcept method ...> sectioning directive that allows + the user to assign authentication control to any HTTP method that + is *not* given in the argument list; i.e., the logical negation + of the <Limit> directive. This is particularly useful for controlling + access on methods unknown to the Apache core, but perhaps known by + some module or CGI script. [Roy Fielding, Tony Finch] + + *) Prevent apachectl from complaining if the PIDFILE exists but + does not contain a process id, as might occur if the server is + being rapidly restarted. [Wilfredo Sanchez] + + *) Win32: Add global symbols missing from ApacheCore.def. [Carl Olsen] + + *) Entity tag comparisons for If-Match and If-None-Match were not being + performed correctly -- weak tags might cause false positives. Also, + strong comparison wasn't properly enforced in all cases. + [Roy Fielding, Ken Coar, Dean Gaudet] PR#2065, 3657 + + *) OS/2: Supply OS/2 error code instead of errno on semaphore errors. + [Brian Havard] + + *) Work around a bug in Lynx regarding its sending "Negotiate: trans" + even though it doesn't understand TCN. [Koen Holtman, Roy Fielding] + + *) Added ap_size_list_item(), ap_get_list_item(), and ap_find_list_item() + to util.c for parsing an HTTP header field value to extract the next + list item, taking into account the possible presence of nested comments, + quoted-pairs, and quoted-strings. ap_get_list_item() also removes + insignificant whitespace and lowercases non-quoted tokens. + [Roy Fielding] PR#2065 + + *) proxy: The various calls to ap_proxyerror() can return HTTP/1.1 status + code different from 500. This allows the proxy to, e.g., return + "403 Forbidden" for ProxyBlock'ed URL's. [Martin Kraemer] Related to PR#3455 + + *) Fix ordering of language variants for the case where the traditional + negotiation algorithm is being used with multiple language variants + and no Accept-Language. [James Treacy <[EMAIL PROTECTED]>] PR#3299, 3688 + + *) Do not round the TCN quality calculation to 5 decimal places, + unlike RFC 2296, because the calculation might need 12 decimal places + to get the right result. [Roy Fielding] + *) Remove unused code to disable transparent negotiation when negotiating on encoding only, as we now handle encoding too - (though this is nonstandard for TCN), and fix bugs in debugging - statements within mod_negotiation. [Koen Holtman] + (though this is nonstandard for TCN), remove charset=ISO-8859-1 + fiddle from the fiddle-averse RVSA comparison, and fix bugs in + some debugging statements within mod_negotiation. [Koen Holtman] *) Fixed a rare memory corruption possibility in mod_dir if the index file is negotiable and no acceptable variant can be found. @@ -42,9 +223,6 @@ use `.db' instead of `.pag' not only for FreeBSD, but also when the NDBM library looks like Berkeley-DB based. [Ralf S. Engelschall] PR#3773 - - *) Fix checking of ETags and other opaque 'tokens' by adding - ap_find_opaque_token(). PR#2065, 3657 [Ken Coar] *) Add ability to handle DES or MD5 authentication passwords. [Ryan Bloom <[EMAIL PROTECTED]>] 1.8 +36 -31 apache-apr/pthreads/src/Configure Index: Configure =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/Configure,v retrieving revision 1.7 retrieving revision 1.8 diff -u -u -r1.7 -r1.8 --- Configure 1999/02/26 20:04:21 1.7 +++ Configure 1999/03/17 17:00:35 1.8 @@ -228,7 +228,7 @@ #################################################################### ## Rule SHARED_CORE implies required DSO support ## -if [ "$RULE_SHARED_CORE" = "yes" ]; then +if [ "x$RULE_SHARED_CORE" = "xyes" ]; then using_shlib=1 fi @@ -321,6 +321,9 @@ CC=cc_r CFLAGS="$CFLAGS -DAIX=1 -U__STR__" LDFLAGS="$LDFLAGS -lm" + RULE_SHARED_CORE=no + DEF_SHARED_CORE=no + using_shlib=0 ;; *-apollo-*) OS='Apollo Domain' @@ -378,7 +381,7 @@ echo "but if you would care to port to 64-bit, send us the patches." DEF_WANTHSREGEX=yes DBM_LIB="" - if [ "$RULE_IRIXNIS" = "yes" ]; then + if [ "x$RULE_IRIXNIS" = "xyes" ]; then OS='SGI IRIX-64 w/NIS' CFLAGS="$CFLAGS -DIRIX" LIBS="$LIBS -lsun" @@ -390,14 +393,14 @@ *-sgi-irix32) DEF_WANTHSREGEX=yes DBM_LIB="" - if [ "$RULE_IRIXN32" = "yes" ]; then - if [ "$RULE_IRIXNIS" = "yes" ]; then + if [ "x$RULE_IRIXN32" = "xyes" ]; then + if [ "x$RULE_IRIXNIS" = "xyes" ]; then OS='SGI IRIX-32 w/NIS' else OS='SGI IRIX-32' fi else - if [ "$RULE_IRIXNIS" = "yes" ]; then + if [ "x$RULE_IRIXNIS" = "xyes" ]; then OS='SGI IRIX w/NIS' else OS='SGI IRIX' @@ -409,7 +412,7 @@ *-sgi-irix) DEF_WANTHSREGEX=yes DBM_LIB="" - if [ "$RULE_IRIXNIS" = "yes" ]; then + if [ "x$RULE_IRIXNIS" = "xyes" ]; then OS='SGI IRIX w/NIS' CFLAGS="$CFLAGS -DIRIX" LIBS="$LIBS -lsun" @@ -786,7 +789,7 @@ #################################################################### ## And adjust/override WANTHSREGEX as needed ## -if [ "$RULE_WANTHSREGEX" = "default" ]; then +if [ "x$RULE_WANTHSREGEX" = "xdefault" ]; then if [ "x$DEF_WANTHSREGEX" = "x" ]; then RULE_WANTHSREGEX=yes else @@ -1003,7 +1006,7 @@ ;; *-solaris2*) case $CC in - */gcc|gcc ) CFLAGS_SHLIB="-fpic" ;; + */gcc|gcc ) CFLAGS_SHLIB="-fPIC" ;; */cc|cc ) CFLAGS_SHLIB="-KPIC" ;; esac LDFLAGS_SHLIB="-G" @@ -1012,7 +1015,7 @@ ;; *-sunos4*) case $CC in - */gcc|gcc ) CFLAGS_SHLIB="-fpic" ;; + */gcc|gcc ) CFLAGS_SHLIB="-fPIC" ;; */acc|acc ) CFLAGS_SHLIB="-pic" ;; esac LDFLAGS_SHLIB="-assert pure-text" @@ -1029,7 +1032,7 @@ N32FLAG="-n32" ;; esac - if [ "$RULE_IRIXN32" = "yes" ]; then + if [ "x$RULE_IRIXN32" = "xyes" ]; then LDFLAGS_SHLIB="$N32FLAG -shared" else LDFLAGS_SHLIB="-shared" @@ -1047,7 +1050,7 @@ N32FLAG="-n32" ;; esac - if [ "$RULE_IRIXN32" = "yes" ]; then + if [ "x$RULE_IRIXN32" = "xyes" ]; then LDFLAGS_SHLIB="$N32FLAG -shared" else LDFLAGS_SHLIB="-shared" @@ -1261,7 +1264,7 @@ esac ;; *IRIX-64*) - if [ "$RULE_IRIXN32" = "yes" ]; then + if [ "x$RULE_IRIXN32" = "xyes" ]; then case "$CC" in */cc|cc ) CFLAGS="$CFLAGS -n32" @@ -1271,7 +1274,7 @@ fi ;; *IRIX-32*) - if [ "$RULE_IRIXN32" = "yes" ]; then + if [ "x$RULE_IRIXN32" = "xyes" ]; then case "$CC" in */cc|cc ) CFLAGS="$CFLAGS -n32" @@ -1340,7 +1343,7 @@ # We assume that if they are using SOCKS4, then they've # adjusted EXTRA_LIBS and/or EXTRA_LDFLAGS as required, # otherwise we assume "-L/usr/local/lib -lsocks" -if [ "$RULE_SOCKS4" = "yes" ]; then +if [ "x$RULE_SOCKS4" = "xyes" ]; then echo " + enabling SOCKS4 support" CFLAGS="$CFLAGS -DSOCKS -DSOCKS4" CFLAGS="$CFLAGS -Dconnect=Rconnect -Dselect=Rselect" @@ -1359,7 +1362,7 @@ # We assume that if they are using SOCKS5, then they've # adjusted EXTRA_LIBS and/or EXTRA_LDFLAGS as required, # otherwise we assume "-L/usr/local/lib -lsocks5" -if [ "$RULE_SOCKS5" = "yes" ]; then +if [ "x$RULE_SOCKS5" = "xyes" ]; then echo " + enabling SOCKS5 support" CFLAGS="$CFLAGS -DSOCKS -DSOCKS5" CFLAGS="$CFLAGS -Dconnect=SOCKSconnect -Dselect=SOCKSselect" @@ -1502,13 +1505,13 @@ sed '1,/ConfigStart/d;/ConfigEnd/,$d' $tmpfile2 > \ $tmpfile3 echo " o $modname uses ConfigStart/End" - if [ "$RULE_PARANOID" = "yes" ]; then + if [ "x$RULE_PARANOID" = "xyes" ]; then sed 's/^/>> /' $tmpfile3 fi . ./$tmpfile3 fi rm -f $tmpfile2 $tmpfile3 - if [ "$ext" != "so" ]; then + if [ "x$ext" != "xso" ]; then ext=o fi fi @@ -1516,11 +1519,11 @@ modname=`echo $modbase | sed 's/^.*\///' | \ sed 's/^mod_//' | sed 's/^lib//' | sed 's/$/_module/'` fi - if [ "$ext" != "so" ]; then + if [ "x$ext" != "xso" ]; then echo "Module $modname $modbase.$ext" >>$tmpfile fi # optionally generate export file for some linkers - if [ "$ext" = "so" -a "$SHLIB_EXPORT_FILES" = "yes" ]; then + if [ "x$ext" = "xso" -a "x$SHLIB_EXPORT_FILES" = "xyes" ]; then echo "$modname" >$modbase.exp fi done @@ -1530,7 +1533,7 @@ ## Now HS's POSIX regex implementation if needed/wanted. We do it ## now since AddModule may have changed it ## -if [ "$RULE_WANTHSREGEX" = "yes" ]; then +if [ "x$RULE_WANTHSREGEX" = "xyes" ]; then REGLIB="regex/libregex.a" SUBDIRS="regex $SUBDIRS" CFLAGS="$CFLAGS -DUSE_HSREGEX" @@ -1541,10 +1544,10 @@ ## LIBS_SHLIB='' if [ "x$using_shlib" = "x1" ] ; then - if [ "$RULE_SHARED_CHAIN" = "default" ] ; then + if [ "x$RULE_SHARED_CHAIN" = "xdefault" ] ; then RULE_SHARED_CHAIN=$DEF_SHARED_CHAIN fi - if [ "$RULE_SHARED_CHAIN" = "yes" ]; then + if [ "x$RULE_SHARED_CHAIN" = "xyes" ]; then echo " + enabling DSO files to be linked against others" # determine libraries which can be safely linked # to our DSO files, i.e. PIC libraries and shared libraries @@ -1559,10 +1562,10 @@ ## Now the SHARED_CORE stuff ## if [ "x$using_shlib" = "x1" ] ; then - if [ "$RULE_SHARED_CORE" = "default" ] ; then + if [ "x$RULE_SHARED_CORE" = "xdefault" ] ; then RULE_SHARED_CORE=$DEF_SHARED_CORE fi - if [ "$RULE_SHARED_CORE" = "yes" ]; then + if [ "x$RULE_SHARED_CORE" = "xyes" ]; then echo " + enabling generation of Apache core as DSO" # shuffle compiler flags from shlib variant to standard CFLAGS="$CFLAGS $CFLAGS_SHLIB" @@ -1573,19 +1576,19 @@ SUBTARGET=target_shared # determine additional suffixes for libhttpd.so V=1 R=3 P=5 - if [ "$SHLIB_SUFFIX_DEPTH" = "0" ]; then + if [ "x$SHLIB_SUFFIX_DEPTH" = "x0" ]; then SHLIB_SUFFIX_LIST="" fi - if [ "$SHLIB_SUFFIX_DEPTH" = "1" ]; then + if [ "x$SHLIB_SUFFIX_DEPTH" = "x1" ]; then SHLIB_SUFFIX_LIST="$V" fi - if [ "$SHLIB_SUFFIX_DEPTH" = "2" ]; then + if [ "x$SHLIB_SUFFIX_DEPTH" = "x2" ]; then SHLIB_SUFFIX_LIST="$V.$R" fi - if [ "$SHLIB_SUFFIX_DEPTH" = "3" ]; then + if [ "x$SHLIB_SUFFIX_DEPTH" = "x3" ]; then SHLIB_SUFFIX_LIST="$V.$R.$P" fi - if [ "$SHLIB_SUFFIX_DEPTH" = "all" ]; then + if [ "x$SHLIB_SUFFIX_DEPTH" = "xall" ]; then SHLIB_SUFFIX_LIST="$V $V.$R $V.$R.$P" fi fi @@ -1864,7 +1867,7 @@ ## check ## -if [ "$OS" = "TPF" ] ; then +if [ "x$OS" = "xTPF" ] ; then : else echo " + doing sanity check on compiler and options" @@ -1912,10 +1915,12 @@ default: all all clean distclean depend :: - @for i in \$(MODULES); do \\ + @for i in \$(MODULES) ""; do \\ + if [ "x\$\$i" != "x" ]; then \\ echo "===> \$(SDP)modules/\$\$i"; \\ (cd \$\$i && \$(MAKE) \$(MFLAGS_STATIC) SDP='\$(SDP)' CC='\$(CC)' AUX_CFLAGS='\$(CFLAGS)' RANLIB='\$(RANLIB)' \$@) || exit 1; \\ echo "<=== \$(SDP)modules/\$\$i"; \\ + fi; \\ done EOF 1.3 +2 -1 apache-apr/pthreads/src/Makefile.tmpl Index: Makefile.tmpl =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/Makefile.tmpl,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- Makefile.tmpl 1999/02/07 06:29:09 1.2 +++ Makefile.tmpl 1999/03/17 17:00:36 1.3 @@ -35,7 +35,8 @@ target_shared: lib$(TARGET).ep $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SHLIB_EXPORT) \ - -o $(TARGET) -DSHARED_CORE_BOOTSTRAP main/http_main.c + -o $(TARGET) -DSHARED_CORE_BOOTSTRAP main/http_main.c \ + ap/libap.a $(LIBS) lib$(TARGET).ep: lib$(TARGET).$(SHLIB_SUFFIX_NAME) $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SHLIB_EXPORT) \ 1.2 +3 -0 apache-apr/pthreads/src/Makefile_win32.txt Index: Makefile_win32.txt =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/Makefile_win32.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -u -r1.1 -r1.2 --- Makefile_win32.txt 1999/02/07 06:29:10 1.1 +++ Makefile_win32.txt 1999/03/17 17:00:37 1.2 @@ -33,6 +33,9 @@ cd ap nmake /nologo CFG="ap - Win32 Release" -f ap.mak cd .. + cd support + nmake /nologo CFG="htpasswd - Win32 Release" -f htpasswd.mak + cd .. cd main nmake /nologo CFG="gen_uri_delims - Win32 Release" -f gen_uri_delims.mak nmake /nologo CFG="gen_test_char - Win32 Release" -f gen_test_char.mak 1.2 +3 -0 apache-apr/pthreads/src/Makefile_win32_debug.txt Index: Makefile_win32_debug.txt =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/Makefile_win32_debug.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -u -u -r1.1 -r1.2 --- Makefile_win32_debug.txt 1999/02/07 06:29:10 1.1 +++ Makefile_win32_debug.txt 1999/03/17 17:00:39 1.2 @@ -33,6 +33,9 @@ cd ap nmake /nologo CFG="ap - Win32 Debug" -f ap.mak cd .. + cd support + nmake /nologo CFG="htpasswd - Win32 Debug" -f htpasswd.mak + cd .. cd main nmake /nologo CFG="gen_uri_delims - Win32 Debug" -f gen_uri_delims.mak nmake /nologo CFG="gen_test_char - Win32 Debug" -f gen_test_char.mak 1.3 +10 -2 apache-apr/pthreads/src/ap/ap_execve.c Index: ap_execve.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/ap/ap_execve.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- ap_execve.c 1999/02/07 06:29:13 1.2 +++ ap_execve.c 1999/03/17 17:00:47 1.3 @@ -126,8 +126,10 @@ } va_end(adummy); - if ((argv = (char **) malloc((argc + 2) * sizeof(*argv))) == NULL) + if ((argv = (char **) malloc((argc + 2) * sizeof(*argv))) == NULL) { + fprintf(stderr, "Ouch! Out of memory in ap_execle()!\n"); return -1; + } /* Pass two --- copy the argument strings into the result space */ va_start(adummy, argv0); @@ -222,8 +224,10 @@ else { int i = count_args(argv) + 1; /* +1 for leading SHELL_PATH */ - if ((script_argv = malloc(sizeof(*script_argv) * i)) == NULL) + if ((script_argv = malloc(sizeof(*script_argv) * i)) == NULL) { + fprintf(stderr, "Ouch! Out of memory in ap_execve()!\n"); return -1; + } script_argv[0] = SHELL_PATH; @@ -345,6 +349,10 @@ newargv = (char **) malloc((p - lbuf + 1) + (i + sargc + 1) * sizeof(*newargv)); + if (newargv == NULL) { + fprintf(stderr, "Ouch! Out of memory in hashbang()!\n"); + return NULL; + } ws = &((char *) newargv)[(i + sargc + 1) * sizeof(*newargv)]; /* Copy entries to allocated memory */ 1.3 +1 -1 apache-apr/pthreads/src/helpers/GuessOS Index: GuessOS =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/GuessOS,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- GuessOS 1999/02/07 06:29:16 1.2 +++ GuessOS 1999/03/17 17:00:51 1.3 @@ -274,7 +274,7 @@ # Apache is not compiled on the TPF platform # therefore an environment variable is used -if [ "$TPF" = "YES" ]; then +if [ "x$TPF" = "xYES" ]; then echo "TPF" exit 0 fi 1.3 +1 -1 apache-apr/pthreads/src/helpers/PrintPath Index: PrintPath =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/PrintPath,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- PrintPath 1999/02/07 06:29:16 1.2 +++ PrintPath 1999/03/17 17:00:53 1.3 @@ -91,7 +91,7 @@ do if [ $test_exec_flag $path/${program}${ext} ] && \ [ ! -d $path/${program}${ext} ]; then - if [ "$echo" = "yes" ]; then + if [ "x$echo" = "xyes" ]; then echo $path/${program}${ext} fi exit 0 1.3 +4 -4 apache-apr/pthreads/src/helpers/TestCompile Index: TestCompile =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/TestCompile,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- TestCompile 1999/02/07 06:29:16 1.2 +++ TestCompile 1999/03/17 17:00:57 1.3 @@ -62,7 +62,7 @@ exit fi TLIB="-l$2" - if [ "$VERBOSE" = "yes" ]; then + if [ "x$VERBOSE" = "xyes" ]; then ERRDIR="" else ERRDIR='2>/dev/null' @@ -76,7 +76,7 @@ ;; "sanity") TLIB="" - if [ "$VERBOSE" = "no" ]; then + if [ "x$VERBOSE" = "xno" ]; then ERRDIR='2>/dev/null' else ERRDIR="" @@ -88,7 +88,7 @@ exit fi TLIB="" - if [ "$VERBOSE" = "yes" ]; then + if [ "x$VERBOSE" = "xyes" ]; then ERRDIR="" else ERRDIR='2>/dev/null' @@ -106,7 +106,7 @@ exit fi TLIB="" - if [ "$VERBOSE" = "yes" ]; then + if [ "x$VERBOSE" = "xyes" ]; then ERRDIR="" else ERRDIR='2>/dev/null' 1.2 +10 -10 apache-apr/pthreads/src/helpers/binbuild.sh Index: binbuild.sh =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/binbuild.sh,v retrieving revision 1.1 retrieving revision 1.2 diff -u -u -r1.1 -r1.2 --- binbuild.sh 1999/02/07 06:29:16 1.1 +++ binbuild.sh 1999/03/17 17:00:58 1.2 @@ -9,7 +9,7 @@ APDIR=`pwd` APDIR=`basename $APDIR` -VER=`echo $APDIR |sed s/apache-//` +VER=`echo $APDIR |sed s/apache_//` OS=`src/helpers/GuessOS` USER="`src/helpers/buildinfo.sh -n [EMAIL PROTECTED]" TAR="`src/helpers/PrintPath tar`" @@ -90,7 +90,7 @@ ./bindist/bin/httpd -V && \ echo "----------------------------------------------------------------------" \ ) > README.bindist -cp README.bindist ../apache-$VER-$OS.README +cp README.bindist ../apache_$VER-$OS.README ( echo " " && \ echo "Apache $VER binary installation" && \ @@ -192,28 +192,28 @@ else if [ "x$GTAR" != "x" ] then - $GTAR -zcf ../apache-$VER-$OS.tar.gz -C .. --owner=root --group=root apache-$VER + $GTAR -zcf ../apache_$VER-$OS.tar.gz -C .. --owner=root --group=root apache_$VER else if [ "x$TAR" != "x" ] then - $TAR -cf ../apache-$VER-$OS.tar -C .. apache-$VER + $TAR -cf ../apache_$VER-$OS.tar -C .. apache_$VER if [ "x$GZIP" != "x" ] then - $GZIP ../apache-$VER-$OS.tar + $GZIP ../apache_$VER-$OS.tar fi else echo "ERROR: Could not find a 'tar' program!" echo " Please execute the following commands manually:" - echo " tar -cf ../apache-$VER-$OS.tar ." - echo " gzip ../apache-$VER-$OS.tar" + echo " tar -cf ../apache_$VER-$OS.tar ." + echo " gzip ../apache_$VER-$OS.tar" fi fi - if [ -f ../apache-$VER-$OS.tar.gz ] && [ -f ../apache-$VER-$OS.README ] + if [ -f ../apache_$VER-$OS.tar.gz ] && [ -f ../apache_$VER-$OS.README ] then echo "Ready." - echo "You can find the binary archive (apache-$VER-$OS.tar.gz)" - echo "and the readme file (apache-$VER-$OS.README) in the" + echo "You can find the binary archive (apache_$VER-$OS.tar.gz)" + echo "and the readme file (apache_$VER-$OS.README) in the" echo "parent directory." exit 0; else 1.3 +1 -1 apache-apr/pthreads/src/helpers/buildinfo.sh Index: buildinfo.sh =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/buildinfo.sh,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- buildinfo.sh 1999/02/07 06:29:16 1.2 +++ buildinfo.sh 1999/03/17 17:00:58 1.3 @@ -19,7 +19,7 @@ if [ $# -eq 2 -a "x$1" != "x-n" ]; then error=yes fi -if [ "$error" = "yes" ]; then +if [ "x$error" = "xyes" ]; then echo "$0:Error: invalid argument line" echo "$0:Usage: $0 [-n] <format-string>" echo "Where <format-string> can contain:" 1.2 +3 -3 apache-apr/pthreads/src/helpers/find-dbm-lib Index: find-dbm-lib =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/find-dbm-lib,v retrieving revision 1.1 retrieving revision 1.2 diff -u -u -r1.1 -r1.2 --- find-dbm-lib 1999/01/21 23:08:32 1.1 +++ find-dbm-lib 1999/03/17 17:00:59 1.2 @@ -18,13 +18,13 @@ elif ./helpers/TestCompile lib ndbm dbm_open; then DBM_LIB="-lndbm" fi - if [ "X$DBM_LIB" != "X" ]; then + if [ "x$DBM_LIB" != "x" ]; then LIBS="$LIBS $DBM_LIB" found_dbm=1 fi ;; *) - if [ "X$DBM_LIB" != "X" ]; then + if [ "x$DBM_LIB" != "x" ]; then oldLIBS="$LIBS" LIBS="$LIBS $DBM_LIB" if ./helpers/TestCompile func dbm_open; then @@ -36,7 +36,7 @@ fi ;; esac - if [ "X$found_dbm" = "X1" ]; then + if [ "x$found_dbm" = "x1" ]; then echo " + using $DBM_LIB for DBM support" fi fi 1.3 +5 -1 apache-apr/pthreads/src/helpers/install.sh Index: install.sh =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/install.sh,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- install.sh 1999/02/07 06:29:17 1.2 +++ install.sh 1999/03/17 17:00:59 1.3 @@ -51,7 +51,11 @@ shift; shift; continue ;; -s) stripcmd="$stripprog" - shift; continue;; + shift; continue + ;; + -S) stripcmd="$stripprog $2" + shift; shift; continue + ;; *) if [ "x$src" = "x" ]; then src=$1 else 1.3 +1 -1 apache-apr/pthreads/src/helpers/slo.sh Index: slo.sh =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/slo.sh,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- slo.sh 1999/02/07 06:29:17 1.2 +++ slo.sh 1999/03/17 17:01:00 1.3 @@ -22,7 +22,7 @@ for opt do # concatenate with previous option if exists - if [ "$optprev" != "" ]; then + if [ "x$optprev" != "x" ]; then opt="${optprev}${opt}"; optprev='' fi 1.4 +1 -1 apache-apr/pthreads/src/include/alloc.h Index: alloc.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/alloc.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- alloc.h 1999/02/18 18:36:37 1.3 +++ alloc.h 1999/03/17 17:01:06 1.4 @@ -343,7 +343,7 @@ }; typedef struct child_info child_info; -API_EXPORT(void) ap_note_subprocess(pool *a, int pid, +API_EXPORT(void) ap_note_subprocess(pool *a, pid_t pid, enum kill_conditions how); API_EXPORT(int) ap_spawn_child(pool *, int (*)(void *, child_info *), void *, enum kill_conditions, 1.3 +10 -2 apache-apr/pthreads/src/include/ap_config.h Index: ap_config.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/ap_config.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- ap_config.h 1999/02/07 06:29:20 1.2 +++ ap_config.h 1999/03/17 17:01:07 1.3 @@ -95,7 +95,9 @@ * means. In particular it's missing inline and the __attribute__ * stuff. So we hack around it. PR#1613. -djg */ -#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 7 || defined(NEXT) +#if !defined(__GNUC__) || __GNUC__ < 2 || \ + (__GNUC__ == 2 && __GNUC_MINOR__ < 7) ||\ + defined(NEXT) #define ap_inline #define __attribute__(__x) #define ENUM_BITFIELD(e,n,w) signed int n : w @@ -458,7 +460,13 @@ #define USE_MMAP_FILES /* flock is faster ... but hasn't been tested on 1.x systems */ -#define USE_FLOCK_SERIALIZED_ACCEPT +/* PR#3531 indicates flock() may not be stable, probably depends on + * kernel version. Go back to using fcntl, but provide a way for + * folks to tweak their Configuration to get flock. + */ +#ifndef USE_FLOCK_SERIALIZED_ACCEPT +#define USE_FCNTL_SERIALIZED_ACCEPT +#endif #define SYS_SIGLIST _sys_siglist 1.3 +1 -0 apache-apr/pthreads/src/include/ap_ctype.h Index: ap_ctype.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/ap_ctype.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- ap_ctype.h 1999/02/07 06:29:21 1.2 +++ ap_ctype.h 1999/03/17 17:01:08 1.3 @@ -79,6 +79,7 @@ #define ap_ispunct(c) (ispunct(((unsigned char)(c)))) #define ap_isspace(c) (isspace(((unsigned char)(c)))) #define ap_isupper(c) (isupper(((unsigned char)(c)))) +#define ap_isxdigit(c) (isxdigit(((unsigned char)(c)))) #define ap_tolower(c) (tolower(((unsigned char)(c)))) #define ap_toupper(c) (toupper(((unsigned char)(c)))) 1.3 +11 -8 apache-apr/pthreads/src/include/ap_mmn.h Index: ap_mmn.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/ap_mmn.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- ap_mmn.h 1999/02/07 06:29:21 1.2 +++ ap_mmn.h 1999/03/17 17:01:08 1.3 @@ -203,13 +203,16 @@ * scan_script_header -> ap_scan_script_header_err * - reordered entries in request_rec that were waiting * for a non-binary-compatible release. - * 19990108-1 - add ap_find_opaque_token() for things like ETags - * (1.3.5-dev) which can contain opaque quoted strings, and - * ap_MD5Encode() for MD5 password handling. - * 19990108-2 - add ap_validate_password() and change ap_MD5Encode() - * (1.3.5-dev) to use a stronger algorithm (which is incompatible - * with the one introduced [but not released] with - * 19990108-1). + * (1.3.5-dev) + * 19990108.1 - add ap_MD5Encode() for MD5 password handling. + * 19990108.2 - add ap_validate_password() and change ap_MD5Encode() + * to use a stronger algorithm. + * 19990108.4 - add ap_size_list_item(), ap_get_list_item(), and + * ap_find_list_item() + * 19990108.5 - added ap_sub_req_method_uri() and added const to the + * definition of method in request_rec. + * 19990108.6 - SIGPIPE is now ignored by the core server. + * 19990108.7 - ap_isxdigit added */ #define MODULE_MAGIC_COOKIE 0x41503133UL /* "AP13" */ @@ -217,7 +220,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 19990108 #endif -#define MODULE_MAGIC_NUMBER_MINOR 2 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 7 /* 0...n */ #define MODULE_MAGIC_NUMBER MODULE_MAGIC_NUMBER_MAJOR /* backward compat */ /* Useful for testing for features. */ 1.3 +0 -1 apache-apr/pthreads/src/include/http_config.h Index: http_config.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/http_config.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- http_config.h 1999/02/07 06:29:21 1.2 +++ http_config.h 1999/03/17 17:01:09 1.3 @@ -344,7 +344,6 @@ /* For mod_so.c... */ void ap_single_module_configure(pool *p, server_rec *s, module *m); -void ap_single_module_init(pool *p, server_rec *s, module *m); /* For http_main.c... */ 1.3 +3 -0 apache-apr/pthreads/src/include/http_request.h Index: http_request.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/http_request.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- http_request.h 1999/02/07 06:29:22 1.2 +++ http_request.h 1999/03/17 17:01:09 1.3 @@ -86,6 +86,9 @@ const request_rec *r); API_EXPORT(request_rec *) ap_sub_req_lookup_file(const char *new_file, const request_rec *r); +API_EXPORT(request_rec *) ap_sub_req_method_uri(const char *method, + const char *new_file, + const request_rec *r); API_EXPORT(int) ap_run_sub_req(request_rec *r); API_EXPORT(void) ap_destroy_sub_req(request_rec *r); 1.12 +6 -4 apache-apr/pthreads/src/include/httpd.h Index: httpd.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/httpd.h,v retrieving revision 1.11 retrieving revision 1.12 diff -u -u -r1.11 -r1.12 --- httpd.h 1999/03/15 14:26:48 1.11 +++ httpd.h 1999/03/17 17:01:10 1.12 @@ -682,14 +682,14 @@ time_t request_time; /* When the request started */ - char *status_line; /* Status line, if set by script */ + const 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. */ + const char *method; /* GET, HEAD, POST, etc. */ int method_number; /* M_GET, M_POST, etc. */ /* @@ -954,10 +954,12 @@ API_EXPORT(char *) ap_getword_conf(pool *p, const char **line); API_EXPORT(char *) ap_getword_conf_nc(pool *p, char **line); +API_EXPORT(const char *) ap_size_list_item(const char **field, int *len); +API_EXPORT(char *) ap_get_list_item(pool *p, const char **field); +API_EXPORT(int) ap_find_list_item(pool *p, const char *line, const char *tok); + API_EXPORT(char *) ap_get_token(pool *p, const char **accept_line, int accept_white); API_EXPORT(int) ap_find_token(pool *p, const char *line, const char *tok); -API_EXPORT(int) ap_find_opaque_token(pool *p, const char *line, - const char *tok); API_EXPORT(int) ap_find_last_token(pool *p, const char *line, const char *tok); API_EXPORT(int) ap_is_url(const char *u); 1.4 +9 -7 apache-apr/pthreads/src/main/alloc.c Index: alloc.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/alloc.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- alloc.c 1999/02/07 06:29:29 1.3 +++ alloc.c 1999/03/17 17:01:16 1.4 @@ -1976,8 +1976,8 @@ struct process_chain *next; }; -API_EXPORT(void) ap_note_subprocess(pool *a, int pid, enum kill_conditions how) -{ +API_EXPORT(void) ap_note_subprocess(pool *a, pid_t pid, enum kill_conditions +how) { struct process_chain *new = (struct process_chain *) ap_palloc(a, sizeof(struct process_chain)); @@ -2000,11 +2000,11 @@ #define BINMODE #endif -static int spawn_child_core(pool *p, int (*func) (void *, child_info *), +static pid_t spawn_child_core(pool *p, int (*func) (void *, child_info *), void *data,enum kill_conditions kill_how, APRFile *pipe_in, APRFile *pipe_out, APRFile *pipe_err) { - int pid; + pid_t pid; APRFile in_fds[2]; APRFile out_fds[2]; APRFile err_fds[2]; @@ -2198,7 +2198,8 @@ FILE **pipe_err) { APRFile fd_in, fd_out, fd_err; - int pid, save_errno; + pid_t pid; + int save_errno; pid = spawn_child_core(p, func, data, kill_how, @@ -2255,7 +2256,7 @@ HANDLE hPipeOutputReadDup = NULL; HANDLE hPipeErrorReadDup = NULL; HANDLE hCurrentProcess; - int pid = 0; + pid_t pid = 0; child_info info; @@ -2426,7 +2427,8 @@ #else APRFile fd_in, fd_out, fd_err; - int pid, save_errno; + pid_t pid; + int save_errno; pid = spawn_child_core(p, func, data, kill_how, 1.6 +3 -1 apache-apr/pthreads/src/main/buff.c Index: buff.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/buff.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -u -r1.5 -r1.6 --- buff.c 1999/03/15 18:22:31 1.5 +++ buff.c 1999/03/17 17:01:16 1.6 @@ -1328,8 +1328,10 @@ if (cbuf != NULL) free(cbuf); cbuf = malloc(csize = nbyte+HUGE_STRING_LEN); - if (cbuf == NULL) + if (cbuf == NULL) { + fprintf(stderr, "Ouch! Out of memory in ap_bwrite()!\n"); csize = 0; + } } ebcdic2ascii((cbuf) ? cbuf : (void*)buf, buf, nbyte); buf = (cbuf) ? cbuf : buf; 1.3 +1 -9 apache-apr/pthreads/src/main/gen_test_char.c Index: gen_test_char.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/gen_test_char.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- gen_test_char.c 1999/02/07 06:29:30 1.2 +++ gen_test_char.c 1999/03/17 17:01:17 1.3 @@ -8,7 +8,6 @@ #define T_ESCAPE_PATH_SEGMENT (0x02) #define T_OS_ESCAPE_PATH (0x04) #define T_HTTP_TOKEN_STOP (0x08) -#define T_HTTP_OPAQUETOKEN_STOP (0x10) int main(int argc, char *argv[]) { @@ -21,15 +20,13 @@ "#define T_ESCAPE_PATH_SEGMENT (%u)\n" "#define T_OS_ESCAPE_PATH (%u)\n" "#define T_HTTP_TOKEN_STOP (%u)\n" -"#define T_HTTP_OPAQUETOKEN_STOP (%u)\n" "\n" "static const unsigned char test_char_table[256] = {\n" " 0,", T_ESCAPE_SHELL_CMD, T_ESCAPE_PATH_SEGMENT, T_OS_ESCAPE_PATH, - T_HTTP_TOKEN_STOP, - T_HTTP_OPAQUETOKEN_STOP); + T_HTTP_TOKEN_STOP); /* we explicitly dealt with NUL above * in case some strchr() do bogosity with it */ @@ -55,11 +52,6 @@ /* these are the "tspecials" from RFC2068 */ if (ap_iscntrl(c) || strchr(" \t()<>@,;:\\/[]?={}", c)) { flags |= T_HTTP_TOKEN_STOP; - } - - /* some tokens (like etags) are opaque strings; stop at the end */ - if (ap_iscntrl(c) || strchr(" ,", c)) { - flags |= T_HTTP_OPAQUETOKEN_STOP; } printf("%u%c", flags, (c < 255) ? ',' : ' '); 1.11 +7 -9 apache-apr/pthreads/src/main/http_config.c Index: http_config.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_config.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -u -r1.10 -r1.11 --- http_config.c 1999/03/16 22:07:55 1.10 +++ http_config.c 1999/03/17 17:01:18 1.11 @@ -327,6 +327,9 @@ } } method_ptrs = malloc((how_many_ptrs + NMETHODS) * sizeof(handler_func)); + if (method_ptrs == NULL) { + fprintf(stderr, "Ouch! Out of memory in build_method_shortcuts()!\n"); + } next_ptr = 0; for (i = 0; i < NMETHODS; ++i) { /* XXX: This is an itsy bit presumptuous about the alignment @@ -693,6 +696,9 @@ */ ap_loaded_modules = (module **)malloc( sizeof(module *)*(total_modules+DYNAMIC_MODULE_LIMIT+1)); + if (ap_loaded_modules == NULL) { + fprintf(stderr, "Ouch! Out of memory in ap_setup_prelinked_modules()!\n"); + } for (m = ap_preloaded_modules, m2 = ap_loaded_modules; *m != NULL; ) *m2++ = *m++; *m2 = NULL; @@ -1069,7 +1075,7 @@ */ static cmd_parms default_parms = -{NULL, 0, -1, NULL, NULL, NULL, NULL, NULL, NULL}; +{NULL, 0, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; API_EXPORT(char *) ap_server_root_relative(pool *p, char *file) { @@ -1486,14 +1492,6 @@ if (m->create_dir_config) ap_set_module_config(s->lookup_defaults, m, (*m->create_dir_config)(p, NULL)); -} - -void ap_single_module_init(pool *p, server_rec *s, module *m) -{ - if (m->init) - (*m->init)(s, p); - build_method_shortcuts(); - init_handlers(p); } void ap_init_modules(pool *p, server_rec *s) 1.11 +31 -16 apache-apr/pthreads/src/main/http_core.c Index: http_core.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_core.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -u -r1.10 -r1.11 --- http_core.c 1999/03/15 15:34:50 1.10 +++ http_core.c 1999/03/17 17:01:18 1.11 @@ -348,7 +348,7 @@ * See directory_walk(). */ -#if defined(OS2) || defined(WIN32) +#ifdef HAVE_DRIVE_LETTERS #define IS_SPECIAL(entry_core) \ ((entry_core)->r != NULL \ || ((entry_core)->d[0] != '/' && (entry_core)->d[1] != ':')) @@ -1075,7 +1075,7 @@ if (error_number == 401 && line[0] != '/' && line[0] != '"') { /* Ignore it... */ - ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, NULL, + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, cmd->server, "cannot use a full URL in a 401 ErrorDocument " "directive --- ignoring!"); } @@ -1246,6 +1246,7 @@ const char *arg) { const char *limited_methods = ap_getword(cmd->pool, &arg, '>'); + void *tog = cmd->cmd->cmd_data; int limited = 0; const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); @@ -1254,7 +1255,7 @@ } /* XXX: NB: Currently, we have no way of checking - * whether <Limit> sections are closed properly. + * whether <Limit> or <LimitExcept> sections are closed properly. * (If we would add a srm_command_loop() here we might...) */ @@ -1262,26 +1263,31 @@ char *method = ap_getword_conf(cmd->pool, &limited_methods); int methnum = ap_method_number_of(method); - if (methnum == M_TRACE) { + if (methnum == M_TRACE && !tog) { return "TRACE cannot be controlled by <Limit>"; } else if (methnum == M_INVALID) { - return ap_pstrcat(cmd->pool, "unknown method \"", - method, "\" in <Limit>", NULL); + return ap_pstrcat(cmd->pool, "unknown method \"", method, + "\" in <Limit", tog ? "Except>" : ">", NULL); } else { limited |= (1 << methnum); } } - cmd->limited = limited; + /* Killing two features with one function, + * if (tog == NULL) <Limit>, else <LimitExcept> + */ + cmd->limited = tog ? ~limited : limited; return NULL; } static const char *endlimit_section(cmd_parms *cmd, void *dummy, void *dummy2) { + void *tog = cmd->cmd->cmd_data; + if (cmd->limited == -1) { - return "</Limit> unexpected"; + return tog ? "</LimitExcept> unexpected" : "</Limit> unexpected"; } cmd->limited = -1; @@ -1901,7 +1907,7 @@ "Error:\tApache has not been designed to serve pages while\n" "\trunning as root. There are known race conditions that\n" "\twill allow any local user to read any file on the system.\n" - "\tShould you still desire to serve pages as root then\n" + "\tIf you still desire to serve pages as root then\n" "\tadd -DBIG_SECURITY_HOLE to the EXTRA_CFLAGS line in your\n" "\tsrc/Configuration file and rebuild the server. It is\n" "\tstrongly suggested that you instead modify the User\n" @@ -2721,6 +2727,11 @@ "authentication directives when accessed using specified HTTP methods" }, { "</Limit>", endlimit_section, NULL, OR_ALL, NO_ARGS, "Marks end of <Limit>" }, +{ "<LimitExcept", ap_limit_section, (void*)1, OR_ALL, RAW_ARGS, + "Container for authentication directives to be applied when any HTTP " + "method other than those specified is used to access the resource" }, +{ "</LimitExcept>", endlimit_section, (void*)1, OR_ALL, NO_ARGS, + "Marks end of <LimitExcept>" }, { "<IfModule", start_ifmod, NULL, OR_ALL, TAKE1, "Container for directives based on existance of specified modules" }, { end_ifmodule_section, end_ifmod, NULL, OR_ALL, NO_ARGS, @@ -2898,6 +2909,10 @@ { "BS2000Account", set_bs2000_account, NULL, RSRC_CONF, TAKE1, "Name of server User's bs2000 logon account name" }, #endif +#ifdef WIN32 +{ "ScriptInterpreterSource", set_interpreter_source, NULL, OR_FILEINFO, TAKE1, + "Where to find interpreter to run Win32 scripts (Registry or script shebang line)" }, +#endif { "ServerTokens", set_serv_tokens, NULL, RSRC_CONF, TAKE1, "Determine tokens displayed in the Server: header - Min(imal), OS or Full" }, { "LimitRequestLine", set_limit_req_line, NULL, RSRC_CONF, TAKE1, @@ -2910,11 +2925,7 @@ (void*)XtOffsetOf(core_dir_config, limit_req_body), OR_ALL, TAKE1, "Limit (in bytes) on maximum size of request message body" }, -#ifdef WIN32 -{ "ScriptInterpreterSource", set_interpreter_source, NULL, OR_FILEINFO, TAKE1, - "Where to find interpreter to run Win32 scripts (Registry or script shebang line)" }, -#endif -{ NULL }, +{ NULL } }; /***************************************************************** @@ -2976,7 +2987,11 @@ { struct mmap *mmd = mmv; - munmap(mmd->mm, mmd->length); + if (munmap(mmd->mm, mmd->length) == -1) { + ap_log_error(APLOG_MARK, APLOG_ERR, NULL, + "Failed to munmap memory of length %ld at 0x%lx", + (long) mmd->length, (long) mmd->mm); + } } #endif @@ -3158,7 +3173,7 @@ static const handler_rec core_handlers[] = { { "*/*", default_handler }, { "default-handler", default_handler }, -{ NULL } +{ NULL, NULL } }; API_VAR_EXPORT module core_module = { 1.4 +1 -2 apache-apr/pthreads/src/main/http_log.c Index: http_log.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_log.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- http_log.c 1999/03/16 22:07:55 1.3 +++ http_log.c 1999/03/17 17:01:19 1.4 @@ -324,8 +324,7 @@ } if (logf) { - len = ap_snprintf(errstr, sizeof(errstr), "%s: [%s] ", - ap_server_argv0, ap_get_time()); + len = ap_snprintf(errstr, sizeof(errstr), "[%s] ", ap_get_time()); } else { len = 0; } 1.61 +9 -0 apache-apr/pthreads/src/main/http_main.c Index: http_main.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_main.c,v retrieving revision 1.60 retrieving revision 1.61 diff -u -u -r1.60 -r1.61 --- http_main.c 1999/03/16 22:07:55 1.60 +++ http_main.c 1999/03/17 17:01:20 1.61 @@ -1157,6 +1157,11 @@ if (sigaction(SIGXFSZ, &sa, NULL) < 0) ap_log_error(APLOG_MARK, APLOG_WARNING, server_conf, "sigaction(SIGXFSZ)"); #endif +#ifdef SIGPIPE + sa.sa_handler = SIG_IGN; + if (sigaction(SIGPIPE, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, server_conf, "sigaction(SIGPIPE)"); +#endif /* we want to ignore HUPs and WINCH while we're busy processing one */ sigaddset(&sa.sa_mask, SIGHUP); @@ -1196,6 +1201,10 @@ #ifdef SIGWINCH signal(SIGWINCH, restart); #endif /* SIGWINCH */ +#ifdef SIGPIPE + signal(SIGPIPE, SIG_IGN); +#endif /* SIGPIPE */ + #endif } 1.11 +208 -132 apache-apr/pthreads/src/main/http_protocol.c Index: http_protocol.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_protocol.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -u -r1.10 -r1.11 --- http_protocol.c 1999/03/16 22:07:55 1.10 +++ http_protocol.c 1999/03/17 17:01:21 1.11 @@ -145,16 +145,18 @@ return 0; } - /* Check the If-Range header for Etag or Date */ - + /* Check the If-Range header for Etag or Date. + * Note that this check will return false (as required) if either + * of the two etags are weak. + */ if ((if_range = ap_table_get(r->headers_in, "If-Range"))) { if (if_range[0] == '"') { if (!(match = ap_table_get(r->headers_out, "Etag")) || - (strcasecmp(if_range, match) != 0)) + (strcmp(if_range, match) != 0)) return 0; } else if (!(match = ap_table_get(r->headers_out, "Last-Modified")) || - (strcasecmp(if_range, match) != 0)) + (strcmp(if_range, match) != 0)) return 0; } @@ -402,14 +404,14 @@ mtime = (r->mtime != 0) ? r->mtime : time(NULL); /* If an If-Match request-header field was given - * AND if our ETag does not match any of the entity tags in that field - * AND the field value is not "*" (meaning match anything), then + * AND the field value is not "*" (meaning match anything) + * AND if our strong ETag does not match any entity tag in that field, * respond with a status of 412 (Precondition Failed). */ if ((if_match = ap_table_get(r->headers_in, "If-Match")) != NULL) { - if ((etag == NULL) || - ((if_match[0] != '*') - && !ap_find_opaque_token(r->pool, if_match, etag))) { + if (if_match[0] != '*' && + (etag == NULL || etag[0] == 'W' || + !ap_find_list_item(r->pool, if_match, etag))) { return HTTP_PRECONDITION_FAILED; } } @@ -432,24 +434,39 @@ } /* If an If-None-Match request-header field was given - * AND if our ETag matches any of the entity tags in that field - * OR if the field value is "*" (meaning match anything), then - * if the request method was GET or HEAD, the server SHOULD - * respond with a 304 (Not Modified) response. - * For all other request methods, the server MUST - * respond with a status of 412 (Precondition Failed). + * AND the field value is "*" (meaning match anything) + * OR our ETag matches any of the entity tags in that field, fail. + * + * If the request method was GET or HEAD, failure means the server + * SHOULD respond with a 304 (Not Modified) response. + * For all other request methods, failure means the server MUST + * respond with a status of 412 (Precondition Failed). + * + * GET or HEAD allow weak etag comparison, all other methods require + * strong comparison. We can only use weak if it's not a range request. */ if_nonematch = ap_table_get(r->headers_in, "If-None-Match"); if (if_nonematch != NULL) { - int rstatus; - - if ((if_nonematch[0] == '*') - || ((etag != NULL) - && ap_find_opaque_token(r->pool, if_nonematch, etag))) { - rstatus = (r->method_number == M_GET) ? HTTP_NOT_MODIFIED - : HTTP_PRECONDITION_FAILED; - return rstatus; + if (r->method_number == M_GET) { + if (if_nonematch[0] == '*') + return HTTP_NOT_MODIFIED; + if (etag != NULL) { + if (ap_table_get(r->headers_in, "Range")) { + if (etag[0] != 'W' && + ap_find_list_item(r->pool, if_nonematch, etag)) { + return HTTP_NOT_MODIFIED; + } + } + else if (strstr(if_nonematch, etag)) { + return HTTP_NOT_MODIFIED; + } + } } + else if (if_nonematch[0] == '*' || + (etag != NULL && + ap_find_list_item(r->pool, if_nonematch, etag))) { + return HTTP_PRECONDITION_FAILED; + } } /* Else if a valid If-Modified-Since request-header field was given * AND it is a GET or HEAD request @@ -940,7 +957,7 @@ ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "request failed: URI too long"); ap_send_error_response(r, 0); - ap_bflush(r->connection->client); + ap_rflush(r); ap_log_transaction(r); return r; } @@ -952,7 +969,7 @@ ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "request failed: error reading the headers"); ap_send_error_response(r, 0); - ap_bflush(r->connection->client); + ap_rflush(r); ap_log_transaction(r); return r; } @@ -970,7 +987,7 @@ r->header_only = 0; r->status = HTTP_BAD_REQUEST; ap_send_error_response(r, 0); - ap_bflush(r->connection->client); + ap_rflush(r); ap_log_transaction(r); return r; } @@ -1003,7 +1020,7 @@ "client sent HTTP/1.1 request without hostname " "(see RFC2068 section 9, and 14.23): %s", r->uri); ap_send_error_response(r, 0); - ap_bflush(r->connection->client); + ap_rflush(r); ap_log_transaction(r); return r; } @@ -1024,7 +1041,7 @@ "client sent an unrecognized expectation value of " "Expect: %s", expect); ap_send_error_response(r, 0); - ap_bflush(r->connection->client); + ap_rflush(r); (void) ap_discard_request_body(r); ap_log_transaction(r); return r; @@ -1157,7 +1174,7 @@ * and must be listed in order. */ -static char *status_lines[RESPONSE_CODES] = { +static const char * const status_lines[RESPONSE_CODES] = { "100 Continue", "101 Switching Protocols", "102 Processing", @@ -1255,8 +1272,7 @@ API_EXPORT_NONSTD(int) ap_send_header_field(request_rec *r, const char *fieldname, const char *fieldval) { - return (0 < ap_bvputs(r->connection->client, - fieldname, ": ", fieldval, "\015\012", NULL)); + return (0 < ap_rvputs(r, fieldname, ": ", fieldval, "\015\012", NULL)); } API_EXPORT(void) ap_basic_http_header(request_rec *r) @@ -1291,8 +1307,7 @@ /* Output the HTTP/1.x Status-Line and the Date and Server fields */ - ap_bvputs(r->connection->client, - protocol, " ", r->status_line, "\015\012", NULL); + ap_rvputs(r, protocol, " ", r->status_line, "\015\012", NULL); ap_send_header_field(r, "Date", ap_gm_timestr_822(r->pool, r->request_time)); ap_send_header_field(r, "Server", ap_get_server_version()); @@ -1375,9 +1390,9 @@ ap_rvputs(r, r->the_request, "\015\012", NULL); - ap_table_do((int (*) (void *, const char *, const char *)) ap_send_header_field, - (void *) r, r->headers_in, NULL); - ap_bputs("\015\012", r->connection->client); + ap_table_do((int (*) (void *, const char *, const char *)) + ap_send_header_field, (void *) r, r->headers_in, NULL); + ap_rputs("\015\012", r); return OK; } @@ -1520,9 +1535,9 @@ r->chunked = 0; ap_bsetflag(r->connection->client, B_CHUNK, 0); - ap_bputs("0\015\012", r->connection->client); + ap_rputs("0\015\012", r); /* If we had footer "headers", we'd send them now */ - ap_bputs("\015\012", r->connection->client); + ap_rputs("\015\012", r); } } @@ -1630,10 +1645,9 @@ if (r->expecting_100 && r->proto_num >= HTTP_VERSION(1,1)) { /* sending 100 Continue interim response */ - ap_bvputs(r->connection->client, - SERVER_PROTOCOL, " ", status_lines[0], "\015\012\015\012", - NULL); - ap_bflush(r->connection->client); + ap_rvputs(r, SERVER_PROTOCOL, " ", status_lines[0], "\015\012\015\012", + NULL); + ap_rflush(r); } return 1; @@ -1643,7 +1657,7 @@ { long chunksize = 0; - while (isxdigit(*b)) { + while (ap_isxdigit(*b)) { int xvalue = 0; if (*b >= '0' && *b <= '9') @@ -1721,7 +1735,7 @@ chunk_start = getline(buffer, bufsiz, r->connection->client, 0, 0); if ((chunk_start <= 0) || (chunk_start >= (bufsiz - 1)) - || !isxdigit(*buffer)) { + || !ap_isxdigit(*buffer)) { r->connection->keepalive = -1; return -1; } @@ -1890,25 +1904,18 @@ while (n && !ap_is_aborted(r->connection)) { w = ap_bwrite(r->connection->client, &buf[o], n, 0); if (w > 0) { - total_bytes_sent += w; + total_bytes_sent += w; n -= w; o += w; } else if (w < 0) { - if (ap_is_aborted(r->connection)) - break; -#if 0 - /* ZZZ: should we rethink this? */ - else if (errno == EAGAIN) - continue; -#endif - else { + if (!ap_is_aborted(r->connection)) { ap_log_rerror(APLOG_MARK, APLOG_INFO, r, "client stopped connection before send body completed"); ap_bsetflag(r->connection->client, B_EOUT, 1); r->connection->aborted = 1; - break; } + break; } } } @@ -1980,10 +1987,15 @@ break; if (n < 0 && errno != EAGAIN /* ZZZ rethink for threaded impl */) break; + /* we need to block, so flush the output first */ - ap_bflush(r->connection->client); - if (ap_is_aborted(r->connection)) + if (ap_bflush(r->connection->client) < 0) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before send body completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; break; + } /* * we don't care what poll says, we might as well loop back * around and try another read @@ -1998,30 +2010,23 @@ if (n < 1 || ap_is_aborted(r->connection)) { break; } - o = 0; - total_bytes_sent += n; while (n && !ap_is_aborted(r->connection)) { w = ap_bwrite(r->connection->client, &buf[o], n, 0); if (w > 0) { + total_bytes_sent += w; n -= w; o += w; } else if (w < 0) { - if (ap_is_aborted(r->connection)) - break; -#if 1 /*rethink for threaded impl */ - else if (errno == EAGAIN) - continue; -#endif - else { + if (!ap_is_aborted(r->connection)) { ap_log_rerror(APLOG_MARK, APLOG_INFO, r, - "client stopped connection before send body completed"); + "client stopped connection before send body completed"); ap_bsetflag(r->connection->client, B_EOUT, 1); r->connection->aborted = 1; - break; } + break; } } } @@ -2095,8 +2100,17 @@ API_EXPORT(int) ap_rputc(int c, request_rec *r) { if (r->connection->aborted) + return EOF; + + if (ap_bputc(c, r->connection->client) < 0) { + if (!r->connection->aborted) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before rputc completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; + } return EOF; - ap_bputc(c, r->connection->client); + } SET_BYTES_SENT(r); return c; } @@ -2107,7 +2121,17 @@ if (r->connection->aborted) return EOF; + rcode = ap_bputs(str, r->connection->client); + if (rcode < 0) { + if (!r->connection->aborted) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before rputs completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; + } + return EOF; + } SET_BYTES_SENT(r); return rcode; } @@ -2115,9 +2139,20 @@ API_EXPORT(int) ap_rwrite(const void *buf, int nbyte, request_rec *r) { int n; + if (r->connection->aborted) - return EOF; + return -1; + n = ap_bwrite(r->connection->client, buf, nbyte, 0); + if (n < 0) { + if (!r->connection->aborted) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before rwrite completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; + } + return -1; + } SET_BYTES_SENT(r); return n; } @@ -2128,10 +2163,21 @@ int n; if (r->connection->aborted) - return EOF; + return -1; + va_start(vlist, fmt); n = ap_vbprintf(r->connection->client, fmt, vlist); va_end(vlist); + + if (n < 0) { + if (!r->connection->aborted) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before rprintf completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; + } + return -1; + } SET_BYTES_SENT(r); return n; } @@ -2155,7 +2201,13 @@ i = ap_bwrite(fb, x, j, 0); if (i != j) { va_end(args); - return -1; + if (!r->connection->aborted) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before rvputs completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; + } + return EOF; } k += i; } @@ -2167,7 +2219,16 @@ API_EXPORT(int) ap_rflush(request_rec *r) { - return ap_bflush(r->connection->client); + if (ap_bflush(r->connection->client) < 0) { + if (!r->connection->aborted) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before rflush completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; + } + return EOF; + } + return 0; } /* We should have named this send_canned_response, since it is used for any @@ -2178,7 +2239,6 @@ */ void ap_send_error_response(request_rec *r, int recursive_error) { - BUFF *fd = r->connection->client; int status = r->status; int idx = ap_index_of_response(status); char *custom_response; @@ -2267,7 +2327,7 @@ * the original error and output that as well. */ if (custom_response[0] == '\"') { - ap_bputs(custom_response + 1, fd); + ap_rputs(custom_response + 1, r); ap_finalize_request_protocol(r); return; } @@ -2278,8 +2338,8 @@ r = r->prev; } { - char *title = status_lines[idx]; - char *h1; + const char *title = status_lines[idx]; + const char *h1; const char *error_notes; /* Accept a status_line set by a module, but only if it begins @@ -2298,7 +2358,7 @@ /* folks decided they didn't want the error code in the H1 text */ h1 = &title[4]; - ap_bvputs(fd, + ap_rvputs(r, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" "<HTML><HEAD>\n<TITLE>", title, "</TITLE>\n</HEAD><BODY>\n<H1>", h1, "</H1>\n", @@ -2308,17 +2368,17 @@ case HTTP_MOVED_PERMANENTLY: case HTTP_MOVED_TEMPORARILY: case HTTP_TEMPORARY_REDIRECT: - ap_bvputs(fd, "The document has moved <A HREF=\"", + ap_rvputs(r, "The document has moved <A HREF=\"", ap_escape_html(r->pool, location), "\">here</A>.<P>\n", NULL); break; case HTTP_SEE_OTHER: - ap_bvputs(fd, "The answer to your request is located <A HREF=\"", + ap_rvputs(r, "The answer to your request is located <A HREF=\"", ap_escape_html(r->pool, location), "\">here</A>.<P>\n", NULL); break; case HTTP_USE_PROXY: - ap_bvputs(fd, "This resource is only accessible " + ap_rvputs(r, "This resource is only accessible " "through the proxy\n", ap_escape_html(r->pool, location), "<BR>\nYou will need to ", @@ -2326,38 +2386,38 @@ break; case HTTP_PROXY_AUTHENTICATION_REQUIRED: case AUTH_REQUIRED: - ap_bputs("This server could not verify that you\n", fd); - ap_bputs("are authorized to access the document you\n", fd); - ap_bputs("requested. Either you supplied the wrong\n", fd); - ap_bputs("credentials (e.g., bad password), or your\n", fd); - ap_bputs("browser doesn't understand how to supply\n", fd); - ap_bputs("the credentials required.<P>\n", fd); + ap_rputs("This server could not verify that you\n" + "are authorized to access the document\n" + "requested. Either you supplied the wrong\n" + "credentials (e.g., bad password), or your\n" + "browser doesn't understand how to supply\n" + "the credentials required.<P>\n", r); break; case BAD_REQUEST: - ap_bputs("Your browser sent a request that\n", fd); - ap_bputs("this server could not understand.<P>\n", fd); + ap_rputs("Your browser sent a request that " + "this server could not understand.<P>\n", r); if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) { - ap_bvputs(fd, error_notes, "<P>\n", NULL); + ap_rvputs(r, error_notes, "<P>\n", NULL); } break; case HTTP_FORBIDDEN: - ap_bvputs(fd, "You don't have permission to access ", + ap_rvputs(r, "You don't have permission to access ", ap_escape_html(r->pool, r->uri), "\non this server.<P>\n", NULL); break; case NOT_FOUND: - ap_bvputs(fd, "The requested URL ", + ap_rvputs(r, "The requested URL ", ap_escape_html(r->pool, r->uri), " was not found on this server.<P>\n", NULL); break; case METHOD_NOT_ALLOWED: - ap_bvputs(fd, "The requested method ", r->method, + ap_rvputs(r, "The requested method ", r->method, " is not allowed " "for the URL ", ap_escape_html(r->pool, r->uri), ".<P>\n", NULL); break; case NOT_ACCEPTABLE: - ap_bvputs(fd, + ap_rvputs(r, "An appropriate representation of the " "requested resource ", ap_escape_html(r->pool, r->uri), @@ -2367,44 +2427,47 @@ { const char *list; if ((list = ap_table_get(r->notes, "variant-list"))) - ap_bputs(list, fd); + ap_rputs(list, r); } break; case LENGTH_REQUIRED: - ap_bvputs(fd, "A request of the requested method ", r->method, + ap_rvputs(r, "A request of the requested method ", r->method, " requires a valid Content-length.<P>\n", NULL); if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) { - ap_bvputs(fd, error_notes, "<P>\n", NULL); + ap_rvputs(r, error_notes, "<P>\n", NULL); } break; case PRECONDITION_FAILED: - ap_bvputs(fd, "The precondition on the request for the URL ", + ap_rvputs(r, "The precondition on the request for the URL ", ap_escape_html(r->pool, r->uri), " evaluated to false.<P>\n", NULL); break; case HTTP_NOT_IMPLEMENTED: - ap_bvputs(fd, ap_escape_html(r->pool, r->method), " to ", + ap_rvputs(r, ap_escape_html(r->pool, r->method), " to ", ap_escape_html(r->pool, r->uri), " not supported.<P>\n", NULL); if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) { - ap_bvputs(fd, error_notes, "<P>\n", NULL); + ap_rvputs(r, error_notes, "<P>\n", NULL); } break; case BAD_GATEWAY: - ap_bputs("The proxy server received an invalid\015\012", fd); - ap_bputs("response from an upstream server.<P>\015\012", fd); + ap_rputs("The proxy server received an invalid\015\012" + "response from an upstream server.<P>\015\012", r); + if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) { + ap_rvputs(r, error_notes, "<P>\n", NULL); + } break; case VARIANT_ALSO_VARIES: - ap_bvputs(fd, "A variant for the requested resource\n<PRE>\n", + ap_rvputs(r, "A variant for the requested resource\n<PRE>\n", ap_escape_html(r->pool, r->uri), "\n</PRE>\nis itself a negotiable resource. " "This indicates a configuration error.<P>\n", NULL); break; case HTTP_REQUEST_TIME_OUT: - ap_bputs("I'm tired of waiting for your request.\n", fd); + ap_rputs("I'm tired of waiting for your request.\n", r); break; case HTTP_GONE: - ap_bvputs(fd, "The requested resource<BR>", + ap_rvputs(r, "The requested resource<BR>", ap_escape_html(r->pool, r->uri), "<BR>\nis no longer available on this server ", "and there is no forwarding address.\n", @@ -2412,30 +2475,30 @@ NULL); break; case HTTP_REQUEST_ENTITY_TOO_LARGE: - ap_bvputs(fd, "The requested resource<BR>", + ap_rvputs(r, "The requested resource<BR>", ap_escape_html(r->pool, r->uri), "<BR>\n", "does not allow request data with ", r->method, " requests, or the amount of data provided in\n", "the request exceeds the capacity limit.\n", NULL); break; case HTTP_REQUEST_URI_TOO_LARGE: - ap_bputs("The requested URL's length exceeds the capacity\n" - "limit for this server.<P>\n", fd); + ap_rputs("The requested URL's length exceeds the capacity\n" + "limit for this server.<P>\n", r); if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) { - ap_bvputs(fd, error_notes, "<P>\n", NULL); + ap_rvputs(r, error_notes, "<P>\n", NULL); } break; case HTTP_UNSUPPORTED_MEDIA_TYPE: - ap_bputs("The supplied request data is not in a format\n" - "acceptable for processing by this resource.\n", fd); + ap_rputs("The supplied request data is not in a format\n" + "acceptable for processing by this resource.\n", r); break; case HTTP_RANGE_NOT_SATISFIABLE: - ap_bputs("None of the range-specifier values in the Range\n" + ap_rputs("None of the range-specifier values in the Range\n" "request-header field overlap the current extent\n" - "of the selected resource.\n", fd); + "of the selected resource.\n", r); break; case HTTP_EXPECTATION_FAILED: - ap_bvputs(fd, "The expectation given in the Expect request-header" + ap_rvputs(r, "The expectation given in the Expect request-header" "\nfield could not be met by this server.<P>\n" "The client sent<PRE>\n Expect: ", ap_table_get(r->headers_in, "Expect"), "\n</PRE>\n" @@ -2443,42 +2506,54 @@ NULL); break; case HTTP_UNPROCESSABLE_ENTITY: - ap_bputs("The server understands the media type of the\n" + ap_rputs("The server understands the media type of the\n" "request entity, but was unable to process the\n" - "contained instructions.\n", fd); + "contained instructions.\n", r); break; case HTTP_LOCKED: - ap_bputs("The requested resource is currently locked.\n" + ap_rputs("The requested resource is currently locked.\n" "The lock must be released or proper identification\n" - "given before the method can be applied.\n", fd); + "given before the method can be applied.\n", r); break; case HTTP_FAILED_DEPENDENCY: - ap_bputs("The method could not be performed on the resource\n" + ap_rputs("The method could not be performed on the resource\n" "because the requested action depended on another\n" - "action and that other action failed.\n", fd); + "action and that other action failed.\n", r); break; case HTTP_INSUFFICIENT_STORAGE: - ap_bputs("The method could not be performed on the resource\n" + ap_rputs("The method could not be performed on the resource\n" "because the server is unable to store the\n" "representation needed to successfully complete the\n" "request. There is insufficient free space left in\n" - "your storage allocation.\n", fd); + "your storage allocation.\n", r); break; case HTTP_SERVICE_UNAVAILABLE: - ap_bputs("The server is temporarily unable to service your\n" + ap_rputs("The server is temporarily unable to service your\n" "request due to maintenance downtime or capacity\n" - "problems. Please try again later.\n", fd); + "problems. Please try again later.\n", r); break; case HTTP_GATEWAY_TIME_OUT: - ap_bputs("The proxy server did not receive a timely response\n" - "from the upstream server.\n", fd); + ap_rputs("The proxy server did not receive a timely response\n" + "from the upstream server.\n", r); break; case HTTP_NOT_EXTENDED: - ap_bputs("A mandatory extension policy in the request is not\n" - "accepted by the server for this resource.\n", fd); + ap_rputs("A mandatory extension policy in the request is not\n" + "accepted by the server for this resource.\n", r); break; default: /* HTTP_INTERNAL_SERVER_ERROR */ - ap_bvputs(fd, "The server encountered an internal error or\n" + /* + * This comparison to expose error-notes could be modified to + * use a configuration directive and export based on that + * directive. For now "*" is used to designate an error-notes + * that is totally safe for any user to see (ie lacks paths, + * database passwords, etc.) + */ + if (((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) + && (h1 = ap_table_get(r->notes, "verbose-error-to")) != NULL + && (strcmp(h1, "*") == 0)) { + ap_rvputs(r, error_notes, "<P>\n", NULL); + } else { + ap_rvputs(r, "The server encountered an internal error or\n" "misconfiguration and was unable to complete\n" "your request.<P>\n" "Please contact the server administrator,\n ", @@ -2488,6 +2563,7 @@ "caused the error.<P>\n" "More information about this error may be available\n" "in the server error log.<P>\n", NULL); + } /* * It would be nice to give the user the information they need to * fix the problem directly since many users don't have access to @@ -2498,20 +2574,20 @@ * can figure out a way to remove the pathname, leave this commented. * * if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) { - * ap_bvputs(fd, error_notes, "<P>\n", NULL); + * ap_rvputs(r, error_notes, "<P>\n", NULL); * } */ break; } if (recursive_error) { - ap_bvputs(fd, "<P>Additionally, a ", + ap_rvputs(r, "<P>Additionally, a ", status_lines[ap_index_of_response(recursive_error)], "\nerror was encountered while trying to use an " "ErrorDocument to handle the request.\n", NULL); } - ap_bputs(ap_psignature("<HR>\n", r), fd); - ap_bputs("</BODY></HTML>\n", fd); + ap_rputs(ap_psignature("<HR>\n", r), r); + ap_rputs("</BODY></HTML>\n", r); } ap_finalize_request_protocol(r); } 1.4 +18 -7 apache-apr/pthreads/src/main/http_request.c Index: http_request.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_request.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- http_request.c 1999/02/09 21:39:56 1.3 +++ http_request.c 1999/03/17 17:01:21 1.4 @@ -180,8 +180,8 @@ char *end = &path[strlen(path)]; char *last_cp = NULL; int rv; -#ifdef WIN32 - BOOL bStripSlash=TRUE; +#ifdef HAVE_DRIVE_LETTERS + char bStripSlash=1; #endif if (r->finfo.st_mode) { @@ -189,12 +189,12 @@ return OK; } -#ifdef WIN32 +#ifdef HAVE_DRIVE_LETTERS /* If the directory is x:\, then we don't want to strip * the trailing slash since x: is not a valid directory. */ if (strlen(path) == 3 && path[1] == ':' && path[2] == '/') - bStripSlash = FALSE; + bStripSlash = 0; /* If UNC name == //machine/share/, do not @@ -213,7 +213,7 @@ } if (iCount == 4) - bStripSlash = FALSE; + bStripSlash = 0; } if (bStripSlash) @@ -724,8 +724,9 @@ return rr; } -API_EXPORT(request_rec *) ap_sub_req_lookup_uri(const char *new_file, - const request_rec *r) +API_EXPORT(request_rec *) ap_sub_req_method_uri(const char *method, + const char *new_file, + const request_rec *r) { request_rec *rnew; int res; @@ -742,6 +743,10 @@ ap_set_sub_req_protocol(rnew, r); + /* would be nicer to pass "method" to ap_set_sub_req_protocol */ + rnew->method = method; + rnew->method_number = ap_method_number_of(method); + if (new_file[0] == '/') ap_parse_uri(rnew, new_file); else { @@ -800,6 +805,12 @@ rnew->status = res; } return rnew; +} + +API_EXPORT(request_rec *) ap_sub_req_lookup_uri(const char *new_file, + const request_rec *r) +{ + return ap_sub_req_method_uri("GET", new_file, r); } API_EXPORT(request_rec *) ap_sub_req_lookup_file(const char *new_file, 1.6 +4 -1 apache-apr/pthreads/src/main/scoreboard.c Index: scoreboard.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/scoreboard.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -u -r1.5 -r1.6 --- scoreboard.c 1999/03/07 00:47:50 1.5 +++ scoreboard.c 1999/03/17 17:01:22 1.6 @@ -47,6 +47,9 @@ { ap_assert(!ap_scoreboard_image); ap_scoreboard_image = (scoreboard *) malloc(SCOREBOARD_SIZE); + if (ap_scoreboard_image == NULL) { + fprintf(stderr, "Ouch! Out of memory reiniting scoreboard!\n"); + } memset(ap_scoreboard_image, 0, SCOREBOARD_SIZE); } @@ -309,7 +312,7 @@ static void setup_shared_mem(pool *p) { struct shmid_ds shmbuf; - server_rec * server_conf = ap_get_server_conf(); + const server_rec * server_conf = ap_get_server_conf(); #ifdef MOVEBREAK char *obrk; #endif 1.3 +257 -64 apache-apr/pthreads/src/main/util.c Index: util.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/util.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- util.c 1999/02/07 06:29:32 1.2 +++ util.c 1999/03/17 17:01:23 1.3 @@ -882,8 +882,8 @@ * line continuation requested - * then remove backslash and continue */ - cbuf = cp; cbufsize -= (cp-cbuf); + cbuf = cp; continue; } else { @@ -983,6 +983,258 @@ } } +/* Size an HTTP header field list item, as separated by a comma. + * The return value is a pointer to the beginning of the non-empty list item + * within the original string (or NULL if there is none) and the address + * of field is shifted to the next non-comma, non-whitespace character. + * len is the length of the item excluding any beginning whitespace. + */ +API_EXPORT(const char *) ap_size_list_item(const char **field, int *len) +{ + const unsigned char *ptr = (const unsigned char *)*field; + const unsigned char *token; + int in_qpair, in_qstr, in_com; + + /* Find first non-comma, non-whitespace byte */ + + while (*ptr == ',' || ap_isspace(*ptr)) + ++ptr; + + token = ptr; + + /* Find the end of this item, skipping over dead bits */ + + for (in_qpair = in_qstr = in_com = 0; + *ptr && (in_qpair || in_qstr || in_com || *ptr != ','); + ++ptr) { + + if (in_qpair) { + in_qpair = 0; + } + else { + switch (*ptr) { + case '\\': in_qpair = 1; /* quoted-pair */ + break; + case '"' : if (!in_com) /* quoted string delim */ + in_qstr = !in_qstr; + break; + case '(' : if (!in_qstr) /* comment (may nest) */ + ++in_com; + break; + case ')' : if (in_com) /* end comment */ + --in_com; + break; + default : break; + } + } + } + + if ((*len = (ptr - token)) == 0) { + *field = ptr; + return NULL; + } + + /* Advance field pointer to the next non-comma, non-white byte */ + + while (*ptr == ',' || ap_isspace(*ptr)) + ++ptr; + + *field = ptr; + return (const char *)token; +} + +/* Retrieve an HTTP header field list item, as separated by a comma, + * while stripping insignificant whitespace and lowercasing anything not in + * a quoted string or comment. The return value is a new string containing + * the converted list item (or NULL if none) and the address pointed to by + * field is shifted to the next non-comma, non-whitespace. + */ +API_EXPORT(char *) ap_get_list_item(pool *p, const char **field) +{ + const char *tok_start; + const unsigned char *ptr; + unsigned char *pos; + char *token; + int addspace = 0, in_qpair = 0, in_qstr = 0, in_com = 0, tok_len = 0; + + /* Find the beginning and maximum length of the list item so that + * we can allocate a buffer for the new string and reset the field. + */ + if ((tok_start = ap_size_list_item(field, &tok_len)) == NULL) { + return NULL; + } + token = ap_palloc(p, tok_len + 1); + + /* Scan the token again, but this time copy only the good bytes. + * We skip extra whitespace and any whitespace around a '=', '/', + * or ';' and lowercase normal characters not within a comment, + * quoted-string or quoted-pair. + */ + for (ptr = (const unsigned char *)tok_start, pos = (unsigned char *)token; + *ptr && (in_qpair || in_qstr || in_com || *ptr != ','); + ++ptr) { + + if (in_qpair) { + in_qpair = 0; + *pos++ = *ptr; + } + else { + switch (*ptr) { + case '\\': in_qpair = 1; + if (addspace == 1) + *pos++ = ' '; + *pos++ = *ptr; + addspace = 0; + break; + case '"' : if (!in_com) + in_qstr = !in_qstr; + if (addspace == 1) + *pos++ = ' '; + *pos++ = *ptr; + addspace = 0; + break; + case '(' : if (!in_qstr) + ++in_com; + if (addspace == 1) + *pos++ = ' '; + *pos++ = *ptr; + addspace = 0; + break; + case ')' : if (in_com) + --in_com; + *pos++ = *ptr; + addspace = 0; + break; + case ' ' : + case '\t': if (addspace) + break; + if (in_com || in_qstr) + *pos++ = *ptr; + else + addspace = 1; + break; + case '=' : + case '/' : + case ';' : if (!(in_com || in_qstr)) + addspace = -1; + *pos++ = *ptr; + break; + default : if (addspace == 1) + *pos++ = ' '; + *pos++ = (in_com || in_qstr) ? *ptr + : ap_tolower(*ptr); + addspace = 0; + break; + } + } + } + *pos = '\0'; + + return token; +} + +/* Find an item in canonical form (lowercase, no extra spaces) within + * an HTTP field value list. Returns 1 if found, 0 if not found. + * This would be much more efficient if we stored header fields as + * an array of list items as they are received instead of a plain string. + */ +API_EXPORT(int) ap_find_list_item(pool *p, const char *line, const char *tok) +{ + const unsigned char *pos; + const unsigned char *ptr = (const unsigned char *)line; + int good = 0, addspace = 0, in_qpair = 0, in_qstr = 0, in_com = 0; + + if (!line || !tok) + return 0; + + do { /* loop for each item in line's list */ + + /* Find first non-comma, non-whitespace byte */ + + while (*ptr == ',' || ap_isspace(*ptr)) + ++ptr; + + if (*ptr) + good = 1; /* until proven otherwise for this item */ + else + break; /* no items left and nothing good found */ + + /* We skip extra whitespace and any whitespace around a '=', '/', + * or ';' and lowercase normal characters not within a comment, + * quoted-string or quoted-pair. + */ + for (pos = (const unsigned char *)tok; + *ptr && (in_qpair || in_qstr || in_com || *ptr != ','); + ++ptr) { + + if (in_qpair) { + in_qpair = 0; + if (good) + good = (*pos++ == *ptr); + } + else { + switch (*ptr) { + case '\\': in_qpair = 1; + if (addspace == 1) + good = good && (*pos++ == ' '); + good = good && (*pos++ == *ptr); + addspace = 0; + break; + case '"' : if (!in_com) + in_qstr = !in_qstr; + if (addspace == 1) + good = good && (*pos++ == ' '); + good = good && (*pos++ == *ptr); + addspace = 0; + break; + case '(' : if (!in_qstr) + ++in_com; + if (addspace == 1) + good = good && (*pos++ == ' '); + good = good && (*pos++ == *ptr); + addspace = 0; + break; + case ')' : if (in_com) + --in_com; + good = good && (*pos++ == *ptr); + addspace = 0; + break; + case ' ' : + case '\t': if (addspace || !good) + break; + if (in_com || in_qstr) + good = (*pos++ == *ptr); + else + addspace = 1; + break; + case '=' : + case '/' : + case ';' : if (!(in_com || in_qstr)) + addspace = -1; + good = good && (*pos++ == *ptr); + break; + default : if (!good) + break; + if (addspace == 1) + good = (*pos++ == ' '); + if (in_com || in_qstr) + good = good && (*pos++ == *ptr); + else + good = good && (*pos++ == ap_tolower(*ptr)); + addspace = 0; + break; + } + } + } + if (good && *pos) + good = 0; /* not good if only a prefix was matched */ + + } while (*ptr && !good); + + return good; +} + + /* Retrieve a token, spacing over it and returning a pointer to * the first non-white byte afterwards. Note that these tokens * are delimited by semis and commas; and can also be delimited @@ -1062,67 +1314,6 @@ } } -/* - * Find opaque HTTP tokens, which have no internal semantics and end - * at the first unquoted ',' or ' '. - */ -API_EXPORT(int) ap_find_opaque_token(pool *p, const char *line, - const char *tok) -{ - const unsigned char *start_token; - const unsigned char *s; - char stop_quote = '\0'; - - if (!line) { - return 0; - } - - s = (const unsigned char *)line; - for (;;) { - /* - * Find start of token, skip all stop characters, note NUL - * isn't a token stop, so we don't need to test for it - */ - while (TEST_CHAR(*s, T_HTTP_OPAQUETOKEN_STOP)) { - ++s; - } - if (!*s) { - return 0; - } - start_token = s; - /* - * Find end of the token - */ - while (*s) { - /* - * If we see the beginning of a quoted string ("foo" or <foo>), - * mark the end character so we know when to stop skipping. - */ - if (!stop_quote && ((*s == '"') || (*s == '<'))) { - stop_quote = (*s == '"') ? '"' : '>'; - } - else if (*s == stop_quote) { - stop_quote = '\0'; - } - /* - * If we're not inside a quoted string, check to see if we're - * at the end of the token. - */ - else if (!stop_quote && TEST_CHAR(*s, T_HTTP_OPAQUETOKEN_STOP)) { - break; - } - ++s; - } - if (!strncmp((const char *)start_token, (const char *)tok, - s - start_token)) { - return 1; - } - if (!*s) { - return 0; - } - } -} - API_EXPORT(int) ap_find_last_token(pool *p, const char *line, const char *tok) { @@ -1212,7 +1403,7 @@ if (url[y] != '%') url[x] = url[y]; else { - if (!isxdigit(url[y + 1]) || !isxdigit(url[y + 2])) { + if (!ap_isxdigit(url[y + 1]) || !ap_isxdigit(url[y + 2])) { badesc = 1; url[x] = '%'; } @@ -1440,8 +1631,10 @@ { char *sdup; - if (!(sdup = (char *) malloc(strlen(str) + 1))) + if (!(sdup = (char *) malloc(strlen(str) + 1))) { + fprintf(stderr, "Ouch! Out of memory in our strdup()!\n"); return NULL; + } sdup = strcpy(sdup, str); return sdup; 1.3 +1 -1 apache-apr/pthreads/src/main/util_date.c Index: util_date.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/util_date.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- util_date.c 1999/02/07 06:29:32 1.2 +++ util_date.c 1999/03/17 17:01:24 1.3 @@ -109,7 +109,7 @@ return 0; break; case '&': - if (!isxdigit(d)) + if (!ap_isxdigit(d)) return 0; break; case '~': 1.4 +2 -0 apache-apr/pthreads/src/main/util_script.c Index: util_script.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/util_script.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- util_script.c 1999/03/15 14:26:50 1.3 +++ util_script.c 1999/03/17 17:01:25 1.4 @@ -492,6 +492,8 @@ ap_overlap_tables(r->err_headers_out, merge, AP_OVERLAP_TABLES_MERGE); if (!ap_is_empty_table(cookie_table)) { + /* the cookies have already been copied to the cookie_table */ + ap_table_unset(r->err_headers_out, "Set-Cookie"); r->err_headers_out = ap_overlay_tables(r->pool, r->err_headers_out, cookie_table); } 1.3 +1 -1 apache-apr/pthreads/src/modules/proxy/mod_proxy.c Index: mod_proxy.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/proxy/mod_proxy.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- mod_proxy.c 1999/02/07 06:29:47 1.2 +++ mod_proxy.c 1999/03/17 17:01:40 1.3 @@ -546,7 +546,7 @@ ap_get_module_config(s->module_config, &proxy_module); int *New; - if (!isdigit(arg[0])) + if (!ap_isdigit(arg[0])) return "AllowCONNECT: port number must be numeric"; New = ap_push_array(conf->allowed_connect_ports); 1.3 +1 -1 apache-apr/pthreads/src/modules/proxy/mod_proxy.h Index: mod_proxy.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/proxy/mod_proxy.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- mod_proxy.h 1999/02/07 06:29:47 1.2 +++ mod_proxy.h 1999/03/17 17:01:41 1.3 @@ -301,7 +301,7 @@ int ap_proxy_hex2sec(const char *x); void ap_proxy_sec2hex(int t, char *y); cache_req *ap_proxy_cache_error(cache_req *r); -int ap_proxyerror(request_rec *r, const char *message); +int ap_proxyerror(request_rec *r, int statuscode, const char *message); const char *ap_proxy_host2addr(const char *host, struct hostent *reqhp); int ap_proxy_is_ipaddr(struct dirconn_entry *This, pool *p); int ap_proxy_is_domainname(struct dirconn_entry *This, pool *p); 1.5 +1 -1 apache-apr/pthreads/src/modules/proxy/proxy_cache.c Index: proxy_cache.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/proxy/proxy_cache.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -u -r1.4 -r1.5 --- proxy_cache.c 1999/03/15 14:26:52 1.4 +++ proxy_cache.c 1999/03/17 17:01:42 1.5 @@ -824,7 +824,7 @@ * requests with an Authorization header, or * protocol requests nocache (e.g. ftp with user/password) */ -/* @@@ XXX FIXME: is the test "r->status != HTTP_MOVED_PERMANENTLY" corerct? +/* @@@ XXX FIXME: is the test "r->status != HTTP_MOVED_PERMANENTLY" correct? * or shouldn't it be "ap_is_HTTP_REDIRECT(r->status)" ? -MnKr */ if ((r->status != HTTP_OK && r->status != HTTP_MOVED_PERMANENTLY && r->status != HTTP_NOT_MODIFIED) || (expire != NULL && expc == BAD_DATE) || 1.3 +6 -3 apache-apr/pthreads/src/modules/proxy/proxy_connect.c Index: proxy_connect.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/proxy/proxy_connect.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- proxy_connect.c 1999/02/07 06:29:47 1.2 +++ proxy_connect.c 1999/03/17 17:01:42 1.3 @@ -148,7 +148,8 @@ for (i = 0; i < conf->noproxies->nelts; i++) { if ((npent[i].name != NULL && strstr(host, npent[i].name) != NULL) || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] == '*') - return ap_proxyerror(r, "Connect to remote machine blocked"); + return ap_proxyerror(r, HTTP_FORBIDDEN, + "Connect to remote machine blocked"); } /* Check if it is an allowed port */ @@ -175,7 +176,9 @@ err = ap_proxy_host2addr(proxyhost ? proxyhost : host, &server_hp); if (err != NULL) - return ap_proxyerror(r, err); /* give up */ + return ap_proxyerror(r, + proxyhost ? HTTP_BAD_GATEWAY : HTTP_INTERNAL_SERVER_ERROR, + err); sock = ap_psocket(r->pool, PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == -1) { @@ -207,7 +210,7 @@ } if (i == -1) { ap_pclosesocket(r->pool, sock); - return ap_proxyerror(r, ap_pstrcat(r->pool, + return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, ap_pstrcat(r->pool, "Could not connect to remote machine:<br>", strerror(errno), NULL)); } 1.4 +34 -22 apache-apr/pthreads/src/modules/proxy/proxy_ftp.c Index: proxy_ftp.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/proxy/proxy_ftp.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- proxy_ftp.c 1999/03/15 14:26:52 1.3 +++ proxy_ftp.c 1999/03/17 17:01:43 1.4 @@ -77,7 +77,7 @@ for (i = 0, j = 0; x[i] != '\0'; i++, j++) { /* decode it if not already done */ ch = x[i]; - if (ch == '%' && isxdigit(x[i + 1]) && isxdigit(x[i + 2])) { + if (ch == '%' && ap_isxdigit(x[i + 1]) && ap_isxdigit(x[i + 2])) { ch = ap_proxy_hex2c(&x[i + 1]); i += 2; } @@ -97,7 +97,7 @@ for (i = 0; x[i] != '\0'; i++) { ch = x[i]; - if (ch == '%' && isxdigit(x[i + 1]) && isxdigit(x[i + 2])) { + if (ch == '%' && ap_isxdigit(x[i + 1]) && ap_isxdigit(x[i + 2])) { ch = ap_proxy_hex2c(&x[i + 1]); i += 2; } @@ -532,7 +532,8 @@ for (i = 0; i < conf->noproxies->nelts; i++) { if ((npent[i].name != NULL && strstr(host, npent[i].name) != NULL) || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] == '*') - return ap_proxyerror(r, /*HTTP_FORBIDDEN*/ "Connect to remote machine blocked"); + return ap_proxyerror(r, HTTP_FORBIDDEN, + "Connect to remote machine blocked"); } Explain2("FTP: connect to %s:%d", host, port); @@ -546,7 +547,7 @@ server.sin_port = htons(port); err = ap_proxy_host2addr(host, &server_hp); if (err != NULL) - return ap_proxyerror(r, err); /* give up */ + return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err); sock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == -1) { @@ -597,7 +598,7 @@ #endif if (i == -1) { ap_pclosesocket(p, sock); - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ ap_pstrcat(r->pool, + return ap_proxyerror(r, HTTP_BAD_GATEWAY, ap_pstrcat(r->pool, "Could not connect to remote machine: ", strerror(errno), NULL)); } @@ -617,7 +618,8 @@ i = ftp_getrc_msg(f, resp, sizeof resp); Explain1("FTP: returned status %d", i); if (i == -1) { - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } #if 0 if (i == 120) { @@ -632,11 +634,11 @@ * Retry-After = "Retry-After" ":" ( HTTP-date | delta-seconds ) */ ap_set_header("Retry-After", ap_psprintf(p, "%u", 60*wait_mins); - return ap_proxyerror(r, /*HTTP_SERVICE_UNAVAILABLE*/ resp); + return ap_proxyerror(r, HTTP_SERVICE_UNAVAILABLE, resp); } #endif if (i != 220) { - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ resp); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, resp); } Explain0("FTP: connected."); @@ -658,7 +660,8 @@ i = ftp_getrc(f); Explain1("FTP: returned status %d", i); if (i == -1) { - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, ,HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (i == 530) { return ftp_unauthorized (r, 1); /* log it: user name guessing attempt? */ @@ -685,10 +688,10 @@ i = ftp_getrc(f); Explain1("FTP: returned status %d", i); if (i == -1) { - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, "Error reading from remote server"); } if (i == 332) { - return ap_proxyerror(r, /*HTTP_UNAUTHORIZED*/ "Need account for login"); + return ap_proxyerror(r, HTTP_UNAUTHORIZED, "Need account for login"); } /* @@@ questionable -- we might as well return a 403 Forbidden here */ if (i == 530) { @@ -725,7 +728,8 @@ i = ftp_getrc(f); Explain1("FTP: returned status %d", i); if (i == -1) { - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (i == 550) { return HTTP_NOT_FOUND; @@ -765,7 +769,8 @@ i = ftp_getrc(f); Explain1("FTP: returned status %d", i); if (i == -1) { - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (i != 200 && i != 504) { return HTTP_BAD_GATEWAY; @@ -842,9 +847,10 @@ i = ap_proxy_doconnect(dsock, &data_addr, r); if (i == -1) { - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ ap_pstrcat(r->pool, - "Could not connect to remote machine: ", - strerror(errno), NULL)); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + ap_pstrcat(r->pool, + "Could not connect to remote machine: ", + strerror(errno), NULL)); } else { pasvmode = 1; @@ -928,7 +934,8 @@ /* 550 Requested action not taken. */ Explain1("FTP: returned status %d", i); if (i == -1) { - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (i == 550) { return HTTP_NOT_FOUND; @@ -963,7 +970,8 @@ i = ftp_getrc_msg(f, resp, sizeof resp); Explain1("FTP: PWD returned status %d", i); if (i == -1 || i == 421) { - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (i == 550) { return HTTP_NOT_FOUND; @@ -1005,7 +1013,8 @@ rc = ftp_getrc(f); Explain1("FTP: returned status %d", rc); if (rc == -1) { - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (rc == 550) { Explain0("FTP: RETR failed, trying LIST instead"); @@ -1024,7 +1033,8 @@ rc = ftp_getrc(f); Explain1("FTP: returned status %d", rc); if (rc == -1) { - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (rc == 550) { return HTTP_NOT_FOUND; @@ -1047,7 +1057,8 @@ i = ftp_getrc_msg(f, resp, sizeof resp); Explain1("FTP: PWD returned status %d", i); if (i == -1 || i == 421) { - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (i == 550) { return HTTP_NOT_FOUND; @@ -1064,7 +1075,8 @@ rc = ftp_getrc(f); Explain1("FTP: returned status %d", rc); if (rc == -1) - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (rc != 125 && rc != 150 && rc != 226 && rc != 250) return HTTP_BAD_GATEWAY; 1.4 +7 -5 apache-apr/pthreads/src/modules/proxy/proxy_http.c Index: proxy_http.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/proxy/proxy_http.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- proxy_http.c 1999/03/15 14:26:52 1.3 +++ proxy_http.c 1999/03/17 17:01:44 1.4 @@ -233,7 +233,8 @@ for (i = 0; i < conf->noproxies->nelts; i++) { if ((npent[i].name != NULL && strstr(desthost, npent[i].name) != NULL) || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] == '*') - return ap_proxyerror(r, "Connect to remote machine blocked"); + return ap_proxyerror(r, HTTP_FORBIDDEN, + "Connect to remote machine blocked"); } if (proxyhost != NULL) { @@ -246,7 +247,7 @@ server.sin_port = htons(destport); err = ap_proxy_host2addr(desthost, &server_hp); if (err != NULL) - return ap_proxyerror(r, err); /* give up */ + return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err); } sock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP); @@ -291,7 +292,7 @@ if (proxyhost != NULL) return DECLINED; /* try again another way */ else - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ ap_pstrcat(r->pool, + return ap_proxyerror(r, HTTP_BAD_GATEWAY, ap_pstrcat(r->pool, "Could not connect to remote machine: ", strerror(errno), NULL)); } @@ -350,7 +351,7 @@ } ap_bputs(CRLF, f); -/* send the request data, if any. N.B. should we trap SIGPIPE ? */ +/* send the request data, if any. */ if (ap_should_client_block(r)) { while ((i = ap_get_client_block(r, buffer, sizeof buffer)) > 0) @@ -364,7 +365,8 @@ ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "ap_bgets() - proxy receive - Error reading from remote server %s", proxyhost ? proxyhost : desthost); - return ap_proxyerror(r, "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } /* Is it an HTTP/1 response? This is buggy if we ever see an HTTP/1.10 */ 1.4 +28 -27 apache-apr/pthreads/src/modules/proxy/proxy_util.c Index: proxy_util.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/proxy/proxy_util.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- proxy_util.c 1999/03/15 14:26:52 1.3 +++ proxy_util.c 1999/03/17 17:01:44 1.4 @@ -178,7 +178,7 @@ } /* decode it if not already done */ if (isenc && ch == '%') { - if (!isxdigit(x[i + 1]) || !isxdigit(x[i + 2])) + if (!ap_isxdigit(x[i + 1]) || !ap_isxdigit(x[i + 2])) return NULL; ch = ap_proxy_hex2c(&x[i + 1]); i += 2; @@ -491,15 +491,15 @@ long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c) { - int ok = 1; + int ok; char buf[IOBUFSIZE]; - long total_bytes_rcv; + long total_bytes_rcvd; register int n, o, w; conn_rec *con = r->connection; - int alt_to = 1; + int alternate_timeouts = 1; /* 1 if we alternate between soft & hard timeouts */ - total_bytes_rcv = 0; - if (c) + total_bytes_rcvd = 0; + if (c != NULL) c->written = 0; #ifdef CHARSET_EBCDIC @@ -517,7 +517,6 @@ #ifdef WIN32 /* works fine under win32, so leave it */ - alt_to = 0; #else /* CHECKME! Since hard_timeout won't work in unix on sends with partial * cache completion, we have to alternate between hard_timeout @@ -526,16 +525,16 @@ * BUT, if we *can't* continue anyway, just use hard_timeout. */ - if (c) { - if (c->len <= 0 || c->cache_completion == 1) { - alt_to = 0; - } - } else { - alt_to = 0; + if (c == NULL || c->len <= 0 || c->cache_completion == 1.0) { + alternate_timeouts = 0; } #endif - while (ok) { + /* Loop and ap_bread() while we can successfully read and write, + * or (after the client aborted) while we can successfully + * read and finish the configured cache_completion. + */ + for (ok = 1; ok; ) { /* Read block from server */ n = ap_bread(f, buf, IOBUFSIZE); @@ -547,9 +546,10 @@ if (n == 0) break; /* EOF */ o = 0; - total_bytes_rcv += n; + total_bytes_rcvd += n; /* Write to cache first. */ + /*@@@ XXX FIXME: Assuming that writing the cache file won't time out?!!? */ if (c != NULL && c->fp != NULL) { if (ap_bwrite(c->fp, &buf[0], n, 0) != n) { c = ap_proxy_cache_error(c); @@ -559,7 +559,7 @@ } /* Write the block to the client, detect aborted transfers */ - while (n && !con->aborted) { + while (!con->aborted && n > 0) { w = ap_bwrite(con->client, &buf[o], n, 0); if (w <= 0) { @@ -570,7 +570,7 @@ */ ok = (c->len > 0) && (c->cache_completion > 0) && - (c->len * c->cache_completion < total_bytes_rcv); + (c->len * c->cache_completion < total_bytes_rcvd); if (! ok) { ap_pclosef(c->req->pool, c->fp->fd); @@ -584,13 +584,13 @@ } n -= w; o += w; - } - } + } /* while client alive and more data to send */ + } /* loop and ap_bread while "ok" */ if (!con->aborted) ap_bflush(con->client); - return total_bytes_rcv; + return total_bytes_rcvd; } /* @@ -606,14 +606,11 @@ BUFF *fp = r->connection->client; table_entry *elts = (table_entry *) ap_table_elts(t)->elts; - ap_bputs(respline, fp); - ap_bputs(CRLF, fp); + ap_bvputs(fp, respline, CRLF, NULL); for (i = 0; i < ap_table_elts(t)->nelts; ++i) { if (elts[i].key != NULL) { ap_bvputs(fp, elts[i].key, ": ", elts[i].val, CRLF, NULL); - /* FIXME: @@@ This used to be ap_table_set(), but I think - * ap_table_addn() is correct. MnKr */ ap_table_addn(r->headers_out, elts[i].key, elts[i].val); } } @@ -812,7 +809,7 @@ return NULL; } -int ap_proxyerror(request_rec *r, const char *message) +int ap_proxyerror(request_rec *r, int statuscode, const char *message) { ap_table_setn(r->notes, "error-notes", ap_pstrcat(r->pool, @@ -820,8 +817,12 @@ "<EM><A HREF=\"", r->uri, "\">", r->method, " ", r->uri, "</A></EM>.<P>\n" "Reason: <STRONG>", message, "</STRONG>", NULL)); - r->status_line = "500 Proxy Error"; - return HTTP_INTERNAL_SERVER_ERROR; + + /* Allow the "error-notes" string to be printed by ap_send_error_response() */ + ap_table_setn(r->notes, "verbose-error-to", ap_pstrdup(r->pool, "*")); + + r->status_line = ap_psprintf(r->pool, "%3.3u Proxy Error", statuscode); + return statuscode; } /* 1.4 +1 -12 apache-apr/pthreads/src/modules/standard/mod_cgi.c Index: mod_cgi.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_cgi.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- mod_cgi.c 1999/03/15 14:26:54 1.3 +++ mod_cgi.c 1999/03/17 17:01:51 1.4 @@ -440,16 +440,10 @@ } /* Transfer any put/post args, CERN style... - * Note that if a buggy script fails to read everything we throw - * at it, or a buggy client sends too much, we get a SIGPIPE, so - * we have to ignore SIGPIPE while doing this. CERN does the same - * (and in fact, they pretty nearly guarantee themselves a SIGPIPE - * on every invocation by chasing the real client data with a - * spurious newline). + * Note that we already ignore SIGPIPE in the core server. */ if (ap_should_client_block(r)) { - void (*handler) (int); int dbsize, len_read; if (conf->logname) { @@ -457,10 +451,6 @@ dbpos = 0; } -#ifdef SIGPIPE - handler = signal(SIGPIPE, SIG_IGN); -#endif - while ((len_read = ap_get_client_block(r, argsbuffer, HUGE_STRING_LEN)) > 0) { if (conf->logname) { @@ -483,7 +473,6 @@ } ap_bflush(script_out); - signal(SIGPIPE, handler); } 1.4 +1 -1 apache-apr/pthreads/src/modules/standard/mod_include.c Index: mod_include.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_include.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- mod_include.c 1999/02/07 06:29:53 1.3 +++ mod_include.c 1999/03/17 17:01:51 1.4 @@ -629,7 +629,7 @@ */ static int is_only_below(const char *path) { -#if WIN32 +#ifdef HAVE_DRIVE_LETTERS if (path[1] == ':') return 0; #endif 1.3 +78 -94 apache-apr/pthreads/src/modules/standard/mod_negotiation.c Index: mod_negotiation.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_negotiation.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- mod_negotiation.c 1999/02/07 06:29:54 1.2 +++ mod_negotiation.c 1999/03/17 17:01:52 1.3 @@ -511,78 +511,78 @@ static void parse_negotiate_header(request_rec *r, negotiation_state *neg) { const char *negotiate = ap_table_get(r->headers_in, "Negotiate"); + char *tok; - if (negotiate) { - /* Negotiate: header tells us UA does transparent negotiation */ + /* First, default to no TCN, no Alternates, and the original Apache + * negotiation algorithm with fiddles for broken browser configs. + * + * To save network bandwidth, we do not configure to send an + * Alternates header to the user agent by default. User + * agents that want an Alternates header for agent-driven + * negotiation will have to request it by sending an + * appropriate Negotiate header. + */ + neg->ua_supports_trans = 0; + neg->send_alternates = 0; + neg->may_choose = 1; + neg->use_rvsa = 0; + neg->dont_fiddle_headers = 0; - /* sending Alternates on non-transparent resources is allowed, - * and may even be useful, but we don't for now, also - * because it could clash with an Alternates header set by - * a sub- or super- request on a transparent resource. - */ + if (!negotiate) + return; - while (*negotiate) { - char *tok = ap_get_token(neg->pool, &negotiate, 1); - char *cp; + if (strcmp(negotiate, "trans") == 0) { + /* Lynx 2.7 and 2.8 send 'negotiate: trans' even though they + * do not support transparent content negotiation, so for Lynx we + * ignore the negotiate header when its contents are exactly "trans". + * If future versions of Lynx ever need to say 'negotiate: trans', + * they can send the equivalent 'negotiate: trans, trans' instead + * to avoid triggering the workaround below. + */ + const char *ua = ap_table_get(r->headers_in, "User-Agent"); - for (cp = tok; (*cp && !ap_isspace(*cp) && *cp != '='); ++cp) { - *cp = ap_tolower(*cp); - } - *cp = 0; - - if (strcmp(tok, "trans") == 0 || - strcmp(tok, "vlist") == 0 || - strcmp(tok, "guess-small") == 0 || - ap_isdigit(tok[0]) || - strcmp(tok, "*") == 0) { - - /* The user agent supports transparent negotiation */ - neg->ua_supports_trans = 1; - - /* Send-alternates could be configurable, but note - * that it must be 1 if we have 'vlist' in the - * negotiate header. - */ - neg->send_alternates = 1; + if (ua && (strncmp(ua, "Lynx", 4) == 0)) + return; + } - if (strcmp(tok, "1.0") == 0) { - /* we may use the RVSA/1.0 algorithm, configure for it */ - neg->may_choose = 1; - neg->use_rvsa = 1; - neg->dont_fiddle_headers = 1; - } - else if (strcmp(tok, "*") == 0) { - /* we may use any variant selection algorithm, configure - * to use the Apache algorithm - */ - neg->may_choose = 1; - - /* We disable header fiddles on the assumption that a - * client sending Negotiate knows how to send correct - * headers which don't need fiddling. - */ - neg->dont_fiddle_headers = 1; - } - } + neg->may_choose = 0; /* An empty Negotiate would require 300 response */ - if (*negotiate) - negotiate++; /* skip over , */ - } - } + while ((tok = ap_get_list_item(neg->pool, &negotiate)) != NULL) { - if (!neg->ua_supports_trans) { - /* User agent does not support transparent negotiation, - * configure to do server-driven negotiation with the Apache - * algorithm. - */ - neg->may_choose = 1; + if (strcmp(tok, "trans") == 0 || + strcmp(tok, "vlist") == 0 || + strcmp(tok, "guess-small") == 0 || + ap_isdigit(tok[0]) || + strcmp(tok, "*") == 0) { + + /* The user agent supports transparent negotiation */ + neg->ua_supports_trans = 1; + + /* Send-alternates could be configurable, but note + * that it must be 1 if we have 'vlist' in the + * negotiate header. + */ + neg->send_alternates = 1; - /* To save network bandwidth, we do not configure to send an - * Alternates header to the user agent in this case. User - * agents which want an Alternates header for agent-driven - * negotiation will have to request it by sending an - * appropriate Negotiate header. - */ + if (strcmp(tok, "1.0") == 0) { + /* we may use the RVSA/1.0 algorithm, configure for it */ + neg->may_choose = 1; + neg->use_rvsa = 1; + neg->dont_fiddle_headers = 1; + } + else if (tok[0] == '*') { + /* we may use any variant selection algorithm, configure + * to use the Apache algorithm + */ + neg->may_choose = 1; + + /* We disable header fiddles on the assumption that a + * client sending Negotiate knows how to send correct + * headers which don't need fiddling. + */ + neg->dont_fiddle_headers = 1; + } + } } #ifdef NEG_DEBUG @@ -1556,7 +1556,7 @@ } /* For a given variant, find the 'q' value of the charset given - * on the Accept-Charset line. If not charsets are listed, + * on the Accept-Charset line. If no charsets are listed, * assume value of '1'. */ static void set_charset_quality(negotiation_state *neg, var_rec *variant) @@ -1763,13 +1763,14 @@ variant->charset_quality * variant->lang_quality; - /* Make sure that variants with a very low nonzero q value - * do not get rounded down to 0 + /* RFC 2296 calls for the result to be rounded to 5 decimal places, + * but we don't do that because it serves no useful purpose other + * than to ensure that a remote algorithm operates on the same + * precision as ours. That is silly, since what we obviously want + * is for the algorithm to operate on the best available precision + * regardless of who runs it. Since the above calculation may + * result in significant variance at 1e-12, rounding would be bogus. */ - if (q <= 0.0f) - q = 0.0f; - else if (q < 0.00001f) - q = 0.00001f; #ifdef NEG_DEBUG fprintf(stderr, "Variant: file=%s type=%s lang=%s sourceq=%1.3f " @@ -1789,7 +1790,7 @@ variant->definite); #endif - if (q == 0.0f) { + if (q <= 0.0f) { return 0; } if (q > bestq) { @@ -1804,19 +1805,6 @@ *p_bestq = q; return 1; } - /* If the best variant's charset is ISO-8859-1 and this variant has - * the same charset quality, then we prefer this variant - */ - if (variant->charset_quality == best->charset_quality && - (variant->content_charset != NULL && - *variant->content_charset != '\0' && - strcmp(variant->content_charset, "iso-8859-1") != 0) && - (best->content_charset == NULL || - *best->content_charset == '\0' || - strcmp(best->content_charset, "iso-8859-1") == 0)) { - *p_bestq = q; - return 1; - } } return 0; } @@ -1834,7 +1822,7 @@ /* For non-transparent negotiation, server can choose how * to handle the negotiation. We'll use the following in * order: content-type, language, content-type level, charset, - * content length. + * content encoding, content length. * * For each check, we have three possible outcomes: * This variant is worse than current best: return 0 @@ -1896,17 +1884,13 @@ return 1; } - /* if language qualities were equal, try the LanguagePriority - * stuff - */ - /* XXX: TODO: there is a slight discrepancy between how this - * behaves and how it described in the documentation - */ - if (best->lang_index != -1 && variant->lang_index > best->lang_index) { + /* if language qualities were equal, try the LanguagePriority stuff */ + if (best->lang_index != -1 && + (variant->lang_index == -1 || variant->lang_index > best->lang_index)) { return 0; } if (variant->lang_index != -1 && - (variant->lang_index < best->lang_index || best->lang_index == -1)) { + (best->lang_index == -1 || variant->lang_index < best->lang_index)) { *p_bestq = q; return 1; } 1.3 +112 -37 apache-apr/pthreads/src/modules/standard/mod_rewrite.c Index: mod_rewrite.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_rewrite.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- mod_rewrite.c 1999/02/07 06:29:55 1.2 +++ mod_rewrite.c 1999/03/17 17:01:53 1.3 @@ -208,11 +208,7 @@ /* whether proxy module is available or not */ static int proxy_available; - /* the txt mapfile parsing stuff */ -static regex_t *lookup_map_txtfile_regexp = NULL; -static regmatch_t lookup_map_txtfile_regmatch[MAX_NMATCH]; - /* ** +-------------------------------------------------------+ ** | | @@ -952,10 +948,6 @@ /* check if proxy module is available */ proxy_available = (ap_find_linked_module("mod_proxy.c") != NULL); - /* precompile a static pattern - for the txt mapfile parsing */ - lookup_map_txtfile_regexp = ap_pregcomp(p, MAPFILE_PATTERN, REG_EXTENDED); - /* create the rewriting lockfile in the parent */ rewritelock_create(s, p); ap_register_cleanup(p, (void *)s, rewritelock_remove, ap_null_cleanup); @@ -2729,13 +2721,15 @@ else { rewritelog(r, 5, "map lookup FAILED: map=%s[txt] " "key=%s", s->name, key); + set_cache_string(cachep, s->name, CACHEMODE_TS, + st.st_mtime, key, ""); return NULL; } } else { rewritelog(r, 5, "cache lookup OK: map=%s[txt] key=%s " "-> val=%s", s->name, key, value); - return value; + return value[0] != '\0' ? value : NULL; } } else if (s->type == MAPTYPE_DBM) { @@ -2764,13 +2758,15 @@ else { rewritelog(r, 5, "map lookup FAILED: map=%s[dbm] " "key=%s", s->name, key); + set_cache_string(cachep, s->name, CACHEMODE_TS, + st.st_mtime, key, ""); return NULL; } } else { rewritelog(r, 5, "cache lookup OK: map=%s[dbm] key=%s " "-> val=%s", s->name, key, value); - return value; + return value[0] != '\0' ? value : NULL; } #else return NULL; @@ -2823,15 +2819,22 @@ else { rewritelog(r, 5, "map lookup FAILED: map=%s[txt] " "key=%s", s->name, key); + set_cache_string(cachep, s->name, CACHEMODE_TS, + st.st_mtime, key, ""); return NULL; } } else { rewritelog(r, 5, "cache lookup OK: map=%s[txt] key=%s " "-> val=%s", s->name, key, value); + } + if (value[0] != '\0') { + value = select_random_value_part(r, value); + rewritelog(r, 5, "randomly choosen the subvalue `%s'", value); + } + else { + value = NULL; } - value = select_random_value_part(r, value); - rewritelog(r, 5, "randomly choosen the subvalue `%s'", value); return value; } } @@ -2839,44 +2842,45 @@ return NULL; } - static char *lookup_map_txtfile(request_rec *r, char *file, char *key) { FILE *fp = NULL; char line[1024]; - char output[1024]; - char result[1024]; char *value = NULL; char *cpT; + size_t skip; char *curkey; char *curval; if ((fp = ap_pfopen(r->pool, file, "r")) == NULL) { - return NULL; + return NULL; } - ap_cpystrn(output, MAPFILE_OUTPUT, sizeof(output)); while (fgets(line, sizeof(line), fp) != NULL) { - if (line[strlen(line)-1] == '\n') { - line[strlen(line)-1] = '\0'; - } - if (regexec(lookup_map_txtfile_regexp, line, - lookup_map_txtfile_regexp->re_nsub+1, - lookup_map_txtfile_regmatch, 0) == 0) { - ap_cpystrn(result, ap_pregsub(r->pool, output, line, - lookup_map_txtfile_regexp->re_nsub+1, - lookup_map_txtfile_regmatch), - sizeof(result)); /* substitute in output */ - cpT = strchr(result, ','); - *cpT = '\0'; - curkey = result; - curval = cpT+1; - - if (strcmp(curkey, key) == 0) { - value = ap_pstrdup(r->pool, curval); - break; - } - } + if (line[0] == '#') + continue; /* ignore comments */ + cpT = line; + curkey = cpT; + skip = strcspn(cpT," \t\r\n"); + if (skip == 0) + continue; /* ignore lines that start with a space, tab, CR, or LF */ + cpT += skip; + *cpT = '\0'; + if (strcmp(curkey, key) != 0) + continue; /* key does not match... */ + + /* found a matching key; now extract and return the value */ + ++cpT; + skip = strspn(cpT, " \t\r\n"); + cpT += skip; + curval = cpT; + skip = strcspn(cpT, " \t\r\n"); + if (skip == 0) + continue; /* no value... */ + cpT += skip; + *cpT = '\0'; + value = ap_pstrdup(r->pool, curval); + break; } ap_pfclose(r->pool, fp); return value; @@ -3834,12 +3838,57 @@ return ap_pstrdup(c->pool, ce->value); } +static int cache_tlb_hash(char *key) +{ + unsigned long n; + char *p; + + n = 0; + for (p=key; *p != '\0'; ++p) { + n = n * 53711 + 134561 + (unsigned)(*p & 0xff); + } + + return n % CACHE_TLB_ROWS; +} + +static cacheentry *cache_tlb_lookup(cachetlbentry *tlb, cacheentry *elt, + char *key) +{ + int ix = cache_tlb_hash(key); + int i; + int j; + + for (i=0; i < CACHE_TLB_COLS; ++i) { + j = tlb[ix].t[i]; + if (j < 0) + return NULL; + if (strcmp(elt[j].key, key) == 0) + return &elt[j]; + } + return NULL; +} + +static void cache_tlb_replace(cachetlbentry *tlb, cacheentry *elt, + cacheentry *e) +{ + int ix = cache_tlb_hash(e->key); + int i; + + tlb = &tlb[ix]; + + for (i=1; i < CACHE_TLB_COLS; ++i) + tlb->t[i] = tlb->t[i-1]; + + tlb->t[0] = e - elt; +} + static void store_cache_string(cache *c, char *res, cacheentry *ce) { int i; int j; cachelist *l; cacheentry *e; + cachetlbentry *t; int found_list; found_list = 0; @@ -3848,11 +3897,22 @@ l = &(((cachelist *)c->lists->elts)[i]); if (strcmp(l->resource, res) == 0) { found_list = 1; + + e = cache_tlb_lookup((cachetlbentry *)l->tlb->elts, + (cacheentry *)l->entries->elts, ce->key); + if (e != NULL) { + e->time = ce->time; + e->value = ap_pstrdup(c->pool, ce->value); + return; + } + for (j = 0; j < l->entries->nelts; j++) { e = &(((cacheentry *)l->entries->elts)[j]); if (strcmp(e->key, ce->key) == 0) { e->time = ce->time; e->value = ap_pstrdup(c->pool, ce->value); + cache_tlb_replace((cachetlbentry *)l->tlb->elts, + (cacheentry *)l->entries->elts, e); return; } } @@ -3864,6 +3924,13 @@ l = ap_push_array(c->lists); l->resource = ap_pstrdup(c->pool, res); l->entries = ap_make_array(c->pool, 2, sizeof(cacheentry)); + l->tlb = ap_make_array(c->pool, CACHE_TLB_ROWS, + sizeof(cachetlbentry)); + for (i=0; i<CACHE_TLB_ROWS; ++i) { + t = &((cachetlbentry *)l->tlb->elts)[i]; + for (j=0; j<CACHE_TLB_COLS; ++j) + t->t[j] = -1; + } } /* create the new entry */ @@ -3874,6 +3941,8 @@ e->time = ce->time; e->key = ap_pstrdup(c->pool, ce->key); e->value = ap_pstrdup(c->pool, ce->value); + cache_tlb_replace((cachetlbentry *)l->tlb->elts, + (cacheentry *)l->entries->elts, e); return; } } @@ -3892,6 +3961,12 @@ for (i = 0; i < c->lists->nelts; i++) { l = &(((cachelist *)c->lists->elts)[i]); if (strcmp(l->resource, res) == 0) { + + e = cache_tlb_lookup((cachetlbentry *)l->tlb->elts, + (cacheentry *)l->entries->elts, key); + if (e != NULL) + return e; + for (j = 0; j < l->entries->nelts; j++) { e = &(((cacheentry *)l->entries->elts)[j]); if (strcmp(e->key, key) == 0) { 1.3 +14 -8 apache-apr/pthreads/src/modules/standard/mod_rewrite.h Index: mod_rewrite.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_rewrite.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- mod_rewrite.h 1999/02/07 06:29:55 1.2 +++ mod_rewrite.h 1999/03/17 17:01:54 1.3 @@ -219,6 +219,9 @@ #define CACHEMODE_TS 1<<0 #define CACHEMODE_TTL 1<<1 +#define CACHE_TLB_ROWS 1024 +#define CACHE_TLB_COLS 4 + #ifndef FALSE #define FALSE 0 #define TRUE !FALSE @@ -241,10 +244,6 @@ #define MAX_NMATCH 10 -#define MAPFILE_PATTERN "^([^ \t]+)[ \t]+([^ \t]+).*$" -#define MAPFILE_OUTPUT "$1,$2" - - /* ** ** our private data structures we handle with @@ -317,17 +316,23 @@ } rewrite_perdir_conf; - /* the cache structures */ - + /* the cache structures, + * a 4-way hash table with LRU functionality + */ typedef struct cacheentry { time_t time; char *key; char *value; } cacheentry; +typedef struct tlbentry { + int t[CACHE_TLB_COLS]; +} cachetlbentry; + typedef struct cachelist { char *resource; array_header *entries; + array_header *tlb; } cachelist; typedef struct cache { @@ -335,9 +340,10 @@ array_header *lists; } cache; - /* the regex structure for the - substitution of backreferences */ + /* the regex structure for the + * substitution of backreferences + */ typedef struct backrefinfo { char *source; int nsub; 1.4 +1 -0 apache-apr/pthreads/src/modules/standard/mod_so.c Index: mod_so.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_so.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- mod_so.c 1999/03/16 22:07:58 1.3 +++ mod_so.c 1999/03/17 17:01:55 1.4 @@ -351,6 +351,7 @@ NULL, /* check auth */ NULL, /* check access */ NULL, /* type_checker */ + NULL, /* fixer_upper */ NULL, /* logger */ NULL, /* header parser */ NULL, /* child_init */ 1.3 +1 -1 apache-apr/pthreads/src/modules/standard/mod_userdir.c Index: mod_userdir.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_userdir.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- mod_userdir.c 1999/02/07 06:29:56 1.2 +++ mod_userdir.c 1999/03/17 17:01:55 1.3 @@ -262,7 +262,7 @@ if (userdir[0] == '\0' || ap_os_is_path_absolute(userdir)) { if (x) { -#ifdef WIN32 +#ifdef HAVE_DRIVE_LETTERS /* * Crummy hack. Need to figure out whether we have been * redirected to a URL or to a file on some drive. Since I 1.3 +1 -1 apache-apr/pthreads/src/os/bs2000/os.h Index: os.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/bs2000/os.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- os.h 1999/02/07 06:30:10 1.2 +++ os.h 1999/03/17 17:02:04 1.3 @@ -37,6 +37,6 @@ * to use request_rec here... */ struct request_rec; extern int ap_checkconv(struct request_rec *r); -extern pid_t os_fork(void); +extern pid_t os_fork(const char *user); #endif /*! APACHE_OS_H*/ 1.3 +1 -0 apache-apr/pthreads/src/os/os2/os.h Index: os.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/os2/os.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- os.h 1999/02/07 06:30:11 1.2 +++ os.h 1999/03/17 17:02:05 1.3 @@ -3,6 +3,7 @@ #define PLATFORM "OS/2" #define HAVE_CANONICAL_FILENAME +#define HAVE_DRIVE_LETTERS /* * This file in included in all Apache source code. It contains definitions 1.2 +11 -1 apache-apr/pthreads/src/os/os2/util_os2.c Index: util_os2.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/os2/util_os2.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -u -r1.1 -r1.2 --- util_os2.c 1999/01/21 23:08:40 1.1 +++ util_os2.c 1999/03/17 17:02:05 1.2 @@ -1,4 +1,5 @@ #define INCL_DOSFILEMGR +#define INCL_DOSERRORS #include <os2.h> #include "httpd.h" #include "http_log.h" @@ -19,7 +20,16 @@ buf[--len] = 0; rc = DosQueryPathInfo(buf, FIL_QUERYFULLNAME, buf2, HUGE_STRING_LEN); - ap_assert(rc == 0); + + if (rc) { + if ( rc != ERROR_INVALID_NAME ) { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, NULL, "OS/2 error %d for file %s", rc, szFile); + return ap_pstrdup(pPool, ""); + } else { + return ap_pstrdup(pPool, szFile); + } + } + strlwr(buf2); /* Switch backslashes to forward */ 1.4 +1 -0 apache-apr/pthreads/src/os/win32/os.h Index: os.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/win32/os.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- os.h 1999/02/07 06:30:15 1.3 +++ os.h 1999/03/17 17:02:06 1.4 @@ -37,6 +37,7 @@ #define USE_MMAP_SCOREBOARD #define MULTITHREAD #define HAVE_CANONICAL_FILENAME +#define HAVE_DRIVE_LETTERS typedef int uid_t; typedef int gid_t; typedef int pid_t; 1.3 +1 -1 apache-apr/pthreads/src/os/win32/util_win32.c Index: util_win32.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/win32/util_win32.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- util_win32.c 1999/02/07 06:30:15 1.2 +++ util_win32.c 1999/03/17 17:02:06 1.3 @@ -642,7 +642,7 @@ /* Test 2 */ for (idx = 0; idx < seglength; idx++) { - if (segstart[idx] < 32 || + if ((segstart[idx] > 0 && segstart[idx] < 32) || strchr(invalid_characters, segstart[idx])) { return 0; } 1.2 +149 -25 apache-apr/pthreads/src/os/win32/installer/installdll/install.c Index: install.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/win32/installer/installdll/install.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -u -r1.1 -r1.2 --- install.c 1999/01/21 23:08:42 1.1 +++ install.c 1999/03/17 17:02:07 1.2 @@ -4,17 +4,79 @@ * 26/06/97 PCS 1.000 Initial version * 22/02/98 PCS 1.001 Used the excellent NTemacs to apply proper formating * 04/05/98 PCS 1.002 Copy conf files to *.conf.default, then to *.conf + * 16/02/99 PCS 1.003 Add logging to "install.log" in the installed directory */ +#define VERSION ( "1.003 " __DATE__ " " __TIME__ ) + #include <windows.h> #include <winsock.h> #include <string.h> #include <stdio.h> #include <direct.h> +#include <time.h> + +#include "conf.h" +#include "ap.h" +#ifdef strftime +#undef strftime +#endif + /* Global to store the instance handle */ HINSTANCE hInstance = NULL; +static char *szLogFilename = NULL; +static FILE *fpLog = NULL; + +void OpenLog(char *dir, char *fn) +{ + szLogFilename = malloc(strlen(dir) + 1 + strlen(fn) + 1); + sprintf(szLogFilename, "%s/%s", dir, fn); + + fpLog = fopen(szLogFilename, "a+"); +} + +void LogMessage(char *fmt, ...) +{ + char buf[4000]; + va_list ap; + struct tm *tms; + time_t nowtime; + char *bp = buf; + int rv; + int free = sizeof(buf); + + if (!fpLog) { + return; + } + + nowtime = time(NULL); + tms = localtime(&nowtime); + rv = strftime(bp, free, "%c", tms); + bp += rv; + free -= rv; + if (free) { + *bp++ = ' '; + free--; + } + + va_start(ap, fmt); + rv = ap_vsnprintf(bp, free, fmt, ap); + va_end(ap); + + free -= rv; + + fprintf(fpLog, "%s\n", buf); +} + +void CloseLog(void) +{ + if (fpLog) { + fclose(fpLog); + } +} + /* * MessageBox_error() is a helper function to display an error in a * message box, optionally including a Win32 error message. If @@ -23,9 +85,6 @@ * the output string. The output string is given as a printf-format * and replacement arguments. The hWnd, title and mb_opt fields are * passed on to the Win32 MessageBox() call. - * - * We shouldn't use a fixed length buffer to build up the printf - * text. Umm. */ #define AP_WIN32ERROR 1 @@ -33,31 +92,72 @@ int MessageBox_error(HWND hWnd, int opt, char *title, int mb_opt, char *fmt, ...) { - char buf[4000]; + char buf[1000]; va_list ap; + int free = sizeof(buf); /* Number of bytes free in the buffer */ + int rv; + char *p; va_start(ap, fmt); - wvsprintf(buf, fmt, ap); + rv = ap_vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); + + free -= rv; - if (opt & AP_WIN32ERROR) { - char *p; + if (opt & AP_WIN32ERROR && free > 3) { + /* We checked in the "if" that we have enough space in buf for + * at least three extra characters. + */ + p = buf + strlen(buf); + *p++ = '\r'; + *p++ = '\r'; + *p++ = '('; + free -= 3; + /* NB: buf is now not null terminated */ + + /* Now put the error message straight into buf. This function + * takes the free buffer size as the 6th argument. + */ + rv = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + 0, + p, + free, + NULL); + + if (rv == 0) { + /* FormatMessage failed, so get rid of the "\r\r(" we just placed + * in the buffer, since there is no system error message. + */ + p -= 3; + *p = '\0'; + free += 3; + } else { + free -= rv; + p += rv; + + /* Strip any trailing \r or \n characters to make it look nice on + * the screen. + */ + while (*(p-1) == '\r' || *(p-1) == '\n') + p--, free++; + *p = '\0'; + + /* Append a trailing ) */ + if (free >= 1) { + *p++ = ')'; + *p++ = '\0'; + } + } + } - strcat(buf, "\r\r("); - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError(), - 0, - buf + strlen(buf), - 4000 - strlen(buf), - NULL); - p = buf+strlen(buf)-1; - while (*p == '\r' || *p == '\n') - p--; - p++; - *p = '\0'; - strcat(buf, ")"); + for (p = buf; *p; p++) { + if (*p == '\n' || *p == '\r') { + *p = ' '; + } } + LogMessage("MSG %s", buf); return MessageBox(hWnd, buf, title, mb_opt); } @@ -262,8 +362,8 @@ FILE *infp; FILE *outfp; - sprintf(inFile, "%s\\%s", szInst, szinFile); - sprintf(outFile, "%s\\%s", szInst, szoutFile); + ap_snprintf(inFile, sizeof(inFile), "%s\\%s", szInst, szinFile); + ap_snprintf(outFile, sizeof(outFile), "%s\\%s", szInst, szoutFile); if (!(infp = fopen(inFile, "r"))) { MessageBox_error(hwnd, @@ -348,8 +448,11 @@ fclose(infp); fclose(outfp); + LogMessage("COPY: expanded %s to %s", inFile, outFile); + if (options & OPT_DELETESOURCE) { unlink(inFile); + LogMessage("COPY: deleted file %s", inFile); } return 0; @@ -375,6 +478,9 @@ #endif for (p = item->value; *p; p++) if (*p == '\\') *p = '/'; + + LogMessage("FillInReplaceTable tmpl=%s value=%s", item->tmpl, item->value); + continue; } #if NEED_FQDN @@ -477,10 +583,22 @@ ACTIONITEM *pactionItem; int end = 0; + OpenLog(szInst, "install.log"); + LogMessage("STARTED %s", VERSION); + LogMessage("src=%s support=%s inst=%s", + szSrcDir, szSupport, szInst); + FillInReplaceTable(hwnd, replaceHttpd, szInst); pactionItem = actionTable; while (!end) { + + LogMessage("command=%d in=%s out=%s options=%d", + pactionItem->command, + pactionItem->in ? pactionItem->in : "NULL", + pactionItem->out ? pactionItem->out : "NULL", + pactionItem->options); + switch(pactionItem->command) { case CMD_END: end = 1; @@ -498,7 +616,7 @@ case CMD_RM: { char inFile[MAX_INPUT_LINE]; - sprintf(inFile, "%s\\%s", szInst, pactionItem->in); + ap_snprintf(inFile, sizeof(inFile), "%s\\%s", szInst, pactionItem->in); if (unlink(inFile) < 0 && !(pactionItem->options & OPT_SILENT)) { MessageBox_error(hwnd, AP_WIN32ERROR, "Error during configuration", MB_ICONHAND, @@ -506,12 +624,13 @@ inFile); return 0; } + LogMessage("RM: deleted file %s", inFile); break; } case CMD_RMDIR: { char inFile[MAX_INPUT_LINE]; - sprintf(inFile, "%s\\%s", szInst, pactionItem->in); + ap_snprintf(inFile, sizeof(inFile), "%s\\%s", szInst, pactionItem->in); if (rmdir(inFile) < 0) { MessageBox_error(hwnd, AP_WIN32ERROR, "Error during configuration", MB_ICONHAND, @@ -519,6 +638,7 @@ inFile); return 0; } + LogMessage("RMDIR: deleted directory %s", inFile); break; } default: @@ -531,6 +651,10 @@ } pactionItem++; } + + LogMessage("FINISHED OK"); + CloseLog(); + return 1; } 1.2 +6 -2 apache-apr/pthreads/src/os/win32/installer/installdll/install.dsp Index: install.dsp =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/win32/installer/installdll/install.dsp,v retrieving revision 1.1 retrieving revision 1.2 diff -u -u -r1.1 -r1.2 --- install.dsp 1999/01/21 23:08:42 1.1 +++ install.dsp 1999/03/17 17:02:07 1.2 @@ -43,7 +43,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" @@ -69,7 +69,7 @@ # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "../../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" @@ -90,6 +90,10 @@ # Begin Group "Source Files" # PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\ap\ap_snprintf.c +# End Source File # Begin Source File SOURCE=.\install.c 1.2 +144 -31 apache-apr/pthreads/src/os/win32/installer/installdll/install.mak Index: install.mak =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/win32/installer/installdll/install.mak,v retrieving revision 1.1 retrieving revision 1.2 diff -u -u -r1.1 -r1.2 --- install.mak 1999/01/21 23:08:42 1.1 +++ install.mak 1999/03/17 17:02:07 1.2 @@ -27,10 +27,6 @@ NULL=nul !ENDIF -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - !IF "$(CFG)" == "install - Win32 Release" OUTDIR=.\Release @@ -50,6 +46,7 @@ !ENDIF CLEAN : + [EMAIL PROTECTED] "$(INTDIR)\ap_snprintf.obj" [EMAIL PROTECTED] "$(INTDIR)\install.obj" [EMAIL PROTECTED] "$(INTDIR)\vc50.idb" [EMAIL PROTECTED] "$(OUTDIR)\install.dll" @@ -59,11 +56,46 @@ "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ - /Fp"$(INTDIR)\install.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +CPP=cl.exe +CPP_PROJ=/nologo /MT /W3 /GX /O2 /I "../../../../include" /D "WIN32" /D\ + "NDEBUG" /D "_WINDOWS" /Fp"$(INTDIR)\install.pch" /YX /Fo"$(INTDIR)\\"\ + /Fd"$(INTDIR)\\" /FD /c CPP_OBJS=.\Release/ CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\install.bsc" BSC32_SBRS= \ @@ -76,6 +108,7 @@ DEF_FILE= \ ".\install.def" LINK32_OBJS= \ + "$(INTDIR)\ap_snprintf.obj" \ "$(INTDIR)\install.obj" "$(OUTDIR)\install.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) @@ -102,6 +135,7 @@ !ENDIF CLEAN : + [EMAIL PROTECTED] "$(INTDIR)\ap_snprintf.obj" [EMAIL PROTECTED] "$(INTDIR)\install.obj" [EMAIL PROTECTED] "$(INTDIR)\vc50.idb" [EMAIL PROTECTED] "$(INTDIR)\vc50.pdb" @@ -114,33 +148,13 @@ "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" -CPP_PROJ=/nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ - /Fp"$(INTDIR)\install.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +CPP=cl.exe +CPP_PROJ=/nologo /MTd /W3 /Gm /GX /Zi /Od /I "../../../../include" /D "WIN32"\ + /D "_DEBUG" /D "_WINDOWS" /Fp"$(INTDIR)\install.pch" /YX /Fo"$(INTDIR)\\"\ + /Fd"$(INTDIR)\\" /FD /c CPP_OBJS=.\Debug/ CPP_SBRS=. -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\install.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ - advapi32.lib shell32.lib wsock32.lib /nologo /subsystem:windows /dll\ - /incremental:yes /pdb:"$(OUTDIR)\install.pdb" /debug /machine:I386\ - /def:".\install.def" /out:"$(OUTDIR)\install.dll"\ - /implib:"$(OUTDIR)\install.lib" /pdbtype:sept -DEF_FILE= \ - ".\install.def" -LINK32_OBJS= \ - "$(INTDIR)\install.obj" -"$(OUTDIR)\install.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - .c{$(CPP_OBJS)}.obj:: $(CPP) @<< $(CPP_PROJ) $< @@ -171,13 +185,112 @@ $(CPP_PROJ) $< << +MTL=midl.exe +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +RSC=rc.exe +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\install.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib wsock32.lib /nologo /subsystem:windows /dll\ + /incremental:yes /pdb:"$(OUTDIR)\install.pdb" /debug /machine:I386\ + /def:".\install.def" /out:"$(OUTDIR)\install.dll"\ + /implib:"$(OUTDIR)\install.lib" /pdbtype:sept +DEF_FILE= \ + ".\install.def" +LINK32_OBJS= \ + "$(INTDIR)\ap_snprintf.obj" \ + "$(INTDIR)\install.obj" + +"$(OUTDIR)\install.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + !IF "$(CFG)" == "install - Win32 Release" || "$(CFG)" ==\ "install - Win32 Debug" +SOURCE=..\..\..\..\ap\ap_snprintf.c + +!IF "$(CFG)" == "install - Win32 Release" + +DEP_CPP_AP_SN=\ + "..\..\..\..\include\alloc.h"\ + "..\..\..\..\include\ap.h"\ + "..\..\..\..\include\ap_config.h"\ + "..\..\..\..\include\ap_ctype.h"\ + "..\..\..\..\include\ap_mmn.h"\ + "..\..\..\..\include\buff.h"\ + "..\..\..\..\include\hsregex.h"\ + "..\..\..\..\include\httpd.h"\ + "..\..\..\..\include\util_uri.h"\ + "..\..\os.h"\ + "..\..\readdir.h"\ + + +"$(INTDIR)\ap_snprintf.obj" : $(SOURCE) $(DEP_CPP_AP_SN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "install - Win32 Debug" + +DEP_CPP_AP_SN=\ + "..\..\..\..\include\alloc.h"\ + "..\..\..\..\include\ap.h"\ + "..\..\..\..\include\ap_config.h"\ + "..\..\..\..\include\ap_ctype.h"\ + "..\..\..\..\include\ap_mmn.h"\ + "..\..\..\..\include\buff.h"\ + "..\..\..\..\include\hsregex.h"\ + "..\..\..\..\include\httpd.h"\ + "..\..\..\..\include\util_uri.h"\ + "..\..\os.h"\ + "..\..\readdir.h"\ + + +"$(INTDIR)\ap_snprintf.obj" : $(SOURCE) $(DEP_CPP_AP_SN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + SOURCE=.\install.c + +!IF "$(CFG)" == "install - Win32 Release" + +DEP_CPP_INSTA=\ + "..\..\..\..\include\ap.h"\ + "..\..\..\..\include\ap_config.h"\ + "..\..\..\..\include\ap_ctype.h"\ + "..\..\..\..\include\ap_mmn.h"\ + "..\..\..\..\include\conf.h"\ + "..\..\..\..\include\hsregex.h"\ + "..\..\os.h"\ + + +"$(INTDIR)\install.obj" : $(SOURCE) $(DEP_CPP_INSTA) "$(INTDIR)" -"$(INTDIR)\install.obj" : $(SOURCE) "$(INTDIR)" +!ELSEIF "$(CFG)" == "install - Win32 Debug" + +DEP_CPP_INSTA=\ + "..\..\..\..\include\ap.h"\ + "..\..\..\..\include\ap_config.h"\ + "..\..\..\..\include\ap_ctype.h"\ + "..\..\..\..\include\ap_mmn.h"\ + "..\..\..\..\include\conf.h"\ + "..\..\..\..\include\hsregex.h"\ + "..\..\os.h"\ + + +"$(INTDIR)\install.obj" : $(SOURCE) $(DEP_CPP_INSTA) "$(INTDIR)" + + +!ENDIF !ENDIF 1.2 +8 -5 apache-apr/pthreads/src/os/win32/installer/installdll/test/resource.h Index: resource.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/win32/installer/installdll/test/resource.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -u -r1.1 -r1.2 --- resource.h 1999/01/21 23:08:42 1.1 +++ resource.h 1999/03/17 17:02:08 1.2 @@ -4,20 +4,23 @@ // #define IDM_TEST 102 #define IDI_TEST 106 +#define IDM_EXIT 106 #define IDD_ABOUT 107 +#define IDD_SETDIRECTORY 109 +#define IDM_ABOUT 303 +#define IDC_DIRECTORY 1000 #define IDM_BEFOREEXIT 40001 -#define IDM_EXIT 106 -#define IDM_ABOUT 303 -#define IDC_STATIC -1 +#define IDM_CONFIGURE 40001 +#define IDC_STATIC -1 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 109 +#define _APS_NEXT_RESOURCE_VALUE 110 #define _APS_NEXT_COMMAND_VALUE 40002 -#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif 1.2 +120 -5 apache-apr/pthreads/src/os/win32/installer/installdll/test/test.c Index: test.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/win32/installer/installdll/test/test.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -u -r1.1 -r1.2 --- test.c 1999/01/21 23:08:42 1.1 +++ test.c 1999/03/17 17:02:09 1.2 @@ -3,6 +3,7 @@ */ #include <windows.h> +#include <direct.h> #include "test.h" @@ -12,13 +13,18 @@ char szAppName[100]; // Name of the app char szTitle[100]; // The title bar text +// This is imported from the Apache INSTALL.DLL extern CHAR WINAPI BeforeExit(HWND, LPSTR,LPSTR,LPSTR,LPSTR); BOOL InitApplication(HINSTANCE); BOOL InitInstance(HINSTANCE, int); +BOOL CenterWindow (HWND hwndChild, HWND hwndParent); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); +LRESULT CALLBACK SetDirectory(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); +char szInstDir[MAX_PATH]; + int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, @@ -30,6 +36,8 @@ lstrcpy (szAppName, APPNAME); lstrcpy (szTitle, APPNAME); + getcwd(szInstDir, sizeof(szInstDir)); + if (!hPrevInstance) { if (!InitApplication(hInstance)) { return (FALSE); @@ -82,8 +90,14 @@ hInst = hInstance; hWnd = CreateWindow(szAppName, szTitle, WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, - NULL, NULL, hInstance, NULL); + CW_USEDEFAULT, // x + 0, // y + 400, // width + 100, // height + NULL, // parent + NULL, // menu + hInstance, // instance handle + NULL); if (!hWnd) { return (FALSE); @@ -111,10 +125,20 @@ DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)About); break; - case IDM_BEFOREEXIT: - BeforeExit(hWnd, "C:\\", "C:\\", "C:\\Apache", NULL); + case IDM_CONFIGURE: + { + int rc; + + if (DialogBox(hInst, MAKEINTRESOURCE(IDD_SETDIRECTORY), hWnd, (DLGPROC)SetDirectory) == FALSE) + break; + rc = BeforeExit(hWnd, szInstDir, szInstDir, szInstDir, NULL); + if (rc == 1) { + MessageBox(hWnd, "Configuration successful", + "Configuration successful", + MB_OK); + } break; - + } case IDM_EXIT: DestroyWindow (hWnd); break; @@ -139,6 +163,7 @@ switch (message) { case WM_INITDIALOG: + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); return (TRUE); case WM_COMMAND: @@ -150,5 +175,95 @@ } return FALSE; +} + +LRESULT CALLBACK SetDirectory(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + + switch (message) { + case WM_INITDIALOG: + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + + SetDlgItemText(hDlg, IDC_DIRECTORY, szInstDir); + //SetFocus(GetDlgItem(hDlg, IDC_DIRECTORY)); + return (TRUE); + + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDCANCEL: + EndDialog(hDlg, FALSE); + return TRUE; + case IDOK: + GetDlgItemText(hDlg, IDC_DIRECTORY, szInstDir, sizeof(szInstDir)); + EndDialog(hDlg, TRUE); + return TRUE; + } + break; + } + + return FALSE; +} + +// +// FUNCTION: CenterWindow(HWND, HWND) +// +// PURPOSE: Centers one window over another. +// +// COMMENTS: +// +// In this function, we save the instance handle in a global variable and +// create and display the main program window. +// +// This functionwill center one window over another ensuring that +// the placement of the window is within the 'working area', meaning +// that it is both within the display limits of the screen, and not +// obscured by the tray or other framing elements of the desktop. +BOOL CenterWindow (HWND hwndChild, HWND hwndParent) +{ + RECT rChild, rParent, rWorkArea; + int wChild, hChild, wParent, hParent; + int xNew, yNew; + BOOL bResult; + + // Get the Height and Width of the child window + GetWindowRect (hwndChild, &rChild); + wChild = rChild.right - rChild.left; + hChild = rChild.bottom - rChild.top; + + // Get the Height and Width of the parent window + GetWindowRect (hwndParent, &rParent); + wParent = rParent.right - rParent.left; + hParent = rParent.bottom - rParent.top; + + // Get the limits of the 'workarea' + bResult = SystemParametersInfo( + SPI_GETWORKAREA, // system parameter to query or set + sizeof(RECT), + &rWorkArea, + 0); + if (!bResult) { + rWorkArea.left = rWorkArea.top = 0; + rWorkArea.right = GetSystemMetrics(SM_CXSCREEN); + rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN); + } + + // Calculate new X position, then adjust for workarea + xNew = rParent.left + ((wParent - wChild) /2); + if (xNew < rWorkArea.left) { + xNew = rWorkArea.left; + } else if ((xNew+wChild) > rWorkArea.right) { + xNew = rWorkArea.right - wChild; + } + + // Calculate new Y position, then adjust for workarea + yNew = rParent.top + ((hParent - hChild) /2); + if (yNew < rWorkArea.top) { + yNew = rWorkArea.top; + } else if ((yNew+hChild) > rWorkArea.bottom) { + yNew = rWorkArea.bottom - hChild; + } + + // Set it, and return + return SetWindowPos (hwndChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } 1.2 +0 -11 apache-apr/pthreads/src/os/win32/installer/installdll/test/test.mak Index: test.mak =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/win32/installer/installdll/test/test.mak,v retrieving revision 1.1 retrieving revision 1.2 diff -u -u -r1.1 -r1.2 --- test.mak 1999/01/21 23:08:42 1.1 +++ test.mak 1999/03/17 17:02:09 1.2 @@ -207,23 +207,12 @@ !IF "$(CFG)" == "test - Win32 Release" || "$(CFG)" == "test - Win32 Debug" SOURCE=.\test.c - -!IF "$(CFG)" == "test - Win32 Release" - - -"$(INTDIR)\test.obj" : $(SOURCE) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "test - Win32 Debug" - DEP_CPP_TEST_=\ ".\test.h"\ "$(INTDIR)\test.obj" : $(SOURCE) $(DEP_CPP_TEST_) "$(INTDIR)" - -!ENDIF SOURCE=.\test.rc DEP_RSC_TEST_R=\ 1.2 +28 -10 apache-apr/pthreads/src/os/win32/installer/installdll/test/test.rc Index: test.rc =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/win32/installer/installdll/test/test.rc,v retrieving revision 1.1 retrieving revision 1.2 diff -u -u -r1.1 -r1.2 --- test.rc 1999/01/21 23:08:42 1.1 +++ test.rc 1999/03/17 17:02:09 1.2 @@ -41,14 +41,11 @@ IDM_TEST MENU DISCARDABLE BEGIN - POPUP "&File" + POPUP "&Configure" BEGIN + MENUITEM "&Configure", IDM_CONFIGURE MENUITEM "E&xit", IDM_EXIT END - POPUP "&Test" - BEGIN - MENUITEM "Call &BeforeExit", IDM_BEFOREEXIT - END POPUP "&Help" BEGIN MENUITEM "&About", IDM_ABOUT @@ -91,14 +88,27 @@ // Dialog // -IDD_ABOUT DIALOG DISCARDABLE 0, 0, 186, 47 +IDD_ABOUT DIALOG DISCARDABLE 0, 0, 186, 62 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Dialog" FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,41,50,14 + LTEXT "Apache post-install configuration tester",IDC_STATIC,7, + 7,172,10,NOT WS_GROUP + LTEXT "Copyright 1999 The Apache Group",IDC_STATIC,7,21,172,9 +END + +IDD_SETDIRECTORY DIALOG DISCARDABLE 0, 0, 186, 63 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Configure Apache" +FONT 8, "MS Sans Serif" BEGIN - DEFPUSHBUTTON "OK",IDOK,129,26,50,14 - LTEXT "Apache Install DLL Tester",IDC_STATIC,7,7,172,14,NOT - WS_GROUP + DEFPUSHBUTTON "OK",IDOK,39,42,50,14 + PUSHBUTTON "Cancel",IDCANCEL,95,42,50,14 + LTEXT "Directory where Apache was installled",IDC_STATIC,7,7, + 164,11 + EDITTEXT IDC_DIRECTORY,7,22,172,12,ES_AUTOHSCROLL END @@ -114,8 +124,16 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 55 + END + + IDD_SETDIRECTORY, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 TOPMARGIN, 7 - BOTTOMMARGIN, 40 + BOTTOMMARGIN, 56 END END #endif // APSTUDIO_INVOKED 1.3 +0 -114 apache-apr/pthreads/src/support/ab.1 <<Binary file>> 1.3 +557 -388 apache-apr/pthreads/src/support/ab.c Index: ab.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/support/ab.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- ab.c 1999/02/07 06:30:18 1.2 +++ ab.c 1999/03/17 17:02:10 1.3 @@ -6,7 +6,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in @@ -55,33 +55,34 @@ * */ -/* -** This program is based on ZeusBench V1.0 written by Adam Twiss -** which is Copyright (c) 1996 by Zeus Technology Ltd. http://www.zeustech.net/ -** -** This software is provided "as is" and any express or implied waranties, -** including but not limited to, the implied warranties of merchantability and -** fitness for a particular purpose are disclaimed. In no event shall -** Zeus Technology Ltd. be liable for any direct, indirect, incidental, special, -** exemplary, or consequential damaged (including, but not limited to, -** procurement of substitute good or services; loss of use, data, or profits; -** or business interruption) however caused and on theory of liability. Whether -** in contract, strict liability or tort (including negligence or otherwise) -** arising in any way out of the use of this software, even if advised of the -** possibility of such damage. -** -*/ +/* + ** This program is based on ZeusBench V1.0 written by Adam Twiss + ** which is Copyright (c) 1996 by Zeus Technology Ltd. http://www.zeustech.net/ + ** + ** This software is provided "as is" and any express or implied waranties, + ** including but not limited to, the implied warranties of merchantability and + ** fitness for a particular purpose are disclaimed. In no event shall + ** Zeus Technology Ltd. be liable for any direct, indirect, incidental, special, + ** exemplary, or consequential damaged (including, but not limited to, + ** procurement of substitute good or services; loss of use, data, or profits; + ** or business interruption) however caused and on theory of liability. Whether + ** in contract, strict liability or tort (including negligence or otherwise) + ** arising in any way out of the use of this software, even if advised of the + ** possibility of such damage. + ** + */ /* -** HISTORY: -** - Originally written by Adam Twiss <[EMAIL PROTECTED]>, March 1996 -** with input from Mike Belshe <[EMAIL PROTECTED]> and -** Michael Campanella <[EMAIL PROTECTED]> -** - Enhanced by Dean Gaudet <[EMAIL PROTECTED]>, November 1997 -** - Cleaned up by Ralf S. Engelschall <[EMAIL PROTECTED]>, March 1998 -** - POST and verbosity by Kurt Sussman <[EMAIL PROTECTED]>, August 1998 -** -*/ + ** HISTORY: + ** - Originally written by Adam Twiss <[EMAIL PROTECTED]>, March 1996 + ** with input from Mike Belshe <[EMAIL PROTECTED]> and + ** Michael Campanella <[EMAIL PROTECTED]> + ** - Enhanced by Dean Gaudet <[EMAIL PROTECTED]>, November 1997 + ** - Cleaned up by Ralf S. Engelschall <[EMAIL PROTECTED]>, March 1998 + ** - POST and verbosity by Kurt Sussman <[EMAIL PROTECTED]>, August 1998 + ** - HTML table output added by David N. Welton <[EMAIL PROTECTED]>, January 1999 + ** + */ /* * BUGS: @@ -95,7 +96,7 @@ * only an issue for loopback usage */ -#define VERSION "1.2" +#define VERSION "1.3" /* -------------------------------------------------------------------- */ @@ -118,7 +119,7 @@ #include <sys/ioctl.h> #include <string.h> -#define ap_select select +#define ap_select select #else /* (!)NO_APACHE_INCLUDES */ #include "ap_config.h" #include <fcntl.h> @@ -139,20 +140,20 @@ struct connection { int fd; int state; - int read; /* amount of bytes read */ - int bread; /* amount of body read */ - int length; /* Content-Length value used for keep-alive */ - char cbuff[CBUFFSIZE]; /* a buffer to store server response header */ - int cbx; /* offset in cbuffer */ - int keepalive; /* non-zero if a keep-alive request */ - int gotheader; /* non-zero if we have the entire header in cbuff */ + int read; /* amount of bytes read */ + int bread; /* amount of body read */ + int length; /* Content-Length value used for keep-alive */ + char cbuff[CBUFFSIZE]; /* a buffer to store server response header */ + int cbx; /* offset in cbuffer */ + int keepalive; /* non-zero if a keep-alive request */ + int gotheader; /* non-zero if we have the entire header in cbuff */ struct timeval start, connect, done; }; struct data { - int read; /* number of bytes read */ - int ctime; /* time in ms to connect */ - int time; /* time in ms for connection */ + int read; /* number of bytes read */ + int ctime; /* time in ms to connect */ + int time; /* time in ms for connection */ }; #define ap_min(a,b) ((a)<(b))?(a):(b) @@ -160,28 +161,33 @@ /* --------------------- GLOBALS ---------------------------- */ -int verbosity = 0; /* no verbosity by default */ -int posting = 0; /* GET by default */ -int requests = 1; /* Number of requests to make */ -int concurrency = 1; /* Number of multiple requests to make */ -int tlimit = 0; /* time limit in cs */ -int keepalive = 0; /* try and do keepalive connections */ -char servername[1024]; /* name that server reports */ -char hostname[1024]; /* host name */ -char path[1024]; /* path name */ -char postfile[1024]; /* name of file containing post data */ -char* postdata; /* *buffer containing data from postfile */ -int postlen = 0; /* length of data to be POSTed */ -char content_type[1024]; /* content type to put in POST header */ -int port = 80; /* port number */ - -int doclen = 0; /* the length the document should be */ -int totalread = 0; /* total number of bytes read */ -int totalbread = 0; /* totoal amount of entity body read */ -int totalposted = 0; /* total number of bytes posted, inc. headers */ -int done = 0; /* number of requests we have done */ -int doneka = 0; /* number of keep alive connections done */ -int good = 0, bad = 0; /* number of good and bad requests */ +int verbosity = 0; /* no verbosity by default */ +int posting = 0; /* GET by default */ +int requests = 1; /* Number of requests to make */ +int concurrency = 1; /* Number of multiple requests to make */ +int tlimit = 0; /* time limit in cs */ +int keepalive = 0; /* try and do keepalive connections */ +char servername[1024]; /* name that server reports */ +char hostname[1024]; /* host name */ +char path[1024]; /* path name */ +char postfile[1024]; /* name of file containing post data */ +char *postdata; /* *buffer containing data from postfile */ +int postlen = 0; /* length of data to be POSTed */ +char content_type[1024]; /* content type to put in POST header */ +int port = 80; /* port number */ + +int use_html = 0; /* use html in the report */ +char *tablestring; +char *trstring; +char *tdstring; + +int doclen = 0; /* the length the document should be */ +int totalread = 0; /* total number of bytes read */ +int totalbread = 0; /* totoal amount of entity body read */ +int totalposted = 0; /* total number of bytes posted, inc. headers */ +int done = 0; /* number of requests we have done */ +int doneka = 0; /* number of keep alive connections done */ +int good = 0, bad = 0; /* number of good and bad requests */ /* store error cases */ int err_length = 0, err_conn = 0, err_except = 0; @@ -196,11 +202,11 @@ /* one global throw-away buffer to read stuff into */ char buffer[8192]; -struct connection *con; /* connection array */ -struct data *stats; /* date for each request */ +struct connection *con; /* connection array */ +struct data *stats; /* date for each request */ -fd_set readbits, writebits; /* bits for select */ -struct sockaddr_in server; /* server addr structure */ +fd_set readbits, writebits; /* bits for select */ +struct sockaddr_in server; /* server addr structure */ /* --------------------------------------------------------- */ @@ -209,7 +215,7 @@ static void err(char *s) { if (errno) { - perror(s); + perror(s); } else { printf("%s", s); @@ -219,7 +225,7 @@ /* --------------------------------------------------------- */ -/* write out request to a connection - assumes we can write +/* write out request to a connection - assumes we can write (small) request out in one go into our new socket buffer */ static void write_request(struct connection *c) @@ -228,8 +234,8 @@ /* XXX: this could use writev for posting -- more efficient -djg */ write(c->fd, request, reqlen); if (posting) { - write(c->fd,postdata, postlen); - totalposted += (reqlen + postlen); + write(c->fd, postdata, postlen); + totalposted += (reqlen + postlen); } c->state = STATE_READ; @@ -283,63 +289,185 @@ printf("\n"); printf("Concurrency Level: %d\n", concurrency); printf("Time taken for tests: %d.%03d seconds\n", - timetaken / 1000, timetaken % 1000); + timetaken / 1000, timetaken % 1000); printf("Complete requests: %d\n", done); printf("Failed requests: %d\n", bad); if (bad) - printf(" (Connect: %d, Length: %d, Exceptions: %d)\n", - err_conn, err_length, err_except); + printf(" (Connect: %d, Length: %d, Exceptions: %d)\n", + err_conn, err_length, err_except); if (err_response) - printf("Non-2xx responses: %d\n", err_response); + printf("Non-2xx responses: %d\n", err_response); if (keepalive) - printf("Keep-Alive requests: %d\n", doneka); + printf("Keep-Alive requests: %d\n", doneka); printf("Total transferred: %d bytes\n", totalread); if (posting) - printf("Total POSTed: %d\n", totalposted); + printf("Total POSTed: %d\n", totalposted); printf("HTML transferred: %d bytes\n", totalbread); /* avoid divide by zero */ + if (timetaken) { + printf("Requests per second: %.2f\n", 1000 * (float) (done) / timetaken); + printf("Transfer rate: %.2f kb/s received\n", + (float) (totalread) / timetaken); + if (posting) { + printf(" %.2f kb/s sent\n", + (float) (totalposted) / timetaken); + printf(" %.2f kb/s total\n", + (float) (totalread + totalposted) / timetaken); + } + } + + { + /* work out connection times */ + int i; + int totalcon = 0, total = 0; + int mincon = 9999999, mintot = 999999; + int maxcon = 0, maxtot = 0; + + for (i = 0; i < requests; i++) { + struct data s = stats[i]; + mincon = ap_min(mincon, s.ctime); + mintot = ap_min(mintot, s.time); + maxcon = ap_max(maxcon, s.ctime); + maxtot = ap_max(maxtot, s.time); + totalcon += s.ctime; + total += s.time; + } + printf("\nConnnection Times (ms)\n"); + printf(" min avg max\n"); + printf("Connect: %5d %5d %5d\n", mincon, totalcon / requests, maxcon); + printf("Processing: %5d %5d %5d\n", + mintot - mincon, (total / requests) - (totalcon / requests), + maxtot - maxcon); + printf("Total: %5d %5d %5d\n", mintot, total / requests, maxtot); + } +} + +/* --------------------------------------------------------- */ + +/* calculate and output results in HTML */ + +static void output_html_results(void) +{ + int timetaken; + + gettimeofday(&endtime, 0); + timetaken = timedif(endtime, start); + + printf("\n\n<table %s>\n", tablestring); + printf("<tr %s><th colspan=2 %s>Server Software:</th>" + "<td colspan=2 %s>%s</td></tr>\n", + trstring, tdstring, tdstring, servername); + printf("<tr %s><th colspan=2 %s>Server Hostname:</th>" + "<td colspan=2 %s>%s</td></tr>\n", + trstring, tdstring, tdstring, hostname); + printf("<tr %s><th colspan=2 %s>Server Port:</th>" + "<td colspan=2 %s>%d</td></tr>\n", + trstring, tdstring, tdstring, port); + printf("<tr %s><th colspan=2 %s>Document Path:</th>" + "<td colspan=2 %s>%s</td></tr>\n", + trstring, tdstring, tdstring, path); + printf("<tr %s><th colspan=2 %s>Document Length:</th>" + "<td colspan=2 %s>%d bytes</td></tr>\n", + trstring, tdstring, tdstring, doclen); + printf("<tr %s><th colspan=2 %s>Concurrency Level:</th>" + "<td colspan=2 %s>%d</td></tr>\n", + trstring, tdstring, tdstring, concurrency); + printf("<tr %s><th colspan=2 %s>Time taken for tests:</th>" + "<td colspan=2 %s>%d.%03d seconds</td></tr>\n", + trstring, tdstring, tdstring, timetaken / 1000, timetaken % 1000); + printf("<tr %s><th colspan=2 %s>Complete requests:</th>" + "<td colspan=2 %s>%d</td></tr>\n", + trstring, tdstring, tdstring, done); + printf("<tr %s><th colspan=2 %s>Failed requests:</th>" + "<td colspan=2 %s>%d</td></tr>\n", + trstring, tdstring, tdstring, bad); + if (bad) + printf("<tr %s><td colspan=4 %s > (Connect: %d, Length: %d, Exceptions: %d)</td></tr>\n", + trstring, tdstring, err_conn, err_length, err_except); + if (err_response) + printf("<tr %s><th colspan=2 %s>Non-2xx responses:</th>" + "<td colspan=2 %s>%d</td></tr>\n", + trstring, tdstring, tdstring, err_response); + if (keepalive) + printf("<tr %s><th colspan=2 %s>Keep-Alive requests:</th>" + "<td colspan=2 %s>%d</td></tr>\n", + trstring, tdstring, tdstring, doneka); + printf("<tr %s><th colspan=2 %s>Total transferred:</th>" + "<td colspan=2 %s>%d bytes</td></tr>\n", + trstring, tdstring, tdstring, totalread); + if (posting) + printf("<tr %s><th colspan=2 %s>Total POSTed:</th>" + "<td colspan=2 %s>%d</td></tr>\n", + trstring, tdstring, tdstring, totalposted); + printf("<tr %s><th colspan=2 %s>HTML transferred:</th>" + "<td colspan=2 %s>%d bytes</td></tr>\n", + trstring, tdstring, tdstring, totalbread); + + /* avoid divide by zero */ if (timetaken) { - printf("Requests per second: %.2f\n", 1000 * (float) (done) / timetaken); - printf("Transfer rate: %.2f kb/s received\n", - (float) (totalread) / timetaken); - if (posting) { - printf(" %.2f kb/s sent\n", - (float)(totalposted)/timetaken); - printf(" %.2f kb/s total\n", - (float)(totalread + totalposted)/timetaken); - } + printf("<tr %s><th colspan=2 %s>Requests per second:</th>" + "<td colspan=2 %s>%.2f</td></tr>\n", + trstring, tdstring, tdstring, 1000 * (float) (done) / timetaken); + printf("<tr %s><th colspan=2 %s>Transfer rate:</th>" + "<td colspan=2 %s>%.2f kb/s received</td></tr>\n", + trstring, tdstring, tdstring, (float) (totalread) / timetaken); + if (posting) { + printf("<tr %s><td colspan=2 %s> </td>" + "<td colspan=2 %s>%.2f kb/s sent</td></tr>\n", + trstring, tdstring, tdstring, + (float) (totalposted) / timetaken); + printf("<tr %s><td colspan=2 %s> </td>" + "<td colspan=2 %s>%.2f kb/s total</td></tr>\n", + trstring, tdstring, tdstring, + (float) (totalread + totalposted) / timetaken); + } } { - /* work out connection times */ - int i; - int totalcon = 0, total = 0; - int mincon = 9999999, mintot = 999999; - int maxcon = 0, maxtot = 0; - - for (i = 0; i < requests; i++) { - struct data s = stats[i]; - mincon = ap_min(mincon, s.ctime); - mintot = ap_min(mintot, s.time); - maxcon = ap_max(maxcon, s.ctime); - maxtot = ap_max(maxtot, s.time); - totalcon += s.ctime; - total += s.time; - } - printf("\nConnnection Times (ms)\n"); - printf(" min avg max\n"); - printf("Connect: %5d %5d %5d\n", mincon, totalcon / requests, maxcon); - printf("Processing: %5d %5d %5d\n", - mintot - mincon, (total/requests) - (totalcon/requests), - maxtot - maxcon); - printf("Total: %5d %5d %5d\n", mintot, total / requests, maxtot); + /* work out connection times */ + int i; + int totalcon = 0, total = 0; + int mincon = 9999999, mintot = 999999; + int maxcon = 0, maxtot = 0; + + for (i = 0; i < requests; i++) { + struct data s = stats[i]; + mincon = ap_min(mincon, s.ctime); + mintot = ap_min(mintot, s.time); + maxcon = ap_max(maxcon, s.ctime); + maxtot = ap_max(maxtot, s.time); + totalcon += s.ctime; + total += s.time; + } + + printf("<tr %s><th %s colspan=4>Connnection Times (ms)</th></tr>\n", + trstring, tdstring); + printf("<tr %s><th %s> </th> <th %s>min</th> <th %s>avg</th> <th %s>max</th></tr>\n", + trstring, tdstring, tdstring, tdstring, tdstring); + printf("<tr %s><th %s>Connect:</th>" + "<td %s>%5d</td>" + "<td %s>%5d</td>" + "<td %s>%5d</td></tr>\n", + trstring, tdstring, tdstring, mincon, tdstring, totalcon / requests, tdstring, maxcon); + printf("<tr %s><th %s>Processing:</th>" + "<td %s>%5d</td>" + "<td %s>%5d</td>" + "<td %s>%5d</td></tr>\n", + trstring, tdstring, tdstring, mintot - mincon, tdstring, + (total / requests) - (totalcon / requests), tdstring, maxtot - maxcon); + printf("<tr %s><th %s>Total:</th>" + "<td %s>%5d</td>" + "<td %s>%5d</td>" + "<td %s>%5d</td></tr>\n", + trstring, tdstring, tdstring, mintot, tdstring, total / requests, tdstring, maxtot); + printf("</table>\n"); } } /* --------------------------------------------------------- */ -/* start asynchronous non-blocking connection */ +/* start asnchronous non-blocking connection */ static void start_connect(struct connection *c) { @@ -351,25 +479,25 @@ c->fd = socket(AF_INET, SOCK_STREAM, 0); if (c->fd < 0) - err("socket"); + err("socket"); nonblock(c->fd); gettimeofday(&c->start, 0); if (connect(c->fd, (struct sockaddr *) &server, sizeof(server)) < 0) { - if (errno == EINPROGRESS) { - c->state = STATE_CONNECTING; - FD_SET(c->fd, &writebits); - return; - } - else { - close(c->fd); - err_conn++; - if (bad++ > 10) { - err("\nTest aborted after 10 failures\n\n"); - } - start_connect(c); - } + if (errno == EINPROGRESS) { + c->state = STATE_CONNECTING; + FD_SET(c->fd, &writebits); + return; + } + else { + close(c->fd); + err_conn++; + if (bad++ > 10) { + err("\nTest aborted after 10 failures\n\n"); + } + start_connect(c); + } } /* connected first time */ @@ -383,28 +511,28 @@ static void close_connection(struct connection *c) { if (c->read == 0 && c->keepalive) { - /* server has legitimately shut down an idle keep alive request */ - good--; /* connection never happend */ + /* server has legitimately shut down an idle keep alive request */ + good--; /* connection never happend */ } else { - if (good == 1) { - /* first time here */ - doclen = c->bread; - } - else if (c->bread != doclen) { - bad++; - err_length++; - } - - /* save out time */ - if (done < requests) { - struct data s; - gettimeofday(&c->done, 0); - s.read = c->read; - s.ctime = timedif(c->connect, c->start); - s.time = timedif(c->done, c->start); - stats[done++] = s; - } + if (good == 1) { + /* first time here */ + doclen = c->bread; + } + else if (c->bread != doclen) { + bad++; + err_length++; + } + + /* save out time */ + if (done < requests) { + struct data s; + gettimeofday(&c->done, 0); + s.read = c->read; + s.ctime = timedif(c->connect, c->start); + s.time = timedif(c->done, c->start); + stats[done++] = s; + } } close(c->fd); @@ -424,144 +552,145 @@ { int r; char *part; - char respcode[4]; /* 3 digits and null */ + char respcode[4]; /* 3 digits and null */ r = read(c->fd, buffer, sizeof(buffer)); if (r == 0 || (r < 0 && errno != EAGAIN)) { - good++; - close_connection(c); - return; + good++; + close_connection(c); + return; } if (r < 0 && errno == EAGAIN) - return; + return; c->read += r; totalread += r; if (!c->gotheader) { - char *s; - int l = 4; - int space = CBUFFSIZE - c->cbx - 1; /* -1 to allow for 0 terminator */ - int tocopy = (space < r) ? space : r; + char *s; + int l = 4; + int space = CBUFFSIZE - c->cbx - 1; /* -1 to allow for 0 terminator */ + int tocopy = (space < r) ? space : r; #ifndef CHARSET_EBCDIC - memcpy(c->cbuff + c->cbx, buffer, space); -#else /*CHARSET_EBCDIC*/ - ascii2ebcdic(c->cbuff + c->cbx, buffer, space); -#endif /*CHARSET_EBCDIC*/ - c->cbx += tocopy; - space -= tocopy; - c->cbuff[c->cbx] = 0; /* terminate for benefit of strstr */ + memcpy(c->cbuff + c->cbx, buffer, space); +#else /*CHARSET_EBCDIC */ + ascii2ebcdic(c->cbuff + c->cbx, buffer, space); +#endif /*CHARSET_EBCDIC */ + c->cbx += tocopy; + space -= tocopy; + c->cbuff[c->cbx] = 0; /* terminate for benefit of strstr */ if (verbosity >= 4) { printf("LOG: header received:\n%s\n", c->cbuff); } - s = strstr(c->cbuff, "\r\n\r\n"); - /* this next line is so that we talk to NCSA 1.5 which blatantly breaks - the http specifaction */ - if (!s) { - s = strstr(c->cbuff, "\n\n"); - l = 2; - } - - if (!s) { - /* read rest next time */ - if (space) - return; - else { - /* header is in invalid or too big - close connection */ - close(c->fd); - if (bad++ > 10) { - err("\nTest aborted after 10 failures\n\n"); - } - FD_CLR(c->fd, &writebits); - start_connect(c); - } - } - else { - /* have full header */ - if (!good) { - /* this is first time, extract some interesting info */ - char *p, *q; - p = strstr(c->cbuff, "Server:"); - q = servername; - if (p) { - p += 8; - while (*p > 32) - *q++ = *p++; - } - *q = 0; - } + s = strstr(c->cbuff, "\r\n\r\n"); + /* this next line is so that we talk to NCSA 1.5 which blatantly breaks + the http specifaction */ + if (!s) { + s = strstr(c->cbuff, "\n\n"); + l = 2; + } + if (!s) { + /* read rest next time */ + if (space) + return; + else { + /* header is in invalid or too big - close connection */ + close(c->fd); + if (bad++ > 10) { + err("\nTest aborted after 10 failures\n\n"); + } + FD_CLR(c->fd, &writebits); + start_connect(c); + } + } + else { + /* have full header */ + if (!good) { + /* this is first time, extract some interesting info */ + char *p, *q; + p = strstr(c->cbuff, "Server:"); + q = servername; + if (p) { + p += 8; + while (*p > 32) + *q++ = *p++; + } + *q = 0; + } + /* XXX: this parsing isn't even remotely HTTP compliant... * but in the interest of speed it doesn't totally have to be, * it just needs to be extended to handle whatever servers * folks want to test against. -djg */ - /* check response code */ - part = strstr(c->cbuff, "HTTP"); /* really HTTP/1.x_ */ - strncpy(respcode, (part+strlen("HTTP/1.x_")), 3); + /* check response code */ + part = strstr(c->cbuff, "HTTP"); /* really HTTP/1.x_ */ + strncpy(respcode, (part + strlen("HTTP/1.x_")), 3); respcode[3] = '\0'; - if (respcode[0] != '2') { - err_response++; - if (verbosity >= 2) printf ("WARNING: Response code not 2xx (%s)\n", respcode); - } + if (respcode[0] != '2') { + err_response++; + if (verbosity >= 2) + printf("WARNING: Response code not 2xx (%s)\n", respcode); + } else if (verbosity >= 3) { - printf("LOG: Response code = %s\n", respcode); - } + printf("LOG: Response code = %s\n", respcode); + } - c->gotheader = 1; - *s = 0; /* terminate at end of header */ - if (keepalive && - (strstr(c->cbuff, "Keep-Alive") - || strstr(c->cbuff, "keep-alive"))) { /* for benefit of MSIIS */ - char *cl; - cl = strstr(c->cbuff, "Content-Length:"); - /* handle NCSA, which sends Content-length: */ - if (!cl) - cl = strstr(c->cbuff, "Content-length:"); - if (cl) { - c->keepalive = 1; - c->length = atoi(cl + 16); - } - } - c->bread += c->cbx - (s + l - c->cbuff) + r - tocopy; - totalbread += c->bread; - } + c->gotheader = 1; + *s = 0; /* terminate at end of header */ + if (keepalive && + (strstr(c->cbuff, "Keep-Alive") + || strstr(c->cbuff, "keep-alive"))) { /* for benefit of MSIIS */ + char *cl; + cl = strstr(c->cbuff, "Content-Length:"); + /* handle NCSA, which sends Content-length: */ + if (!cl) + cl = strstr(c->cbuff, "Content-length:"); + if (cl) { + c->keepalive = 1; + c->length = atoi(cl + 16); + } + } + c->bread += c->cbx - (s + l - c->cbuff) + r - tocopy; + totalbread += c->bread; + } } else { - /* outside header, everything we have read is entity body */ - c->bread += r; - totalbread += r; + /* outside header, everything we have read is entity body */ + c->bread += r; + totalbread += r; } if (c->keepalive && (c->bread >= c->length)) { - /* finished a keep-alive connection */ - good++; - doneka++; - /* save out time */ - if (good == 1) { - /* first time here */ - doclen = c->bread; - } - else if (c->bread != doclen) { - bad++; - err_length++; - } - if (done < requests) { - struct data s; - gettimeofday(&c->done, 0); - s.read = c->read; - s.ctime = timedif(c->connect, c->start); - s.time = timedif(c->done, c->start); - stats[done++] = s; - } - c->keepalive = 0; - c->length = 0; - c->gotheader = 0; - c->cbx = 0; - c->read = c->bread = 0; - write_request(c); - c->start = c->connect; /* zero connect time with keep-alive */ + /* finished a keep-alive connection */ + good++; + doneka++; + /* save out time */ + if (good == 1) { + /* first time here */ + doclen = c->bread; + } + else if (c->bread != doclen) { + bad++; + err_length++; + } + if (done < requests) { + struct data s; + gettimeofday(&c->done, 0); + s.read = c->read; + s.ctime = timedif(c->connect, c->start); + s.time = timedif(c->done, c->start); + stats[done++] = s; + } + c->keepalive = 0; + c->length = 0; + c->gotheader = 0; + c->cbx = 0; + c->read = c->bread = 0; + write_request(c); + c->start = c->connect; /* zero connect time with keep-alive */ } } @@ -575,18 +704,20 @@ fd_set sel_read, sel_except, sel_write; int i; - printf("Benchmarking %s (be patient)...", hostname); - fflush(stdout); + if (!use_html) { + printf("Benchmarking %s (be patient)...", hostname); + fflush(stdout); + } { - /* get server information */ - struct hostent *he; - he = gethostbyname(hostname); - if (!he) - err("bad hostname"); - server.sin_family = he->h_addrtype; - server.sin_port = htons(port); - server.sin_addr.s_addr = ((unsigned long *) (he->h_addr_list[0]))[0]; + /* get server information */ + struct hostent *he; + he = gethostbyname(hostname); + if (!he) + err("bad hostname"); + server.sin_family = he->h_addrtype; + server.sin_port = htons(port); + server.sin_addr.s_addr = ((unsigned long *) (he->h_addr_list[0]))[0]; } con = malloc(concurrency * sizeof(struct connection)); @@ -600,96 +731,109 @@ /* setup request */ if (!posting) { sprintf(request, "GET %s HTTP/1.0\r\n" - "User-Agent: ApacheBench/%s\r\n" - "%s" - "Host: %s\r\n" - "Accept: */*\r\n" - "\r\n", - path, - VERSION, - keepalive ? "Connection: Keep-Alive\r\n" : "", - hostname); + "User-Agent: ApacheBench/%s\r\n" + "%s" + "Host: %s\r\n" + "Accept: */*\r\n" + "\r\n", + path, + VERSION, + keepalive ? "Connection: Keep-Alive\r\n" : "", + hostname); } else { sprintf(request, "POST %s HTTP/1.0\r\n" - "User-Agent: ApacheBench/%s\r\n" - "%s" - "Host: %s\r\n" - "Accept: */*\r\n" - "Content-length: %d\r\n" - "Content-type: %s\r\n" - "\r\n", - path, - VERSION, - keepalive ? "Connection: Keep-Alive\r\n" : "", - hostname, postlen, - (content_type[0]) ? content_type : "text/plain"); + "User-Agent: ApacheBench/%s\r\n" + "%s" + "Host: %s\r\n" + "Accept: */*\r\n" + "Content-length: %d\r\n" + "Content-type: %s\r\n" + "\r\n", + path, + VERSION, + keepalive ? "Connection: Keep-Alive\r\n" : "", + hostname, postlen, + (content_type[0]) ? content_type : "text/plain"); } - if (verbosity >= 2) printf("INFO: POST header == \n---\n%s\n---\n", request); + if (verbosity >= 2) + printf("INFO: POST header == \n---\n%s\n---\n", request); reqlen = strlen(request); #ifdef CHARSET_EBCDIC ebcdic2ascii(request, request, reqlen); -#endif /*CHARSET_EBCDIC*/ +#endif /*CHARSET_EBCDIC */ /* ok - lets start */ gettimeofday(&start, 0); /* initialise lots of requests */ for (i = 0; i < concurrency; i++) - start_connect(&con[i]); + start_connect(&con[i]); while (done < requests) { - int n; - /* setup bit arrays */ - memcpy(&sel_except, &readbits, sizeof(readbits)); - memcpy(&sel_read, &readbits, sizeof(readbits)); - memcpy(&sel_write, &writebits, sizeof(readbits)); - - /* check for time limit expiry */ - gettimeofday(&now, 0); - if (tlimit && timedif(now, start) > (tlimit * 1000)) { - requests = done; /* so stats are correct */ - } - - /* Timeout of 30 seconds. */ - timeout.tv_sec = 30; - timeout.tv_usec = 0; - n = ap_select(FD_SETSIZE, &sel_read, &sel_write, &sel_except, &timeout); - if (!n) { - err("\nServer timed out\n\n"); - } - if (n < 1) - err("select"); - - for (i = 0; i < concurrency; i++) { - int s = con[i].fd; - if (FD_ISSET(s, &sel_except)) { - bad++; - err_except++; - start_connect(&con[i]); - continue; - } - if (FD_ISSET(s, &sel_read)) - read_connection(&con[i]); - if (FD_ISSET(s, &sel_write)) - write_request(&con[i]); - } + int n; + /* setup bit arrays */ + memcpy(&sel_except, &readbits, sizeof(readbits)); + memcpy(&sel_read, &readbits, sizeof(readbits)); + memcpy(&sel_write, &writebits, sizeof(readbits)); + + /* check for time limit expiry */ + gettimeofday(&now, 0); + if (tlimit && timedif(now, start) > (tlimit * 1000)) { + requests = done; /* so stats are correct */ + } + + /* Timeout of 30 seconds. */ + timeout.tv_sec = 30; + timeout.tv_usec = 0; + n = ap_select(FD_SETSIZE, &sel_read, &sel_write, &sel_except, &timeout); + if (!n) { + err("\nServer timed out\n\n"); + } + if (n < 1) + err("select"); + + for (i = 0; i < concurrency; i++) { + int s = con[i].fd; + if (FD_ISSET(s, &sel_except)) { + bad++; + err_except++; + start_connect(&con[i]); + continue; + } + if (FD_ISSET(s, &sel_read)) + read_connection(&con[i]); + if (FD_ISSET(s, &sel_write)) + write_request(&con[i]); + } } - output_results(); + if (use_html) + output_html_results(); + else + output_results(); } /* ------------------------------------------------------- */ /* display copyright information */ -static void copyright(void) +static void copyright(void) { - printf("This is ApacheBench, Version %s\n", VERSION); - printf("Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/\n"); - printf("Copyright (c) 1998-1999 The Apache Group, http://www.apache.org/\n"); - printf("\n"); + if (!use_html) { + printf("This is ApacheBench, Version %s\n", VERSION); + printf("Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/\n"); + printf("Copyright (c) 1998-1999 The Apache Group, http://www.apache.org/\n"); + printf("\n"); + } + else { + printf("<p>\n"); + printf(" This is ApacheBench, Version %s<br>\n", VERSION); + printf(" Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/<br>\n"); + printf(" Copyright (c) 1998-1999 The Apache Group, http://www.apache.org/<br>\n"); + printf("</p>\n<p>\n"); + } } /* display usage information */ @@ -703,6 +847,10 @@ fprintf(stderr, " -p postfile File containg data to POST\n"); fprintf(stderr, " -T content-type Content-type header for POSTing\n"); fprintf(stderr, " -v verbosity How much troubleshooting info to print\n"); + fprintf(stderr, " -w Print out results in HTML tables\n"); + fprintf(stderr, " -x attributes String to insert as table attributes\n"); + fprintf(stderr, " -y attributes String to insert as tr attributes\n"); + fprintf(stderr, " -z attributes String to insert as td or th attributes\n"); fprintf(stderr, " -V Print version number and exit\n"); fprintf(stderr, " -k Use HTTP KeepAlive feature\n"); fprintf(stderr, " -h Display usage information (this message)\n"); @@ -719,21 +867,21 @@ char *h; char *p = NULL; - if (strlen(url) > 7 && strncmp(url, "http://", 7) == 0) - url += 7; + if (strlen(url) > 7 && strncmp(url, "http://", 7) == 0) + url += 7; h = url; if ((cp = strchr(url, ':')) != NULL) { - *cp++ = '\0'; - p = cp; - url = cp; + *cp++ = '\0'; + p = cp; + url = cp; } if ((cp = strchr(url, '/')) == NULL) - return 1; + return 1; strcpy(path, cp); *cp = '\0'; strcpy(hostname, h); if (p != NULL) - port = atoi(p); + port = atoi(p); return 0; } @@ -747,21 +895,21 @@ struct stat postfilestat; if ((postfd = open(pfile, O_RDONLY)) == -1) { - printf("Invalid postfile name (%s)\n", pfile); - return errno; + printf("Invalid postfile name (%s)\n", pfile); + return errno; } if ((status = fstat(postfd, &postfilestat)) == -1) { - perror("Can\'t stat postfile\n"); - return status; + perror("Can\'t stat postfile\n"); + return status; } postdata = malloc(postfilestat.st_size); if (!postdata) { - printf("Can\'t alloc postfile buffer\n"); - return ENOMEM; + printf("Can\'t alloc postfile buffer\n"); + return ENOMEM; } if (read(postfd, postdata, postfilestat.st_size) != postfilestat.st_size) { - printf("error reading postfilen"); - return EIO; + printf("error reading postfilen"); + return EIO; } postlen = postfilestat.st_size; return 0; @@ -776,60 +924,82 @@ int main(int argc, char **argv) { int c, r; + + /* table defaults */ + tablestring = ""; + trstring = ""; + tdstring = "bgcolor=white"; + optind = 1; - while ((c = getopt(argc, argv, "n:c:t:T:p:v:kVh")) > 0) { - switch (c) { - case 'n': - requests = atoi(optarg); - if (!requests) { - err("Invalid number of requests\n"); - } - break; - case 'k': - keepalive = 1; - break; - case 'c': - concurrency = atoi(optarg); - break; - case 'p': - if (0 == (r = open_postfile(optarg))) { - posting = 1; - } + while ((c = getopt(argc, argv, "n:c:t:T:p:v:kVhwx:y:z:")) > 0) { + switch (c) { + case 'n': + requests = atoi(optarg); + if (!requests) { + err("Invalid number of requests\n"); + } + break; + case 'k': + keepalive = 1; + break; + case 'c': + concurrency = atoi(optarg); + break; + case 'p': + if (0 == (r = open_postfile(optarg))) { + posting = 1; + } else if (postdata) { - exit(r); + exit(r); } - break; - case 'v': - verbosity = atoi(optarg); - break; - case 't': - tlimit = atoi(optarg); - requests = MAX_REQUESTS; /* need to size data array on something */ - break; - case 'T': - strcpy(content_type, optarg); - break; - case 'V': - copyright(); - exit(0); - break; - case 'h': - usage(argv[0]); - break; - default: - fprintf(stderr, "%s: invalid option `%c'\n", argv[0], c); - usage(argv[0]); - break; - } - } - if (optind != argc-1) { - fprintf(stderr, "%s: wrong number of arguments\n", argv[0]); - usage(argv[0]); + break; + case 'v': + verbosity = atoi(optarg); + break; + case 't': + tlimit = atoi(optarg); + requests = MAX_REQUESTS; /* need to size data array on something */ + break; + case 'T': + strcpy(content_type, optarg); + break; + case 'V': + copyright(); + exit(0); + break; + case 'w': + use_html = 1; + break; + /* if any of the following three are used, turn on html output automatically */ + case 'x': + use_html = 1; + tablestring = optarg; + break; + case 'y': + use_html = 1; + trstring = optarg; + break; + case 'z': + use_html = 1; + tdstring = optarg; + break; + case 'h': + usage(argv[0]); + break; + default: + fprintf(stderr, "%s: invalid option `%c'\n", argv[0], c); + usage(argv[0]); + break; + } } + if (optind != argc - 1) { + fprintf(stderr, "%s: wrong number of arguments\n", argv[0]); + usage(argv[0]); + } if (parse_url(argv[optind++])) { - fprintf(stderr, "%s: invalid URL\n", argv[0]); - usage(argv[0]); + fprintf(stderr, "%s: invalid URL\n", argv[0]); + usage(argv[0]); } copyright(); @@ -837,4 +1007,3 @@ exit(0); } - 1.4 +1 -1 apache-apr/pthreads/src/support/apachectl Index: apachectl =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/support/apachectl,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- apachectl 1999/02/15 07:01:58 1.3 +++ apachectl 1999/03/17 17:02:10 1.4 @@ -50,7 +50,7 @@ # check for pidfile if [ -f $PIDFILE ] ; then PID=`cat $PIDFILE` - if kill -0 $PID; then + if [ ! "x$PID" = "x" ] && kill -0 $PID; then STATUS="httpd (pid $PID) running" RUNNING=1 else 1.3 +0 -133 apache-apr/pthreads/src/support/apachectl.1 <<Binary file>> 1.3 +4 -0 apache-apr/pthreads/src/support/apxs.pl Index: apxs.pl =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/support/apxs.pl,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- apxs.pl 1999/02/07 06:30:18 1.2 +++ apxs.pl 1999/03/17 17:02:11 1.3 @@ -91,6 +91,10 @@ ## ## Initial shared object support check ## +if (not -x "$CFG_SBINDIR/$CFG_TARGET") { + print STDERR "apxs:Error: $CFG_SBINDIR/$CFG_TARGET not found or not executable\n"; + exit(1); +} if (not grep(/mod_so/, `$CFG_SBINDIR/$CFG_TARGET -l`)) { print STDERR "apxs:Error: Sorry, no shared object support for Apache\n"; print STDERR "apxs:Error: available under your platform. Make sure\n"; 1.3 +48 -1 apache-apr/pthreads/src/support/dbmmanage.1 Index: dbmmanage.1 =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/support/dbmmanage.1,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- dbmmanage.1 1999/02/07 06:30:19 1.2 +++ dbmmanage.1 1999/03/17 17:02:11 1.3 @@ -86,7 +86,8 @@ found at http://www.apache.org/. .SH OPTIONS .IP \fB\fIfilename\fP -The filename of the DBM format file. Usually without the extension .pag or .dir. +The filename of the DBM format file. Usually without the +extension .db, .pag, or .dir. .IP \fB\fIcommand\fP This selects the operation to perform: .TP 12 @@ -118,6 +119,52 @@ Just displays the complete contents of the DBM file. .IP \fB\fIusername\fP The user for which the update operation is performed. +.PD +.SH BUGS +.PP +One should be aware that there are a number of different DBM file +formats in existance, and with all likelihood, libraries for more than +one format may exist on your system. The three primary examples are +NDBM, the GNU project's GDBM, and Berkeley DB 2. Unfortunately, all +these libraries use different file formats, and you must make sure +that the file format used by +.I filename +is the same format that +.B dbmmanage +expects to see. +.B dbmmanage +currently has no way of determining what type of DBM file it is +looking at. If used against the wrong format, +.dbmmanage +will simply return nothing, or may create a different DBM file with a +different name, or at worst, it may corrupt the DBM file if you were +attempting to write to it. +.PP +.B dbmmanage +has a list of DBM format preferences, defined by the +.B @AnyDBM::ISA +array near the beginning of the program. Since we prefer the Berkeley +DB 2 file format, the order in which +.B dbmmanage +will look for system libraries is Berkeley DB 2, then NDBM, and then +GDBM. The first library found will be the library +.B dbmmanage +will attempt to use for all DBM file transactions. This ordering is +slightly different than the standard +.B @AnyDBM::ISA +ordering in perl, as well as the ordering used by the simple dbmopen() +call in Perl, so if you use any other utilities to manage your DBM +files, they must also follow this preference ordering. Similar care +must be taken if using programs in other languages, like C, to +access these files. +.PP +Apache's +.B mod_auth_db.c +module corresponds to Berkeley DB 2 library, while +.B mod_auth_dbm.c +corresponds to the NDBM library. Also, one can usually use the +.B file +program supplied with most Unix systems to see what format a DBM file is in. .PD .SH SEE ALSO .BR httpd(8) 1.4 +377 -142 apache-apr/pthreads/src/support/htpasswd.c Index: htpasswd.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/support/htpasswd.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- htpasswd.c 1999/03/08 15:58:35 1.3 +++ htpasswd.c 1999/03/17 17:02:11 1.4 @@ -1,3 +1,60 @@ +/* ==================================================================== + * Copyright (c) 1995-1999 The Apache Group. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the Apache Group + * for use in the Apache HTTP server project (http://www.apache.org/)." + * + * 4. The names "Apache Server" and "Apache Group" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * [EMAIL PROTECTED] + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the Apache Group + * for use in the Apache HTTP server project (http://www.apache.org/)." + * + * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Group and was originally based + * on public domain software written at the National Center for + * Supercomputing Applications, University of Illinois, Urbana-Champaign. + * For more information on the Apache Group and the Apache HTTP server + * project, please see <http://www.apache.org/>. + * + */ + /****************************************************************************** ****************************************************************************** * NOTE! This program is not safe as a setuid executable! Do not make it @@ -5,14 +62,25 @@ ****************************************************************************** *****************************************************************************/ /* - * htpasswd.c: simple program for manipulating password file for NCSA httpd + * htpasswd.c: simple program for manipulating password file for + * the Apache HTTP server * - * Rob McCool + * Originally by Rob McCool + * + * Exit values: + * 0: Success + * 1: Failure; file access/permission problem + * 2: Failure; command line syntax problem (usage message issued) + * 3: Failure; password verification failure + * 4: Failure; operation interrupted (such as with CTRL/C) + * 5: Failure; buffer would overflow (username, filename, or computed + * record too long) */ #include "ap_config.h" #include <sys/types.h> #include <signal.h> +#include <errno.h> #include "ap.h" #include "ap_md5.h" @@ -31,9 +99,24 @@ #endif /*CHARSET_EBCDIC*/ #define MAX_STRING_LEN 256 +#define ALG_CRYPT 1 +#define ALG_APMD5 2 + +#define ERR_FILEPERM 1 +#define ERR_SYNTAX 2 +#define ERR_PWMISMATCH 3 +#define ERR_INTERRUPTED 4 +#define ERR_OVERFLOW 5 -char *tn; +/* + * This needs to be declared statically so the signal handler can + * access it. + */ +static char *tempfilename; +/* + * Duplicate a string into memory malloc()ed for it. + */ static char *strd(char *s) { char *d; @@ -43,24 +126,6 @@ return (d); } -static void getword(char *word, char *line, char stop) -{ - int x = 0, y; - - for (x = 0; ((line[x]) && (line[x] != stop)); x++) { - word[x] = line[x]; - } - - word[x] = '\0'; - if (line[x]) { - ++x; - } - y = 0; - - while ((line[y++] = line[x++])) - ; -} - static int getline(char *s, int n, FILE *f) { register int i = 0; @@ -93,7 +158,7 @@ /* From local_passwd.c (C) Regents of Univ. of California blah blah */ static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ -"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; static void to64(register char *s, register long v, register int n) { @@ -104,7 +169,8 @@ } #ifdef MPE -/* MPE lacks getpass() and a way to suppress stdin echo. So for now, just +/* + * MPE lacks getpass() and a way to suppress stdin echo. So for now, just * issue the prompt and read the results with echo. (Ugh). */ @@ -125,7 +191,8 @@ #endif #ifdef WIN32 -/* Windows lacks getpass(). So we'll re-implement it here. +/* + * Windows lacks getpass(). So we'll re-implement it here. */ static char *getpass(const char *prompt) @@ -158,170 +225,338 @@ } #endif -static void add_password(char *user, FILE *f, int use_md5) +/* + * Make a password record from the given information. A zero return + * indicates success; failure means that the output buffer contains an + * error message instead. + */ +static int mkrecord(char *user, char *record, size_t rlen, int alg) { - char *pw, cpw[120], salt[9]; - - pw = strd((char *) getpass("New password:")); - if (strcmp(pw, (char *) getpass("Re-type new password:"))) { - fprintf(stderr, "They don't match, sorry.\n"); - if (tn) { - unlink(tn); - } - exit(1); + char *pw; + char cpw[120]; + char salt[9]; + + pw = strd((char *) getpass("New password: ")); + if (strcmp(pw, (char *) getpass("Re-type new password: "))) { + ap_cpystrn(record, "password verification error", (rlen - 1)); + return ERR_PWMISMATCH; } (void) srand((int) time((time_t *) NULL)); to64(&salt[0], rand(), 8); salt[8] = '\0'; - if (use_md5) { - ap_MD5Encode(pw, salt, cpw, sizeof(cpw)); - } - else { + switch (alg) { + case ALG_APMD5: + ap_MD5Encode(pw, salt, cpw, sizeof(cpw)); + break; + case ALG_CRYPT: ap_cpystrn(cpw, (char *)crypt(pw, salt), sizeof(cpw) - 1); + break; } + /* + * Now that we have the smashed password, we don't need the + * plaintext one any more. + */ free(pw); - fprintf(f, "%s:%s\n", user, cpw); + /* + * Check to see if the buffer is large enough to hold the username, + * hash, and delimiters. + */ + if ((strlen(user) + 1 + strlen(cpw)) > (rlen - 1)) { + ap_cpystrn(record, "resultant record too long", (rlen - 1)); + return ERR_OVERFLOW; + } + strcpy(record, user); + strcat(record, ":"); + strcat(record, cpw); + return 0; } -static void usage(void) +static int usage(void) { fprintf(stderr, "Usage: htpasswd [-cm] passwordfile username\n"); fprintf(stderr, "The -c flag creates a new file.\n"); - fprintf(stderr, "The -m flag creates a md5 encrypted file.\n"); + fprintf(stderr, "The -m flag forces MD5 encryption of the password.\n"); fprintf(stderr, "On Windows systems the -m flag is used by default.\n"); - exit(1); + return ERR_SYNTAX; } static void interrupted(void) { fprintf(stderr, "Interrupted.\n"); - if (tn) { - unlink(tn); + if (tempfilename != NULL) { + unlink(tempfilename); + } + exit(ERR_INTERRUPTED); +} + +/* + * Check to see if the specified file can be opened for the given + * access. + */ +int accessible(char *fname, char *mode) +{ + FILE *s; + + s = fopen(fname, mode); + if (s == NULL) { + return 0; + } + fclose(s); + return 1; +} + +/* + * Return true if a file is readable. + */ +int readable(char *fname) +{ + return accessible(fname, "r"); +} + +/* + * Return true if the specified file can be opened for write access. + */ +int writable(char *fname) +{ + return accessible(fname, "a"); +} + +/* + * Return true if the named file exists, regardless of permissions. + */ +int exists(char *fname) +{ +#ifdef WIN32 + struct _stat sbuf; +#else + struct stat sbuf; +#endif + int check; + +#ifdef WIN32 + check = _stat(fname, &sbuf); +#else + check = stat(fname, &sbuf); +#endif + return ((check == -1) && (errno == ENOENT)) ? 0 : 1; +} + +/* + * Copy from the current position of one file to the current position + * of another. + */ +void copy_file(FILE *target, FILE *source) +{ + static char line[MAX_STRING_LEN]; + + while (fgets(line, sizeof(line), source) != NULL) { + fputs(line, target); } - exit(1); } +/* + * Let's do it. We end up doing a lot of file opening and closing, + * but what do we care? This application isn't run constantly. + */ int main(int argc, char *argv[]) { - FILE *tfp, *f; + FILE *ftemp = NULL; + FILE *fpw = NULL; char user[MAX_STRING_LEN]; + char record[MAX_STRING_LEN]; char line[MAX_STRING_LEN]; - char l[MAX_STRING_LEN]; - char w[MAX_STRING_LEN]; - char command[MAX_STRING_LEN]; - char filename[MAX_STRING_LEN]; - int found; - int use_md5 = 0; + char pwfilename[MAX_STRING_LEN]; + char *arg; + int found = 0; + int alg = ALG_CRYPT; int newfile = 0; - int currarg = 1; - int filearg; + int i; - tn = NULL; + tempfilename = NULL; signal(SIGINT, (void (*)(int)) interrupted); - /* preliminary check to make sure they provided at least + /* + * Preliminary check to make sure they provided at least * three arguments, we'll do better argument checking as * we parse the command line. */ if (argc < 3) { - usage(); + return usage(); } - /* I would rather use getopt, but Windows and UNIX seem to handle getopt - * differently, so I am doing the argument checking by hand. + /* + * Go through the argument list and pick out any options. They + * have to precede any other arguments. */ - - if (!strcmp(argv[1],"-c") || !strcmp(argv[2],"-c")) { - newfile = 1; - currarg++; - } - if (!strcmp(argv[1],"-m") || !strcmp(argv[2],"-m")) { - use_md5 = 1; - currarg++; + for (i = 1; i < argc; i++) { + arg = argv[i]; + if (*arg != '-') { + break; + } + while (*++arg != '\0') { + if (*arg == 'c') { + newfile++; + } + else if (*arg == 'm') { + alg = ALG_APMD5; + } + else { + return usage(); + } + } } - if (!strcmp(argv[1], "-cm") || !strcmp(argv[2], "-mc")) { - use_md5 = 1; - newfile = 1; - currarg++; + /* + * Make sure we still have exactly two arguments left (the filename + * and the username). + */ + if ((argc - i) != 2) { + return usage(); } - - strcpy(filename, argv[currarg]); - filearg = currarg++; - - if (argc <= filearg + 1) { - usage(); + if (strlen(argv[i]) > (sizeof(pwfilename) - 1)) { + fprintf(stderr, "%s: filename too long\n", argv[0]); + return ERR_OVERFLOW; + } + strcpy(pwfilename, argv[i]); + if (strlen(argv[i + 1]) > (sizeof(user) - 1)) { + fprintf(stderr, "%s: username too long\n", argv[0]); + return ERR_OVERFLOW; } + strcpy(user, argv[i + 1]); #ifdef WIN32 - if (!use_md5) { - use_md5 = 1; - fprintf(stderr,"Automatically using md5 format on Windows.\n"); + if (alg == ALG_CRYPT) { + alg = ALG_APMD5; + fprintf(stderr, "Automatically using MD5 format on Windows.\n"); } #endif - if (newfile) { - if (!(tfp = fopen(filename, "w+"))) { - fprintf(stderr, "Could not open password file %s for writing.\n", - filename); - perror("fopen"); - exit(1); - } - printf("Adding password for %s.\n", argv[currarg]); - add_password(argv[currarg], tfp, use_md5); - fclose(tfp); - return(0); - } - - tn = tmpnam(NULL); - if (!(tfp = fopen(tn, "w+"))) { - fprintf(stderr, "Could not open temp file.\n"); - exit(1); - } - - if (!(f = fopen(argv[filearg], "r+"))) { - fprintf(stderr, "Could not open password file %s for reading.\n", - argv[filearg]); - fprintf(stderr, "Use -c option to create a new one\n"); - fclose(tfp); - unlink(tn); - exit(1); - } - strcpy(user, argv[currarg]); - - found = 0; - while (!(getline(line, MAX_STRING_LEN, f))) { - if (found || (line[0] == '#') || (!line[0])) { - putline(tfp, line); - continue; - } - strcpy(l, line); - getword(w, l, ':'); - if (strcmp(user, w)) { - putline(tfp, line); - continue; - } - else { - printf("Changing password for user %s\n", user); - add_password(user, tfp, use_md5); - found = 1; + + /* + * Verify that the file exists if -c was omitted. We give a special + * message if it doesn't. + */ + if ((! newfile) && (! exists(pwfilename))) { + fprintf(stderr, "%s: cannot modify file %s; use '-c' to create it\n", + argv[0], pwfilename); + perror("fopen"); + exit(ERR_FILEPERM); + } + /* + * Verify that we can read the existing file in the case of an update + * to it (rather than creation of a new one). + */ + if ((! newfile) && (! readable(pwfilename))) { + fprintf(stderr, "%s: cannot open file %s for read access\n", + argv[0], pwfilename); + perror("fopen"); + exit(ERR_FILEPERM); + } + /* + * Now check to see if we can preserve an existing file in case + * of password verification errors on a -c operation. + */ + if (newfile && exists(pwfilename) && (! readable(pwfilename))) { + fprintf(stderr, "%s: cannot open file %s for read access\n" + "%s: existing auth data would be lost on password mismatch", + argv[0], pwfilename, argv[0]); + perror("fopen"); + exit(ERR_FILEPERM); + } + /* + * Now verify that the file is writable! + */ + if (! writable(pwfilename)) { + fprintf(stderr, "%s: cannot open file %s for write access\n", + argv[0], pwfilename); + perror("fopen"); + exit(ERR_FILEPERM); + } + + /* + * All the file access checks have been made. Time to go to work; + * try to create the record for the username in question. If that + * fails, there's no need to waste any time on file manipulations. + * Any error message text is returned in the record buffer, since + * the mkrecord() routine doesn't have access to argv[]. + */ + if ((i = mkrecord(user, record, sizeof(record) - 1, alg)) != 0) { + fprintf(stderr, "%s: %s\n", argv[0], record); + exit(i); + } + + /* + * We can access the files the right way, and we have a record + * to add or update. Let's do it.. + */ + tempfilename = tmpnam(NULL); + ftemp = fopen(tempfilename, "w+"); + if (ftemp == NULL) { + fprintf(stderr, "%s: unable to create temporary file\n", argv[0]); + perror("fopen"); + exit(ERR_FILEPERM); + } + /* + * If we're not creating a new file, copy records from the existing + * one to the temporary file until we find the specified user. + */ + if (! newfile) { + char scratch[MAX_STRING_LEN]; + + fpw = fopen(pwfilename, "r"); + while (! (getline(line, sizeof(line), fpw))) { + char *colon; + + if ((line[0] == '#') || (line[0] == '\0')) { + putline(ftemp, line); + continue; + } + strcpy(scratch, line); + /* + * See if this is our user. + */ + colon = strchr(scratch, ':'); + if (colon != NULL) { + *colon = '\0'; + } + if (strcmp(user, scratch) != 0) { + putline(ftemp, line); + continue; + } + found++; + break; } + } + if (found) { + fprintf(stderr, "Updating "); } - if (!found) { - printf("Adding user %s\n", user); - add_password(user, tfp, use_md5); - } -/* - * make a copy from the tmp file to the actual file - */ - f = fopen(filename, "w+"); - rewind(tfp); - while (fgets(command, MAX_STRING_LEN, tfp) != NULL) { - fputs(command, f); - } - - fclose(f); - fclose(tfp); - unlink(tn); - return(0); + else { + fprintf(stderr, "Adding "); + } + fprintf(stderr, "password for user %s\n", user); + /* + * Now add the user record we created. + */ + putline(ftemp, record); + /* + * If we're updating an existing file, there may be additional + * records beyond the one we're updating, so copy them. + */ + if (! newfile) { + copy_file(ftemp, fpw); + fclose(fpw); + } + /* + * The temporary file now contains the information that should be + * in the actual password file. Close the open files, re-open them + * in the appropriate mode, and copy them file to the real one. + */ + fclose(ftemp); + fpw = fopen(pwfilename, "w+"); + ftemp = fopen(tempfilename, "r"); + copy_file(fpw, ftemp); + fclose(fpw); + fclose(ftemp); + unlink(tempfilename); + return 0; } 1.4 +4 -1 apache-apr/pthreads/src/support/httpd.exp Index: httpd.exp =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/support/httpd.exp,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- httpd.exp 1999/02/15 17:59:37 1.3 +++ httpd.exp 1999/03/17 17:02:11 1.4 @@ -107,8 +107,8 @@ ap_find_command_in_modules ap_find_last_token ap_find_linked_module +ap_find_list_item ap_find_module_name -ap_find_opaque_token ap_find_path_info ap_find_token ap_find_types @@ -118,6 +118,7 @@ ap_get_basic_auth_pw ap_get_client_block ap_get_gmtoff +ap_get_list_item ap_get_local_host ap_get_remote_host ap_get_remote_logname @@ -309,6 +310,7 @@ ap_signal ap_single_module_configure ap_single_module_init +ap_size_list_item ap_slack ap_snprintf ap_soft_timeout @@ -325,6 +327,7 @@ ap_strcmp_match ap_sub_req_lookup_file ap_sub_req_lookup_uri +ap_sub_req_method_uri ap_suexec_enabled ap_table_add ap_table_addn 1.3 +36 -0 apache-apr/pthreads/src/support/suexec.c Index: suexec.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/support/suexec.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -u -r1.2 -r1.3 --- suexec.c 1999/02/07 06:30:20 1.2 +++ suexec.c 1999/03/17 17:02:11 1.3 @@ -341,7 +341,34 @@ actual_gname = strdup(target_gname); } +#ifdef _OSD_POSIX /* + * Initialize BS2000 user environment + */ + { + pid_t pid; + int status; + + switch (pid = ufork(target_uname)) + { + case -1: /* Error */ + log_err("failed to setup bs2000 environment for user %s: %s\n", + target_uname, strerror(errno)); + exit(150); + case 0: /* Child */ + break; + default: /* Father */ + while (pid != waitpid(pid, &status, 0)) + ; + /* @@@ FIXME: should we deal with STOP signals as well? */ + if (WIFSIGNALED(status)) + kill (getpid(), WTERMSIG(status)); + exit(WEXITSTATUS(status)); + } + } +#endif /*_OSD_POSIX*/ + + /* * Save these for later since initgroups will hose the struct */ uid = pw->pw_uid; @@ -514,7 +541,16 @@ /* * Execute the command, replacing our image with its own. */ +#ifdef NEED_HASHBANG_EMUL + /* We need the #! emulation when we want to execute scripts */ + { + extern char **environ; + + ap_execve(cmd, &argv[3], environ); + } +#else /*NEED_HASHBANG_EMUL*/ execv(cmd, &argv[3]); +#endif /*NEED_HASHBANG_EMUL*/ /* * (I can't help myself...sorry.)